2017-11-23 38 views
0

私のコードでは、行と列の数が変化する動的配列を定義しようとしています。関数内の新しい条件に依存します。行や列を追加することがあります。 2次元のポインタ配列を作成しようとしましたが、この2次元のポインタ配列を関数の引数として渡したいと考えています。二次元動的ポインタ配列を引数として関数に渡す

これは私のコードの小さな一部です:

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

n,dおよびalphaはPython変数なので、&nは実行できません。あなたはruncdefに機能を変更、または多分一時的なバージョンを作成することができます

cdef int _n = n; 

、その後、とにかく、これら三つの変数へのポインタを渡すのポイントは何でしょう、あなたのコードに基づいて、しかし&_n

を渡します?あなたはそれらを変更しません。あなたは単にポインタなしでそれらを渡すことができます。

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

が最初の行の最初の要素のアドレスを取得してint**にそれをキャスト:

1

あなたの当面の問題は、ということです。実際にはint*intのアドレスなので)です。したがって、initializerに書き込むメモリはナンセンスであり、セグメンテーションフォルトが発生します。キャストは、しばしば間違っていることを示しています。

int**Zを渡すだけで済みます。

+0

答えに感謝します!このエラーは修正されましたが、主な質問は動的配列を定義する最良の方法です。 gsl_matrixはどうですか?それはどのようにcythonで動作するのですか?私はまた、正方行列の逆行列を見つける必要があり、それは良い選択だろうと思いますよね?何がお勧めですか? – Dalek

+0

numpy配列を使用するだけではどうですか?しかし、私は本当に知らない。私は明らかなバグを見て、それを指摘する価値があると思ったので、私はこの回答を「コミュニティwiki」としましたが、完全な質問には答えたくありませんでした。 – DavidW

関連する問題