在C 中实现正态分布的统一比率

Implementing the ratio of uniforms for normal distribution in C++

本文关键字:比率 正态分布 实现      更新时间:2023-10-16

我知道这可以通过定义泪珠形状并接受该区域内(来自统一发生器)来完成。

我试图通过生成两个均匀的随机数x和y来在C 中进行此操作以定位点(x,y),然后检查该点是否落在该区域内。

我对代码本身没有问题,但是这里的逻辑有缺陷吗?我还没有找到合适的图形方法来检查这是否是真正的正态分布。

这是应该有效的代码:

typedef unsigned long long int Ullong;
typedef double Doub;
struct Normaldev : Ran {
    Doub mu,sig;
    Normaldev (Doub mmu, Doub ssig, Ullong i)
        : Ran (i), mu(mmu), sig(ssig){}
    Doub dev() {
      Doub u, v, x, y, q;
        do {
          u=Doub();
          v=1.7156*(Doub()-0.5);
          x=u-0.449871;
          y=abs(v)+0.386595;
          q=x*x+y*(0.19600*y-0.25472*x);
        } while(q>0.27597 && (q>0.27846 || v*v>-4*log(u)*u*u));
        return mu+sig*v/u;
     }
};

我尽可能多地改变了数值食谱书中的建议代码,但我对C 的知识进行了更改,但是到底应该运行什么?

我尽可能多地改变了数值食谱书中的建议代码,但我对C 的知识进行了更改,但是到底应该运行什么?

ran是andardev的父级。它未在您提供的代码中定义。基于代码,它似乎是一个非常通用的随机数类,在其构造函数中采用unsigned long long int种子。

可以查看" C中的数值配方"的第三版,第364-369页。您会发现Box-Muller返回两个正态分布的随机变量,即" U"answers" V"。因此,第一次调用函数时,您可以计算两个变量,但只返回" u"。该函数的第二个呼叫除了返回" V"。

double  u, v;
double  sigma = 1.0
double  mean  = 0.0;
int     flag  = 0;
double boxMuller()
{
    if (flag == 1) {
        flag  = 0;
        return v * sigma + mean;
    }
    double help;
    do {
        u = Doub() - 0.5;
        v = Doub() - 0.5;
        help      = u * u + v * v;
    } while (help >= 0.25);
    help = sqrt( log( help * 4.0 ) / help * -2.0 );
    u   *= help;
    v   *= help;
    flag = 1;
    return u * sigma + mean;
}

相比之下,均匀法的比率必须在每个呼叫上计算一个新的随机变量(不是每秒)。

所以我测量了时间,并且更喜欢使用上面的盒子磨损代码。