簡體   English   中英

在SWIG中返回未指定大小的numpy數組

[英]Return numpy array of unspecified size in SWIG

我的目標是將SWIG與C和Python結合使用來創建一個函數,該函數將NumPy數組作為輸入並返回另一個NumPy數組。 返回的數組的大小不確定,具體取決於輸入數組。 不幸的是,當我嘗試運行代碼時,我得到了一個空數組。 這是一個顯示問題的“最小”示例。 我通過以下代碼運行此代碼:

python setup.py build_ext --inplace
python test.py

感興趣的文件復制到下面。 如果您知道如何使此代碼返回非空NumPy數組,請告訴我。 謝謝!

cancelterms.c:

#include "cancelterms.h"
void cancel(double complex* vec, int m, int n, double complex sum[])
{   

    // Some code that processes vec.

    // This is just an example. In practice the following lines will depend on vec.
    sum[0] = 1.0;
    sum[1] = 2.5;
    sum[2] = 3.6;
}

cancelterms.h:

#include <stdlib.h>
#include <stdio.h>
#include <complex.h>

void cancel(double complex* vec, int m, int n, double complex sum[]);

cancelterms.i:

%module cancelterms
%{
/* Put header files here or function declarations like below */
    #define SWIG_FILE_WITH_INIT
    #include "cancelterms.h"
%}

%include "numpy.i"
%include <complex.i>

%numpy_typemaps(double complex, NPY_CDOUBLE, int)

%init %{
    import_array();
%}

%apply (double complex* INPLACE_ARRAY2, int DIM1, int DIM2) {(double complex* vec, int m, int n)}
%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[])}

%include "cancelterms.h"

setup.py:

# Import necessary modules.
from distutils.core import setup, Extension
import numpy as np

try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()

example_module = Extension('_cancelterms', sources=['cancelterms.c', 'cancelterms.i'], include_dirs = [numpy_include])

setup(name='cancelterms', ext_modules=[example_module], py_modules=["cancelterms"])

test.py:

import cancelterms
import numpy as np

a=np.array([[1.0j,2.0j,3.0j,4.0j,5.0j,6.0j],[-1.0j,-2.0j,-3.0j,6.0j,7.0j,8.0j]])
print cancelterms.cancel(a)

不幸的是,numpy.i太大,無法在此處粘貼,但是我使用了numpy github存儲庫中的標准numpy.i文件,並做了一些小的修改,即在類型列表中添加了double complex。

...[ANY]映射適用於具有硬編碼維的數組。 對於輸入數組,這在numpy.i文檔中有明確說明,但也適用於其他數組。

例如,它們可以用作:

%apply (double complex ARGOUT_ARRAY1[ANY]) {(double complex sum[5])}

如果您的函數采用大小為5的數組(由調用方/在包裝代碼中分配)。

關鍵是SWIG無法得知argout數組sum大小。 您的代碼完全可以編譯和運行完全是巧合。 看一下生成的包裝器代碼(搜索“ wrap_cancel”),您將看到發生了什么。

還有以下類型映射:

  • ( DATA_TYPE* ARGOUT_ARRAY1, int DIM1 )
    您可以在其中指定要預分配的數組的大小
  • ( DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
    該數組是由函數分配的,但另外還會返回分配的數組的大小。

在您的情況下,函數cancel為數組sum分配內存,假設調用方有某種方法可以確定大小。 在這種情況下,沒有預定義的類型映射。

這類似於函數僅返回double complex *精度double complex * ,如numpy.i的文檔中所述:

如果遇到函數或方法返回指向數組的指針的情況,則最好的選擇是編寫自己要包裝的函數版本,對於類方法,使用%extend或%ignore和%重命名功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM