나는 포인터 배열 (interv
)을 반환하는 C 형 함수를 작성하기 위해 노력하고 내가 python- 내에서이 함수를 호출하고 싶습니다에 대한 포인터 배열을 반환하는 C 형 기능 함수 (sampler
)을 입력하십시오. 다음 코드를 작성했지만 결과가 잘못되었습니다. 코드가 컴파일되지만 sampler
함수의 memoryview
개체로 함수 doubling
이 반환하는 포인터 배열이 올바르지 않습니다.사이 썬
from cpython cimport array
import cython
import numpy as np
import ctypes
cimport numpy as np
cimport cython
from libc.stdlib cimport malloc, free
from libcpp.vector cimport vector
cdef extern from "gsl/gsl_rng.h":#nogil:
ctypedef struct gsl_rng_type:
pass
ctypedef struct gsl_rng:
pass
gsl_rng_type *gsl_rng_mt19937
gsl_rng *gsl_rng_alloc(gsl_rng_type * T)
cdef gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937)
cdef extern from "gsl/gsl_randist.h" nogil:
double unif "gsl_rng_uniform"(gsl_rng * r)
double unif_interval "gsl_ran_flat"(gsl_rng * r,double,double) ## syntax; (seed, lower, upper)
double exponential "gsl_ran_exponential"(gsl_rng * r,double) ## syntax; (seed, mean) ... mean is 1/rate
cdef double* doubling(double x0, double y, double w, int p):
cdef double* interv = <double *>malloc(2 * cython.sizeof(double))
if interv is NULL:
raise MemoryError()
cdef double u
cdef int K
cdef bint now_left
cdef double g_interv[2]
u = unif_interval(r,0,1)
interv[0] = x0 - w*u
interv[1] = interv[0] + w
if p>0:
K = p
g_interv[0]= f(interv[0])
g_interv[1]= f(interv[1])
while ((g_interv[0] > y) or (g_interv[1] > y)):
u = unif_interval(r,0,1)
now_left = (u < 0.5)
if (now_left):
interv[0] -= (interv[1] - interv[0])
g_interv[0]=f(interv[0])
else:
interv[1] += (interv[1] - interv[0])
g_interv[1]=f(interv[1])
if p>0:
K-=1
if (K<=0):
break
try:
return interv
finally:
if interv is not NULL:
free(interv)
def sampler(int n_sample,
int p = 0,
double x0=0.0,
double w=0.1):
cdef vector[double] samples
cdef double vertical
cdef Py_ssize_t i
cdef np.ndarray[ndim=1, dtype=np.float64_t] interv
cdef np.float64_t[:] view
for 0<= i <n_sample:
vertical = f(x0) - exponential(r, 1)
view=<np.float64_t[:2]>doubling(x0, vertical, w, p)
interv= np.asarray(view)
samples.push_back(interv[0])
return samples
cdef double f(double x):
cdef double a=5.
return log(a)+(a-1.)*log(x)
파이썬 함수에서 포인터 배열을 numpy 배열로 반환하는 올바른 방법은 무엇입니까? 미리 감사드립니다.
'doubling' 함수는 반환하는 포인터를 해제합니다. 그 포인터가 어떻게 데이터를 가질 것으로 기대합니까? – danny
@danny 정말요? 이유인가? 그렇다면 포인터에 대한 메모리는 어디에서 해제해야합니까? – Dalek
[c malloc 배열 포인터가 cython에서 반환 될 수 있습니다] 가능한 복제본 (https://stackoverflow.com/questions/25102409/c-malloc-array-pointer-return-in-cython) – DavidW