C++中的Marsaglia正态随机变量
Marsaglia Normal Random Variables in C++
我的查询非常简单。我更喜欢用Java编写数值方法,但经常需要用C++做一些事情。我喜欢Java中的高斯随机变量,因为它使用Marsaglia算法并保持两个Normal随机变量。它在第一次调用时返回一个,在第二次调用中返回第二个,并且直到第三次调用才再次进行昂贵的计算。使用下面的oracle链接(在程序注释中),我试图用C++实现这段代码,但不知道如何编写C++版本的"同步"公共方法,这将允许我使用两个Normal随机变量。我不是一个专业的程序员,所以任何指导都将不胜感激。
简而言之,我想保留:
v2*乘数
// This function is Similar to the GNU
// Java Implementation as seen on
// http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextGaussian%28%29
double nextGaussian() {
double v1, v2, s, nextNextGaussian;
do {
v1 = 2 * nextUniform() - 1; // between -1.0 and 1.0
v2 = 2 * nextUniform() - 1; // between -1.0 and 1.0
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = sqrt(-2 * log(s)/s);
nextNextGaussian = v2 * multiplier;
return v1 * multiplier;
}
只需将nextGaussianVal声明为静态,即
static double nextGaussianVal;
然后,nextGaussianVal的值将在下次调用该方法时可用。您可能还需要另一个静态变量来跟上当前计数,如下所示:
double nextGaussian()
{
static int count = 0;
static double nextGaussianVal;
double firstGaussianVal, v1, v2, s;
if (count == 0) {
do {
v1 = 2 * nextUniform() - 1; // between -1.0 and 1.0
v2 = 2 * nextUniform() - 1; // between -1.0 and 1.0
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = sqrt(-2 * log(s)/s);
nextGaussianVal = v2 * multiplier;
firstGaussianVal = v1 * multiplier;
count = 1;
return firstGaussianVal;
}
count = 0;
return nextGaussianVal;
}
编辑:更详细的解释——第一次调用函数时,count被初始化为零。根据if语句,执行有问题的计算,并假设firstGaussianVal和nextGaussianVal被赋值,count被赋值为1,并返回firstGaussian Valount将具有其先前分配的值1,并且nextGaussianVal包含其在第一次调用期间先前分配的数值——也就是说,由于count现在是1,因此函数将基于if语句,将零分配给计数并返回nextGaussianVal。冲洗,重复。。。
在更面向对象的情况下,您应该将这些东西保存在"随机数生成器"对象中。例如,查看以下代码:https://code.cor-lab.org/projects/nemomath/repository/entry/trunk/nemomath/src/nemo/Random.h类"gaussian"以算法的方式实现了你想要的东西。
以上建议的问题是COUNT变量应该是BOOLEAN,而不是整数。此外,存储的高斯也需要是静态的。
我要感谢大家的帮助,帮助我找到我想要的正确解决方案。我知道这个片段属于一个对象。我现在有理由把它放在一个文件里。
double nextGaussian() {
// Static variables allow the function to make use of
// both Gaussian Random variables. Generated by the polar Marsaglia
// method This makes the function much more efficient with will
// pay off for simulations
static bool hasNextGaussian = false;
static double nextNextGaussian;
double v1, v2, s;
if (!hasNextGaussian) {
do {
v1 = 2 * nextUniform() - 1; // between -1.0 and 1.0
v2 = 2 * nextUniform() - 1; // between -1.0 and 1.0
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = sqrt(-2 * log(s)/s);
nextNextGaussian = v2 * multiplier;
hasNextGaussian = true;
return v1 * multiplier;
} else {
hasNextGaussian = false;
return nextNextGaussian;
}
}
double nextUniform(){
double Uniform = rand() / double(RAND_MAX);
return Uniform;
}
- 将正态随机变量与任意 RHO(corrcoef) 相关联
- 为什么变量的打印地址在每次执行时都会打印随机值,即使它是 C 中的逻辑地址?
- 如何让变量随机输出四个单词之一
- 如何生成随机变量或类名并在以后使用?
- 尝试生成随机变量时获得"-nan(ind)"
- 为什么在 sync_with_stdio(false) 之前使用 cin 为下一个 i/p 变量提供随机值
- 如何使计算机每次在猪游戏中进行随机变量
- 如何通过Mersenne Twister生成不重复的随机变量
- C 中的Bernoulli随机变量
- 快速在C 中添加随机变量
- 为什么这个随机变量没有均匀分布?
- 具有QuantLib的泊松随机变量
- 生成n个随机变量,并用c++将它们相乘
- C++中的Marsaglia正态随机变量
- 随机变量总是生成5
- 随机变量名称,可能吗?
- 用相同的公式生成0和1之间的两个随机变量
- 如何最有效地防止正态分布的随机变量为零
- 如何在没有for循环的情况下请求boost::normaldistribution生成一个大的随机变量向量
- 有没有办法在不计算 CDF 的情况下从非标准分布生成随机变量