-1

我正在为直方图生成通常分布的数字。这是我的两个功能。首先用于生成,其次用于将它们转换为正态分布。出于某种原因,当我进行测试 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]);

 }

多谢你们!

4

2 回答 2

2

在:

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

表达方式:

rand() % 1

总是产生0

编辑

由于同时编辑了程序,现在的问题是sqrt程序中函数的参数可以是负值。如果sqrt参数为负,则发生域错误sqrt并将返回实现定义的值。

于 2013-04-14T21:00:00.483 回答
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生成了正态分布的数字,因此您可以定义transformeddouble 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。我把这留给你解决。

于 2013-04-14T21:26:49.477 回答