如何为GSL(GNU Scientific Library)改编C ++风格的随机数引擎?

时间:2018-06-11 22:34:38

标签: c++ random gsl

我有一个PRNG满足C ++随机数引擎的要求,如here所述。 (它来自PCG family)。也就是说,C ++标准库分发类可以使用引擎的实例来生成随机数:

pcg_extras::seed_seq_from<std::random_device> seed_source;
pcg32 rng(seed_source);
std::uniform_real_distribution<double> uniformDist(0., 1.);
double randomNumber = uniformDist(rng);

我需要从<random>中未包含的分布中生成样本,因此我需要使用GSL中的函数。如何将C ++引擎用于此目的? GSL rng函数都需要const gsl_rng *作为第一个参数。

gsl_rng的默认创建和用法如下:

const gsl_rng_type * T;
gsl_rng * r;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
double u = gsl_rng_uniform (r);

要使用我自己的引擎,我相信我需要定义一个gsl_rng_type,如"gsl/gsl_rng.h"中所定义:

typedef struct
  {
    const char *name;
    unsigned long int max;
    unsigned long int min;
    size_t size;
    void (*set) (void *state, unsigned long int seed);
    unsigned long int (*get) (void *state);
    double (*get_double) (void *state);
  }
gsl_rng_type;

我猜测我需要的是正确的吗?有没有关于我如何定义自定义gsl_rng_type的例子,特别是三个必要的成员函数?可能是我的void *state

2 个答案:

答案 0 :(得分:0)

这是正确的。整个公共界面在https://github.com/LuaDist/gsl/blob/master/rng/gsl_rng.h

中列出

答案 1 :(得分:0)

我最终做了以下工作以使事情顺利进行。请注意,我的随机数引擎是我程序中的全局变量:g_rng

有必要构造一个结构来保存与RNG相关的任何状态。在我的例子中,我只是指向pcg32

// In some header file, e.g. rng.h
typedef struct
{
    pcg32 *rng;
} gsl_pcg_state;

必须定义三个函数“set”,“get”和“get_double”:

// In some header file, e.g. rng.h
static void gsl_pcg_set(void *state, unsigned long int seed)
{
    ((gsl_pcg_state *)state)->rng = &g_rng;
    (void)seed;                 // unused
}

static unsigned long int gsl_pcg_get(void *state)
{
    return (*((gsl_pcg_state *)state)->rng)();
}

static double gsl_pcg_get_double(void *state)
{
    // Range [0, 1)
    return (*((gsl_pcg_state *)state)->rng)() / 4294967296.;
}

然后可以实例化gsl_rng_type

static const gsl_rng_type gsl_rng_pcg = {
    "pcg",
    0xffffffffUL,
    0,
    sizeof(gsl_pcg_state),
    &gsl_pcg_set,
    &gsl_pcg_get,
    &gsl_pcg_get_double
};

在主程序中,你会......

gsl_rng *r;
r = gsl_rng_alloc(&gsl_rng_pcg);
// one can now call various gsl_ran_[...] functions

gsl_rng_free(r);

查看GSL gsl_rng_alloc中定义的rng.c,确认这是正确的设置。