将二维动态指针数组作为参数传递给cython

时间:2017-11-23 12:54:28

标签: python c arrays pointers cython

在我的代码中,我试图定义一个动态数组,其中行和列的数量会发生变化,这取决于函数内部的新条件,这意味着我可能会添加更多的行或列。我试图制作二维指针数组,我希望能够将这个2-D指针数组作为参数传递给函数。

这是我的代码的一小部分:

更新:test.pyx

from libc.string cimport memset
import numpy as np
cimport numpy as np
cimport cython
from cython.view cimport array as cvarray
from libc.stdlib cimport malloc, free
from libc.math cimport log, exp
from cython_gsl cimport *
import ctypes
cdef gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937)
cdef int** zeros2(dim):
     assert len(dim) == 2
     cdef int i
     cdef int **matrix
     matrix = <int**> malloc(sizeof(int*) * dim[0])
     for i from 0 <= i < dim[0]:
         matrix[i] = <int*> malloc(sizeof(int) * dim[1])
         memset(matrix[i], 0, sizeof(int) * dim[1])
     return matrix

@cython.cdivision(True)
@cython.wraparound(False)
@cython.boundscheck(False)
cdef void generator(double* alpha,int* D, double* m):

     cdef Py_ssize_t i
     for i from 0 <= i < D[0]:            
        m[i]=gsl_ran_beta(r, alpha[0], 1)
     return

@cython.cdivision(True)     
@cython.boundscheck(False)
@cython.wraparound(False)     
cdef void initializer(double* alpha, int* D, int* N, double* m, int** Z ):
     cdef int i, j         

     generator(alpha, D, &m[0])

     for i from 0 <= i < D[0]:
         for j from 0 <= j < N[0]: 
             Z[j][i]= gsl_ran_bernoulli(r, m[i]) 
             print Z[j][i]
     return

def run(int n, int d, double alpha):
    cdef np.ndarray[double, ndim=1, mode='c'] mu=np.empty((d,), dtype=ctypes.c_double)
    cdef int **Z = zeros2((n, d))

    initializer(&alpha, &d, &n,  &mu[0], <int **>(&Z[0][0]) )

setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize
from numpy import get_include
import numpy
import cython_gsl
from Cython.Distutils import build_ext
ext_modules = [
    Extension(
        "test",
        ["test.pyx"],
        libraries=cython_gsl.get_libraries(),
        library_dirs=[cython_gsl.get_library_dir()],
        include_dirs=[numpy.get_include(), cython_gsl.get_include()])

]
ext_modules = cythonize(ext_modules)

setup(
    name='test',
    ext_modules=ext_modules,
cmdclass={'build_ext': build_ext})

更新

代码被编译但是当我在python中导入run function时,我得到了这个错误:

>>> import test
>>> test.run( 10, 4,0.9)
Segmentation fault (core dumped)

我不确定我定义的二维数组是解决我定义动态数组问题的最佳方法,我得到这个错误的原因是什么?

欢迎任何建议。

2 个答案:

答案 0 :(得分:1)

你当前的问题是:

Sub Macro1()
    Dim s As String
    s = "<" & CStr(Date)
    With Columns("A:A")
        .AutoFilter
        .AutoFilter Field:=1, Criteria1:=s
    End With
End Sub

获取第一行第一个元素的地址并将其强制转换为<int **>(&Z[0][0]) 。它实际上是int**(因为它是int*的地址)。因此int写入的内存是无意义的,并且您会遇到分段错误。演员表明你做错了。

您只需要传递已经initializer的{​​{1}}。

答案 1 :(得分:0)

问题是ndalpha是Python变量,因此&n不是您可以执行的操作。您可以将run更改为cdef功能,也可以创建临时版本:

cdef int _n = n;

然后传递&_n

但是,根据您的代码,无论如何,将指针传递给这三个变量的重点是什么?你不能修改它们。你可以简单地在没有指针的情况下传递它们。

相关问题