我正致力于生成数字,通常分布为直方图。这是我的两个功能。首先用于生成,第二用于将它们转换为正态分布。出于某种原因,当我进行测试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]);
}
谢谢你们!
答案 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
。我把这个留给你解决。