3

SWIG と numpy の些細な問題で立ち往生しています。numpy に接続したい C の特殊な行列 (n,k) ベクトル (k) 積があります。したがって、乗算前の出力ベクトル (n) の形状は常にわかっています。

現在、C 関数はメモリを割り当て、計算された積に double* を返します。メモリリークを防ぎ、Cコードの変更を避けるために、ドットの例のようにインターフェースします:

%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);
}
%}

ここで、出力ベクトルを ARGOUT_ARRAY1 として指定しているため、関数は Python で次のように呼び出されます。

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

これは不便です。swig に内部的にサイズを伝える方法はありますか? または、ユーザーフレンドリーなインターフェイスを提供して、次のようにラッパーを追加する唯一の方法です。

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

前もって感謝します。

4

1 に答える 1