我遇到的困难是GSL中的随机变量(RV)生成函数需要指向特殊结构gsl_rng
的指针作为其参数之一,例如
double gsl_rng_uniform (const gsl_rng * r); // generate uniform RVs
double gsl_ran_gaussian (const gsl_rng * r, double sigma); // generate Gaussian RVs
由于所有RV生成函数共享相同的"随机源",由gsl_rng * r
表示,因此C中的典型使用模式是预先构造gsl_rng * r
,然后调用各种随机变量生成函数,最后解构r
。
我想在python中使用CFFI来进行本机C调用以加速蒙特卡罗模拟程序。我现在的问题是如何适当地隐藏"来自python端的C指针gsl_rng * r
,同时确保它由我从python调用的所有RV生成函数共享?
P.S。我知道如何在Cython中实现这一点,如下所示:
## demo.pyx --- a Cython file
## declaration of C functions and structs
cdef extern from "math.h":
double exp(double)
cdef extern from "gsl/gsl_rng.h":
ctypedef struct gsl_rng:
pass
ctypedef struct gsl_rng_type:
pass
const gsl_rng_type * gsl_rng_default
gsl_rng * gsl_rng_alloc (const gsl_rng_type *)
void gsl_rng_free (gsl_rng *)
double gsl_rng_uniform (const gsl_rng *)
cdef extern from "gsl/gsl_randist.h":
double gsl_ran_gaussian (const gsl_rng *, double)
## define a python function that generates RVs
def foo(double sigma):
cdef:
int i;
double s;
const gsl_rng_type * T = gsl_rng_default;
gsl_rng * r = gsl_rng_alloc(T)
for i in range(10):
s += gsl_ran_gaussian(r, sigma) + gsl_rng_uniform(r); ## share r
gsl_rng_free(r)
return s