生成正态分布直方图的数字?

时间:2013-04-14 20:56:54

标签: c

我正致力于生成数字,通常分布为直方图。这是我的两个功能。首先用于生成,第二用于将它们转换为正态分布。出于某种原因,当我进行测试printf时,它只返回最小负数。有人对此有所了解吗?谢谢!

double s, u[1000], v[1000], z;
int transformed[1000];

void generateec(){
srand( time(NULL) );
for(int i = 0; i < 1000; ++i)
 {
 u[i] = rand() % 7-3;
 v[i] = rand() % 7-3;
 }

}

void transform(){
generateec();




for(int i = 0; i < 1000; ++i)
{
    s = (u[i]*u[i])+(v[i]*v[i]);
    transformed[i] = u[i]*(sqrt( (-2.0 * log(s) ) / s)); 

}

printf("%d %d %d \n", transformed[0], transformed[500], transformed[600]);

 }

谢谢你们!

2 个答案:

答案 0 :(得分:2)

在:

for(int i = 0; i < 1000; ++i)
{
    u[i] = rand() % 1;
    v[i] = rand() % 1;
 }

表达式:

rand() % 1

始终会产生0

修改

由于程序在此期间被编辑,现在问题是程序中sqrt函数的参数可能是负值。如果sqrt参数为负,则会发生域错误,sqrt将返回实现定义的值。

答案 1 :(得分:0)

好的,所以看来你正试图实现Box-Muller的转换。但是你的代码存在一些问题。

首先,你需要一个连续的均匀分布,而不是一个离散的分布,所以

u[i] = (double)rand()/(double)(RAND_MAX);
v[i] = (double)rand()/(double)(RAND_MAX);

然后,转换部分非常关闭,请参阅Box Muller Transform,它必须沿着

transformed[i] = sqrt(-2.0 * log(u[i])) * cos(2 * pi * v[i]) ; 

其中pi = atan(1)*4

请注意,生成了正常分布的2 * 1000个数字,因此您可以将transformed定义为double transformed[2000];并执行此操作

transformed[2*i] = sqrt(-2.0 * log(u[i])) * cos(2 * pi * v[i]); 
transformed[2*i+1] = sqrt(-2.0 * log(u[i])) * sin(2 * pi * v[i]); 

请注意,仍然有一个非零概率仍可获得u[i] * v[i] == 0。我把这个留给你解决。