我有一个满足 C++ 随机数引擎要求的 PRNG,如所述 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
?
最佳答案
我最终做了以下事情来让事情正常进行。请注意,我的随机数引擎是我程序中的一个全局变量: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 的 rng.c
中定义的 gsl_rng_alloc
确认这是正确的设置。
关于c++ - 如何为 GSL(GNU 科学图书馆)改编 C++ 风格的随机数引擎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50806962/