我一直在尝试编写一个返回指针数组(interv
)的C类型函数,我想在 python中调用此函数型函数(sampler
)。我写了下面的代码,但它返回的结果是错误的。代码被编译,但doubling
函数返回memoryview
函数中的sampler
对象的指针数组不正确。
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)
在python函数中将指针数组作为numpy数组返回的正确方法是什么? 提前谢谢。
答案 0 :(得分:3)
在def in_all_three(listA, listB, listC):
for x in listA:
if x in listB and x in listC:
return True
return False
函数中,释放已分配的内存并返回刚刚释放的指针。在doubling
中使用时,该指针不再指向已释放的数据。
sampler
由于您正在使用NumPy数组,因此最好使用内存视图来传递指针,使用cython数组来专门分配数据。
Cython数组基于对象生命周期自动执行内存管理,而内存视图可以接受cython和/或numpy数组,而无需复制作为指针和手动内存管理的替代。
请参阅documentation for examples以及coercion of numpy arrays to cython arrays。