我的查询非常简单。我更喜欢在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;
}
答案 0 :(得分:3)
只需将 nextGaussianVal 声明为 static ,即
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,并返回 firstGaussianVal 。下次调用该函数时, count 将使其先前指定的值为1,而 nextGaussianVal 将包含先前在第一次调用期间分配的值 - 即说,因为 count 现在是1,该函数将根据 if 语句将零指定给计数并返回 nextGaussianVal < / strong>即可。冲洗,重复......
答案 1 :(得分:1)
在更加面向对象的问题中,您应该将这些内容保存在“随机数生成器”对象中。查看此代码的实例: https://code.cor-lab.org/projects/nemomath/repository/entry/trunk/nemomath/src/nemo/Random.h “gaussian”这个类以算法的方式实现了你想要的东西。
答案 2 :(得分:-1)
上述建议的问题是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;
}