高斯随机发生器

信息处理 matlab 高斯 随机的
2022-02-22 20:41:10

我有一个非常直截了当的问题。我的目标是生成一组具有正态分布 ( mu = 0, sigma = 1) 的随机数。

现在,处理上述高斯钟的最佳方法是生成大量样本。

不幸的是,就我而言,我只能生成保留的样本子集:通常围绕2048样本,这会导致拟合不佳。

我实际上想知道是否有任何方法可以提高适应度,首先生成更大的样本集或相同大小的更多子集(作为 2048 样本的 10 倍),然后选择那些最接近所需平均值标准的 2048偏差(当然还有高斯)。

您会提出什么建议或如何进行?

3个回答

详细说明 Dilip 的答案(这是完全正确的,尽管在实践中Ziggurat 方法的计算效率比 Box-Mueller 高得多):

你的推理中缺少的一个关键因素是你是否希望你的样本是独立的。从您的问题中不清楚,但这是最常见的情况......

如果您希望您的样本是独立的,那么您将不得不接受它们的经验均值和方差不会完全为 0 和 1 - 众所周知,样本越大,经验值越接近 0、1 - 这绝对没问题 - 这是正态分布的“特征”而不是“错误”。尝试选择看起来更“随机”或“表现良好”的样本是个坏主意;因为这个选择过程使它们变得不那么随机了!例如,如果你想出一个过程总是产生 2048 个样本块,其中μ=0σ=1,这意味着在您的生成过程中只有 2046 个可能的自由度,因此您的样本不是独立的(给定 2046 个第一个样本,您可以使用 equation...所以这最后两个值不是随机的!)。μ=0σ=1

Dilip 和 pichenettes 已经指出了两种生成高斯随机变量的方法(Box-Muller 变换Ziggurat 算法)。为了完整起见,我将指出另一个:逆变换采样我最近需要创建一个最大吞吐量的软件高斯随机数生成器,在评估了我能找到的所有方法之后,我选择了这个,因为它被证明是目标系统上最快的。

逆变换采样的想法是,您从一个基本随机生成器开始,该生成器在某个区间内产生均匀的值,通常是(或者区间在任一端是开还是闭的一些变化)。然后,您将这些统一值应用于选择的函数,以使结果输出具有所需的分布。这种技术的设置如下:[0,1)

  • 选择要从中生成随机数的分布。确定其累积分布函数 (cdf) Fx(x). 对于高斯分布,此函数为:

    Fx(x)=12(1+erf(xμ2σ2))
    在哪里erf(z)误差函数对于标准高斯分布,μ=0σ=1.

  • 反转分布的 CDF 以产生其逆 CDFFx1(x),有时称为分位数函数这通常很难或不可能以紧凑的分析形式完成,因此您可能需要依赖数值近似。对于标准高斯分布,这是概率函数,可以从上面的 cdf 表达式中获得:

    Fx1(x)=2erf1(2x1)

    如果您的计算环境具有逆误差函数的实现,那么这应该很容易评估。否则,您将需要依赖函数的一些数值近似。

有了上述信息,您现在可以从所需的分布中生成值。简单的程序如下:

  1. 生成统一值u在区间[0,1).

  2. 计算y=Fx1(u).

  3. 输出y.

假设您有一个良好的基础统一生成器(以及逆 CDF 函数的良好实现),则生成的样本为y应该非常接近于期望的分布。这种技术有几个好处:

  • 它很笼统;虽然我在上面谈到了高斯随机数生成,但您可以通过更改用于逆 CDF 的函数来成功地将其用于许多分布。

  • 如果你有一个逆 CDF 函数的简单实现,它可以非常快(尽管统一生成器的速度很重要)。通过使用不使用任何逻辑检查或分支的逆 CDF 近似,我能够从这种方法中挤出比 Ziggurat 算法更快的速度。

Box Müller 大多是好的,但不一定优于逆 CDF,因为它受到 Neave 效应的影响,请参阅 HR Neave,On using the Box-Muller transformation with multiplicative congruential pseudorandom number generators Applied Statistics, 22, 92-97, 1973,或手冢https://www.researchgate.net/publication/3528180_NEAVE_EFFECT_ALSO_OCCURS_WITH_TAUSWORTHE_SEQUENCES

这个堆栈溢出帖子是相关的https://stackoverflow.com/questions/2325472/generate-random-numbers-following-a-normal-distribution-in-cc