因此,对于f(x) = (4-2x)/3
中的x
和其他地方的[0,1]
,我有分布f(x) = 0
。
我现在想根据此分布生成n = 100个随机数。我尝试遵循this的示例,这是我自己的代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
//pdf(x) = 1 if x>1
// = 0 if x<0
// = 1/3*(4-2x) otherwise
int N = 10;
int var1(int argc, char **argv) {
int p = 0, i;
for (i = 0; i < N; i++) {
p = (double)(rand() % 100)/100; // Generates 100 numbers in [0,1]
if (p > 1)
printf("%d ", 0);
else if (p < 0)
printf("%d ", 0);
else
printf("%f ", p * (4-2*0.1)/3);
}
printf("...");
return 0;
}
但是我的输出仅为零:
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 …
我有两个问题:
x
代替了0.1
?我只是做了同样的事情,但我不明白为什么。答案 0 :(得分:1)
首先,您没有返回自己认为的随机数范围:
p = (double)(rand() % 100)/100;
右手尺寸将为您提供范围为(0.00、0.01、0.02 ... 0.99)的数字。但是随后您将该值分配给p
类型的int
。小数部分被截断,因此分配的值将始终为0。
将p
的类型更改为double
以存储适当的值。另外,如果您想要更大范围的随机值,请改用此方法:
p = (double)rand() / RAND_MAX;
对此:
printf("%f ", p * (4-2*0.1)/3);
与链接的代码相比:
printf("%f ", p * 0.1 / 360);
他们的代码没有将0.1代替x
。 p
与x
相同,但是由于某些原因,他们添加了额外的0.1因子。
要执行f(x) = (4-2x)/3
,您需要这样做:
printf("%f ", (4-2*p)/3);
答案 1 :(得分:0)
问题中的函数,对于[0,1]中的 x ,f( x )=(4-2 x )/ 3 ]是概率密度函数,而不是累积分布函数。如果将分布绘制为在 x 轴和曲线之间具有单位面积的曲线,则概率密度函数是该曲线的斜率,而累积分布函数是曲线下的面积量直到某个 x 。
我们可以看到(4-2 x )/ 3不是累积分布函数,因为累积分布在分布末尾必须为1(通常为∞,但自函数在1之外为零,但(4-2 x )/ 3在1处为2/3。我们可以看到它是一个概率密度函数,因为其积分(如下所示)在末尾为1的分布。
link given in the question使用累积分布函数。实际上,它是用于在[0,360]上均匀分布的累积分布函数。因此,求解必要的方程式(见下文)仅是缩放的问题。这是微不足道的,不能用作生成任意分布样本的一般示例。
给出概率密度函数f( x ),相应的累积分布函数F( x )是f从-∞到 x 。我们可以使用累积分布函数将均匀分布转换为所需分布。
(4-2 x )/ 3的积分为(4 x - x 2 ) / 3(加上一个常数)。由于在 x = 0处为零,并且对于 x <0,f( x )为零,因此F( x >)在[0,1]中也是(4 x − x 2 )/ 3。
如果我们有一个均匀分布[0,1]中的样本 p ,则点 x 在或以下的位置x 等于或等于 p 的均匀分布量满足F( x )= p 。
因此(4 x − x 2 )/ 3 = p ,因此 x < / em> = 2 + sqrt(4−3 p )。
因此,给定使用p = (double) rand() / RAND_MAX
生成的 p ,我们可以找到所需分布的样本为2 + sqrt(4-3*p)
。