问题描述
我有一些具有以下声明的C代码:
I have some C code that has the following declaration:
int myfunc(int m, int n, const double **a, double **b, double *c);
因此,a
是一个恒定的2D数组,b
是一个2D数组,而c
是一个1D数组,它们都是动态分配的. b
和c
在传递给myfunc
之前不需要特别指定任何内容,应将其理解为输出信息.出于此问题的目的,不允许更改myfunc
的声明.
So a
is a constant 2D array, b
is a 2D array, and c
is a 1D array, all dynamically allocated. b
and c
do not need to be anything specifically before they are passed to myfunc
, and should be understood as output information. For the purposes of this question, I'm not allowed to change the declaration of myfunc
.
问题1:如何将给定的numpy数组a_np
转换为具有此C函数所需格式的数组a
,以便可以在Cython中使用以下命令调用此C函数: a
?
Question 1: How do I convert a given numpy array a_np
into an array a
with the format required by this C function, so that I can call this C function in Cython with a
?
问题2:下面的b
和c
的声明正确无误,还是C函数需要采用其他某种格式才能将它们理解为2D和1D数组? (分别)?
Question 2: Are the declarations for b
and c
below correct, or do they need to be in some other format for the C function to understand them as a 2D and 1D array (respectively)?
我的尝试:
myfile.pxd
cdef extern from "myfile.h":
int myfunc(int p, int q, const double **a, double **b, double *c)
mytest.pyx
cimport cython
cimport myfile
import numpy as np
cimport numpy as np
p = 3
q = 4
cdef:
double** a = np.random.random([p,q])
double** b
double* c
myfile.myfunc(p, q, a, b, c)
然后在iPython中运行
Then in iPython I run
import pyximport; pyximport.install()
import mytest
定义为a
的行向我显示错误消息Cannot convert Python object to 'double **'
.我没有收到有关b
或c
的任何错误消息,但是由于我目前无法运行C函数,因此我不确定b
和c
的声明是否正确编写(也就是说,这将使C函数分别输出2D和1D数组.)
The line with the definition of a
gives me the error message Cannot convert Python object to 'double **'
. I don't get any error messages regarding b
or c
, but since I'm unable to run the C function at this time, I'm not sure the declarations of b
and c
are written correctly (that is, in a way that will enable the C function to output a 2D and a 1D array, respectively).
其他尝试:我也尝试按照解决方案此处进行操作,但这没有我不能使用myfunc
声明中的双星号类型的数组.解决方案此处不适用于我的任务,因为我无法更改myfunc
的声明.
Other attempts: I've also tried following the solution here, but this doesn't work with the double-asterisk type of arrays I have in the myfunc
declaration. The solution here does not apply to my task because I can't change the declaration of myfunc
.
推荐答案
在cython中创建一个辅助数组
要从numpy数组中获取double**
,可以在* .pyx文件中创建指针的帮助器数组.此外,您必须确保numpy数组具有正确的内存布局. (这可能涉及创建副本)
Create a helper array in cython
To get a double**
from a numpy array, you can create a helper-array of pointers in your *.pyx file. Further more, you have to make sure that the numpy array has the correct memory layout. (It might involve creating a copy)
如果您的C函数期望fortran顺序(一个列表中的所有x坐标,另一列表中的所有y坐标,第三列表中的所有z坐标,如果您的数组a对应于3D空间中的点列表)
If your C-function expects fortran order (all x-coordinates in one list, all y coordinates in another list, all z-coordinates in a third list, if your array a corresponds to a list of points in 3D space)
N,M = a.shape
# Make sure the array a has the correct memory layout (here F-order)
cdef np.ndarray[double, ndim=2, mode="fortran"] a_cython =
np.asarray(a, dtype = float, order="F")
#Create our helper array
cdef double** point_to_a = <double **>malloc(M * sizeof(double*))
if not point_to_a: raise MemoryError
try:
#Fillup the array with pointers
for i in range(M):
point_to_a[i] = &a_cython[0, i]
# Call the C function that expects a double**
myfunc(... &point_to_a[0], ...)
finally:
free(point_to_a)
C订单
如果您的C函数期望C阶([x1,y1,z1]是第一个列表,[x2,y2,z2]是第二个3D点列表):
C-order
If your C-function expects C-order ([x1,y1,z1] is the first list, [x2,y2,z2] the second list for a list of 3D points):
N,M = a.shape
# Make sure the array a has the correct memory layout (here C-order)
cdef np.ndarray[double, ndim=2, mode="c"] a_cython =
np.asarray(a, dtype = float, order="C")
#Create our helper array
cdef double** point_to_a = <double **>malloc(N * sizeof(double*))
if not point_to_a: raise MemoryError
try:
for i in range(N):
point_to_a[i] = &a_cython[i, 0]
# Call the C function that expects a double**
myfunc(... &point_to_a[0], ...)
finally:
free(point_to_a)
这篇关于将Cython中的numpy数组传递给需要动态分配数组的C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!