生成遵循特定分布的随机双打

时间:2018-10-11 18:14:33

标签: c

因此,对于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 …

我有两个问题:

  1. 我想念什么?
  2. 在我提供的链接中,为什么他用x代替了0.1?我只是做了同样的事情,但我不明白为什么。

2 个答案:

答案 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代替xpx相同,但是由于某些原因,他们添加了额外的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)