如何使用python-CFFI在GSL中包装随机变量生成函数?

时间:2014-09-28 23:50:30

标签: python random cython gsl python-cffi

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

0 个答案:

没有答案