Bort
Bort

Reputation: 2491

Return a vector of known size without additional wrapper?

I am just stuck on a trivial problem with SWIG and numpy. I have a specialized matrix (n,k) vector (k) product in C which I want to interface to numpy. So I always know the shape of the output vector (n) before the multiplication.

Currently, the C function allocates the memory and returns a double* to the calculated product. To prevent memory leakage and to avoid changing the C-code I interface it like in the dot example:

%apply (int DIM1, int DIM2, double* IN_ARRAY2) {(int m1, int nd1, double* xd)};
%apply (int DIM1, double* IN_ARRAY1) {(int nd2, double* zd)};
%apply (int DIM1, double* ARGOUT_ARRAY1) {(int nd4, double* za)};

%rename (mat_vec_mul) my_mat_vec_mul;
%ignore mat_vec_mul;
%include "math_lib.h"
%exception my_mat_vec_mul {
    $action
    if (PyErr_Occurred()) SWIG_fail;
}
%inline %{
void my_mat_vec_mul( int m1, int nd1, double* xd, int nd2, double* zd, int nd4, double* za) 
{
    if (nd1 != nd2) {
        PyErr_Format(PyExc_ValueError,
                     "Arrays of lengths (%d,%d) given",
                     nd1, nd2);
    }

    int i;
    double *tmp = NULL;
    tmp = mat_vec_mul(m1,nd1,xd,zd);
    for( i = 0; i < nd1; i++){
        za[i] = tmp[i];
    } 
    free(tmp);
}
%}

Now, because I am specifying the output vector as ARGOUT_ARRAY1, the function is called in python as

v = test.mat_vec_mul(A,b,A.shape[0])

which is inconvenient. Is there a way to tell swig the size internally? Or is the only way to provide a user friendly interface to add an additional wrapper around it as:

def user_interface_mat_vec_mul(A,b):
    mat_vec_mul(A,b,A.shape[0])

Thanks in advance.

Upvotes: 3

Views: 152

Answers (1)

Bort
Bort

Reputation: 2491

Here is my answer, I found a way to put the wrapper function into the swig file, which does essentially what I want:

%pythoncode %{
def mat_vec_mul(A, b):
    return _test._mat_vec_mul(A, b, A.shape[0])
%}

Upvotes: 1

Related Questions