Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How multiarray.correlate2(a, v, mode) is actually implemented?

On my way to understand how the Numpy.correlate() function actually works, I get to it's implementation in pure Python, but what I saw was very disappointing:

def correlate(a, v, mode='valid', old_behavior=False):
    mode = _mode_from_name(mode)
    if old_behavior:
        warnings.warn("""Warning.""", DeprecationWarning)
        return multiarray.correlate(a, v, mode)
    else:
        return multiarray.correlate2(a, v, mode)

So I started to look for implementation of the multiarray.correlate2(a, v, mode) function, but unfortunately I can't find it. I'll just say, that I'm looking for it, because I try to implement the autocorrelation function by myself, and I'm missing the functionality similar to mode='full' parameter in Numpy.correlate() that makes function to return result as a 1D array. Thank you for help in advance.

like image 433
bluevoxel Avatar asked Dec 13 '14 19:12

bluevoxel


2 Answers

The speed of python code can be very poor compared to other languages like c. numpy aims to provide highly performant operations on arrays, therefore the developers decided to implement some operations in c.

Unfortunately, won't find a python implementation of correlate in numpy's code base, but if you are familiar with C and python's extension modules, you can have find the relevant code here.

The different modes just specify the length of the output array. You can simulate them by transforming your inputs:

import numpy as np
a = [1, 2, 3]
v = [0, 1, 0.5]
np.correlate(a, v, mode="full")

returns:

array([ 0.5,  2. ,  3.5,  3. ,  0. ])

You can get the same result by filling v with zeros:

np.correlate(a, [0, 0] + v + [0, 0])

returns the same result:

array([ 0.5,  2. ,  3.5,  3. ,  0. ])
like image 94
cel Avatar answered Sep 24 '22 13:09

cel


np.core.multiarray.correlate2
dir(np.core.multiarray.correlate2) # to inspect
print (numpy.__version__) 
print numpy.__version__ # python 2

found it! it might be a private API, can't find the docs after first search with numpy.multiarray or with the newly discovered 'correct' name. optimal search query is 'np.core.multiarray.correlate2 github'

return multiarray.correlate2(a, v, mode) # mode is int data type

if you're plan to customize the code for your purposes, be careful.

/*
 * simulates a C-style 1-3 dimensional array which can be accessed using
 * ptr[i]  or ptr[i][j] or ptr[i][j][k] -- requires pointer allocation
 * for 2-d and 3-d.
 *
 * For 2-d and up, ptr is NOT equivalent to a statically defined
 * 2-d or 3-d array.  In particular, it cannot be passed into a
 * function that requires a true pointer to a fixed-size array.
 */

/*NUMPY_API
 * Simulate a C-array
 * steals a reference to typedescr -- can be NULL
 */
NPY_NO_EXPORT int
PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int nd,
                 PyArray_Descr* type
# NPY_NO_EXPORT int NPY_NUMUSERTYPES = 0;

# omit code
    switch(mode) {
    case 0:
        length = length - n + 1;
        n_left = n_right = 0;
        break;
    case 1:
        n_left = (npy_intp)(n/2);
        n_right = n - n_left - 1;
        break;
    case 2:
        n_right = n - 1;
        n_left = n - 1;
        length = length + n - 1;
        break;
    default:
        PyErr_SetString(PyExc_ValueError, "mode must be 0, 1, or 2");
        return NULL;
    }

don't mess with the internal APIs if this is your first crack at the codebase and you are on a deadline. Too late for me.

like image 39
sikef Avatar answered Sep 22 '22 13:09

sikef