簡體   English   中英

將二維動態指針數組作為參數傳遞給cython中的函數

[英]passing a two dimensional dynamic pointer array as an argument to a function in cython

在我的代碼中,我試圖定義一個動態數組,該數組的行數和列數會變化,具體取決於函數內部的新條件,這意味着我可能會添加更多的行或列。 我試圖制作二維指針數組,並且希望能夠將此二維指針數組作為函數的參數傳遞。

這是我的代碼的一小部分:

更新: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)

我不確定我定義的二維數組是否是解決定義動態數組問題的最佳方法,請問出現此錯誤的原因是什么?

任何建議將是最歡迎的。

您的直接問題是:

<int **>(&Z[0][0])

接受第一行的第一個元素的地址,並將其轉換為int** 它實際上是一個int* (因為它是int的地址)。 因此, initializer寫入的內存是無用的,並且您會遇到分段錯誤。 強制轉換通常表明您做錯了事。

您只需要傳遞已經是int** Z

問題在於ndalpha是Python變量,因此&n不能執行。 您可以將run更改為cdef函數,也可以創建一個臨時版本:

cdef int _n = n;

然后通過&_n

但是,根據您的代碼,無論如何將指針傳遞給這三個變量有什么意義? 您無需修改​​它們。 您可以簡單地傳遞它們而無需使用指針。

暫無
暫無

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

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