Lawerance
Lawerance

Reputation: 131

Pass 2d array as argument to a function using numpy and swig

I'm trying to pass a 2D numpy array of type double to the function load_denseSPD_from_console using the following files. But I keep getting errors (see below)

// "test.h"
SPDMATRIX_DENSE load_denseSPD_from_console(double* numpyArr,
                                           int row_numpyArr,
                                           int col_numpyArr);

// "test.cpp"
SPDMATRIX_DENSE load_denseSPD_from_console(double* numpyArr,
                                           int row_numpyArr,
                                           int col_numpyArr) {
  /* Load values of a numpy matrix `numpyArr` into a SPD matrix container
   
   @numpyArr: double pointer of type double

   @row_numpyArr: row of `numpyArr`

   @col_numpyArr: col of `numpyArr`

   @return: copy of a locally created SPD matrix which contains the values
            from `numpyArr`
  */
  SPDMATRIX_DENSE K(row_numpyArr, col_numpyArr);  // container for numpyArr

  // Fill the container
  int index = -1;
  for (int i = 0; i < row_numpyArr; i++)
    for (int j = 0; j < col_numpyArr; j++) {
      index = i * col_numpyArr + j;
      K.data()[index] = numpyArr[index];  // .data()'s type is double*
    }

  return K;
}


// "test.i"
%{
  #define SWIG_FILE_WITH_INIT
  #include "../example/test.cpp"
%}
%include "../example/test.cpp"

// Use numpy array
%include "numpy.i"
%init %{
  import_array();
%}


%apply (double* IN_ARRAY2, int DIM1, int DIM2 ) \
      {(double* numpyArr, int row_numpyArr, int col_numpyArr)};

Here is the python file that I run

# "test.py"

import test
import numpy as np

a = np.array([[2, -1, 0], [-1, 2, -1], [0, -1, 2]], dtype=np.double)

tools.load_denseSPD_from_console(a, 3, 3)
tools.load_denseSPD_from_console(a)

The error from the command

test.load_denseSPD_from_console(a, 3, 3)

is TypeError: in method 'load_denseSPD_from_console', argument 1 of type 'double *'

And the error from the command

test.load_denseSPD_from_console(a)

is TypeError: load_denseSPD_from_console() takes exactly 3 arguments (1 given)

I have looked up other posts Swig and multidimensional arrays but I don't know where I got wrong.

Upvotes: 0

Views: 688

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 177685

%include "../example/test.cpp" to the last line of the test.i file so %include "numpy.i" and the %apply are processed first. If the typemaps (via the %apply) are not processed first, then the code of the typemaps won't be used when processing your functions. This is why the errors you were seeing required 3 parameters instead of 1...the typemap that translates a single numpy array paramter to the three C parameters wasn't applied.

Also, you can just %include "../example/test.h" instead of the .cpp. The actual code isn't needed, just the declarations.

Upvotes: 1

Related Questions