我遇到的困难是 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 调用以加速蒙特卡洛模拟程序。我现在的问题是如何gsl_rng * r
从 python 端适当地“隐藏” C 指针,同时确保它由我从 python 调用的所有 RV 生成函数共享?
PS我知道如何在 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