How to convert numpy ndarray to C float *[]

Deadly 提交于 2019-12-05 21:48:24

There is SciPy documentation on exactly this: How to pass numpy arrays to C code via SWIG (and vice versa). Have a look here.

Basically, there is a swig interface file numpy.i that you use in the following way. In your swig interface file you include:

%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}

and then add in your interface file, before mentioning your C functions:

%apply ( float* IN_ARRAY2, int DIM1, int DIM2 ) {
    (float* your_array_parameter_name, int N_parameter_name, int M_parameter_name)
};

This works for ordinary C float arrays. I am not quite sure what a float* [] is. You may need to write your own typemaps for this, for which you can use the utility macros provided by numpy.i. But it is all explained in the numpy.i documentation mentioned above, or in the relevant swig typemap docs

Ok for everyone that might face the same problem as I did, here is how I finally solved it.

First I changed the header in the .h file and the .c file of the function from

void Flame_SetDataMatrix( Flame *self, float *data[], int N, int M, int T );

to

void Flame_SetDataMatrix( Flame *self, float *data, int N, int M, int T );

After that, I added

%apply (float* IN_ARRAY2, int DIM1, int DIM2) {
    (float *data, int N, int M)
};

To the interface file (flame.i). This makes it possible to call the function in Python like this: flame.Flame_SetDataMatrix( flameobject, data, T), where data is a numpy array with two dimensions.

The "problem" now is that the array that arrives in the C function is in the wrong format, because we want a double array (which in this case is a pointer to a pointer to a float).

The solution is to convert this array, which is wrapped in a single dimension, to reconstruct the double array in the c code like this:

//n = number of rows, m= number of columns columns
void Flame_SetDataMatrix( Flame *self, float *data, int n, int m, int dt )
{
    //convert data to float** for later use
    int i=0, j=0;
    float ** data2 = (float**) calloc( n, sizeof(float*) ); 
    for (i=0; i<n; i++){
        data2[i] = calloc( m, sizeof(float) ); 
        for (j=0; j<m; j++){
            //the data is in a single array row after row, so i*columns+j
            data2[i][j] = data[i * m + j];
        }
    }

In the end I could use the same "trick" to also get a two dimensional float array back into a numpy array, which I did have to reschape but in numpy that is easy.

Hope it will help someone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!