2

我遇到的困难是 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
4

0 回答 0