尝试生成随机变量时获得"-nan(ind)"

Getting "-nan(ind)" when trying to generate random variates

本文关键字:-nan ind 随机 变量      更新时间:2023-10-16

我正在尝试通过使用极坐标以及平均值和西格玛值来生成两个标准正态变量 r1、r2,从而尝试生成随机变量。但是,当我运行代码时,我不断得到一个"-nan(ind("作为我的输出。

我在这里做错了什么?代码如下:

static double saveNormal;
static int NumNormals = 0;
static double PI = 3.1415927;
double fRand(double fMin, double fMax)
{
    double f = (double)rand() / RAND_MAX;
    return fMin + f * (fMax - fMin);
}
static double normal(double r, double mean, double sigma) {
    double returnNormal;
    if (NumNormals == 0) {
        //to get next double value
        double r1 = fRand(0, 20);
        double r2 = fRand(0, 20);
        returnNormal = sqrt(-2 * log(r1)) * cos(2 * PI*r2);
        saveNormal = sqrt(-2 * log(r1)) * sin(2 * PI*r2);
    }
    else {
        NumNormals = 0;
        returnNormal = saveNormal;
    }
    return returnNormal*sigma + mean;
}

因此,您正在使用Box-Muller方法对正态随机变量进行伪随机采样。要使此变换起作用,r1r2 必须在 [0,1] 中均匀分布独立变量。

相反,您的r1/r2是 [0,20] 支持的,导致在>1 时出现负sqrt参数,这将为您提供 nans。替换为

double r1 = fRand(0, 1);
double r2 = fRand(0, 1);

此外,您应该使用 C++11 <random>来更好地生成伪随机数;截至目前,由于rand()double的转换以及相邻调用之间可能存在虚假相关性,您的fRand质量很差。此外,您的函数缺乏一些基本的错误检查,并且严重依赖全局变量,并且本质上是线程不安全的。

仅供参考,这就是 C++11 版本

的样子
#include <random>
#include <iostream>
int main()
{
  auto engine = std::default_random_engine{ std::random_device{}() };
  auto variate = std::normal_distribution<>{ /*mean*/0., /*stddev*/ 1. };
  while(true) // a lot of normal samples ...
    std::cout << variate(engine) << std::endl;
}

r1 可以为零,使log(r1)未定义。


此外,不要使用rand(),除非你需要你的数字在匆忙的人看来是随机的。请改用<random>