gpt4 book ai didi

r - 在 C++11 中为 创建一个与 R 中的 PRNG 结果相匹配的 PRNG 引擎

转载 作者:行者123 更新时间:2023-12-02 14:55:25 32 4
gpt4 key购买 nike

这个问题是双重的。我正在将 R 脚本翻译成 C++,它使用 L'Ecuyer 组合多重递归生成器 (CMRG) 作为引擎(特别是 MRG32k3a),然后从区间 (0, 1) 上的均匀分布返回一个随机数。 R 中的一个最小示例如下所示:

seednum<-100                              # set seed
set.seed(seednum, kind="L'Ecuyer-CMRG") # set RNG engine
runif(1) # set distribution

我希望能够在 R 脚本和 C++ 代码之间验证我的结果(因为生成的随机数只是开始)。我发现 PRNG 在不同语言中具有相同的种子不一定会产生相同的结果(因为它们可能具有编译器可以自由指定的参数),如 SO 帖子中所示 herehere .也就是说,使用相同的种子、相同的引擎和相同的分布可能会根据 PRNG 的特定实现而产生不同的随机数。下面是 R 和 C++11 之间的相关示例。在 R 中使用无处不在的 Mersenne-Twister PRNG:

seednum<-100
set.seed(seednum, kind="Mersenne-Twister")
runif(1)

产生随机数 0.3077661 .在 C++11 中做同样的事情:

#include <iostream>
#include <random>

int main()
{
unsigned seed = 100;

std::mt19937 generator (seed);

std::uniform_real_distribution<double> distribution (0.0, 1.0);

std::cout << distribution(generator) << std::endl;

return 0;
}

产生随机数 0.671156 .我最初对这个结果感到困惑,但之前的 SO 问题为我澄清了这一点(如上链接)。似乎有一些参数被传递给 R 中的 MRG32k3a,我需要在 C++ 中复制这些参数以生成相同的随机数。因此,第一个问题是,我在哪里可以找到有关 R 中指定这些参数的 MRG32k3a 实现的文档?

第二个问题是关于在 C++11 中实现这个生成器的。此生成器未出现在 <random> 中的预配置引擎类型列表中C++11 库已列出 here .可以找到用 C 实现的 MRG32k3a 示例 here如下所示:

/*
32-bits Random number generator U(0,1): MRG32k3a
Author: Pierre L'Ecuyer,
Source: Good Parameter Sets for Combined Multiple Recursive Random
Number Generators,
Shorter version in Operations Research,
47, 1 (1999), 159--164.
---------------------------------------------------------
*/
#include <stdio.h>

#define norm 2.328306549295728e-10
#define m1 4294967087.0
#define m2 4294944443.0
#define a12 1403580.0
#define a13n 810728.0
#define a21 527612.0
#define a23n 1370589.0

/***
The seeds for s10, s11, s12 must be integers in [0, m1 - 1] and not all 0.
The seeds for s20, s21, s22 must be integers in [0, m2 - 1] and not all 0.
***/

#define SEED 100

static double s10 = SEED, s11 = SEED, s12 = SEED,
s20 = SEED, s21 = SEED, s22 = SEED;


double MRG32k3a (void)
{
long k;
double p1, p2;
/* Component 1 */
p1 = a12 * s11 - a13n * s10;
k = p1 / m1;
p1 -= k * m1;
if (p1 < 0.0)
p1 += m1;
s10 = s11;
s11 = s12;
s12 = p1;

/* Component 2 */
p2 = a21 * s22 - a23n * s20;
k = p2 / m2;
p2 -= k * m2;
if (p2 < 0.0)
p2 += m2;
s20 = s21;
s21 = s22;
s22 = p2;

/* Combination */
if (p1 <= p2)
return ((p1 - p2 + m1) * norm);
else
return ((p1 - p2) * norm);
}

int main()
{
double result = MRG32k3a();

printf("Result with seed 100 is: %f\n", result);

return (0);
}

如前所述,我需要使用此生成器来创建一个可以馈送到统一真实分布中的引擎。问题是我不知道这是如何完成的,而且我似乎无法在任何地方找到任何信息(除了知道引擎是类之外)。有没有可用的 C++11 资源可以帮助我完成这样的任务?我不是在寻求问题的解决方案,而是可以帮助我自己实现的建议。

最佳答案

The first question is thus, where can I find the documentation on the MRG32k3a implementation in R that specifies these parameters?

我会使用来源: https://github.com/wch/r-source/blob/5a156a0865362bb8381dcd69ac335f5174a4f60c/src/main/RNG.c#L143

The problem is I have no idea how this is done and I can't seem to find any information anywhere (aside from knowing that engines are classes).

可以在此处找到对 RandomNumberEngine 的要求: https://en.cppreference.com/w/cpp/named_req/RandomNumberEngine虽然足以满足 UniformRandomBitGenerator如果你想使用 uniform_real_distribution :

Expression      Return type     Requirements
G::result_type T T is an unsigned integer type
G::min() T Returns the smallest value that G's operator()
may return. The value is strictly less than
G::max().
G::max() T Returns the largest value that G's operator() may
return. The value is strictly greater than
G::min()
g() T Returns a value in the closed interval [G::min(),
G::max()]. Has amortized constant complexity.

主要问题是 MRG32k3a 旨在返回 (0,1) 中的 float ,而 C++ UniformRandomBitGenerator 返回整数类型。为什么要与 <random> 集成标题?

您必须考虑的其他困难:

备选方案包括直接使用 R 源代码而不与 <random> 集成 header 或链接到 libR .

关于r - 在 C++11 中为 <random> 创建一个与 R 中的 PRNG 结果相匹配的 PRNG 引擎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53201392/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com