如何生成服从正态分布的随机数

经典回顾

  • 分布函数(Cumulative Distribution Function, CDF)

    XX为随机变量,对于任意实数xx,令

    F(x)=P{Xx},xRF(x)=P\{X\leq x\}, x\in \R

    F(x)F(x)为随机变量XX的分布函数。分布函数满足如下性质:

    • 0F(x)10\leq F(x) \leq 1
    • F(x)F(x)是关于xx的单调不减函数
    • limxF(x)=0,limx+F(x)=1\lim \limits_{x\to -\infty} F(x) = 0, \lim \limits_{x\to +\infty} F(x) = 1
    • F(x)F(x)是右连续的
    • P{aXb}=F(b)F(a),a<bP\{a\leq X \leq b\} = F(b) - F(a), a\lt b
  • 连续型随机变量的概率密度函数(Probability Density Function, PDF)

    对于随机变量XX的分布函数F(x)F(x),如果存在非负函数f(x)f(x),使得对任意xx都有

    F(x)=xf(t)dtF(x)=\int_{-\infty}^x f(t)dt

    则称随机变量XX是连续型随机变量,其中f(x)f(x)叫做XX的概率密度函数,简称为概率密度,记为Xf(x)X\sim f(x).概率密度函数具有以下性质:

    • f(x)0f(x)\geq 0
    • +f(t)dt=1\int_{-\infty}^{+\infty} f(t)dt=1
    • P{a<Xb}=F(b)F(a)=abf(x)dx,a<bP\{a\lt X \leq b\} = F(b) - F(a) = \int_a^b f(x)dx, a\lt b
    • F(x)F(x)xx处连续,则F(x)=f(x)F'(x)=f(x)
  • 正态分布(Normal Distribution)

    若随机变量XX具有概率密度函数

    f(x)=12πσe(xμ)22σ2,<x<+f(x)=\dfrac{1}{\sqrt{2\pi \sigma}}\mathrm{e}^{-\frac{(x-\mu)^2}{2\sigma^2}}, -\infty \lt x \lt +\infty

    其中μ,σ(σ>0)\mu,\sigma(\sigma \gt 0)为常数,则称XX服从参数为μ,σ\mu, \sigma的正态分布,记作XN(μ,σ2)X\sim N(\mu, \sigma^2).XX的分布函数为

    F(x)=12πσxe(tμ)22σ2dt,<x<+F(x)=\dfrac{1}{\sqrt{2\pi \sigma}}\int_{-\infty}^{x}\mathrm{e}^{-\frac{(t-\mu)^2}{2\sigma^2}}dt, -\infty \lt x \lt +\infty

    为什么不写成初等函数的形式呢?是不喜欢吗?

Box-Muller方法

  • 万流归一定理:设XX为连续型随机变量,其分布函数为FX(x)F_X(x),则随机变量Y=FX(X)Y=F_X(X)服从(0,1)上的均匀分布。

    证明:根据分布函数的定义可知

    FY(y)=P{Yy}=P{FX(X)y}F_Y(y)=P\{Y\le y\}=P\{F_X(X)\le y\}

    由于累积分布函数在其定义域上是单调不减函数,有

    P{FX(X)y}=P{XFX1(y)}P\{F_X(X)\le y\} = P\{X \le F^{-1}_X(y)\}

    因此,YY的累计分布函数为

    FY(y)=FX(FX1(y))=yF_Y(y)=F_X(F^{-1}_X(y))=y

    概率密度函数为

    fY(y)=1f_Y(y)=1

  • 逆变换定理:设XX(a,b)(a,b)上的连续型随机变量,且XX的分布函数为F(x)F(x),随机变量UU(0,1)U\sim U(0,1),则随机变量Y=FX1(U)Y=F^{-1}_X(U)服从与XX相同的分布.

    证明:YY的累积分布函数为

    CDF(FX1(U))=P{FX1(U)u}\mathrm{CDF}(F^{-1}_X(U))=P\{F^{-1}_X(U)\leq u\}

    由于累积分布函数在其定义域上是单调不减函数,且UU服从(0,1)(0,1)上的均匀分布,有

    P{FX1(U)u}=P{UFX(u)}=FX(u)P\{F^{-1}_X(U)\leq u\} = P\{U\leq F_X(u)\}=F_X(u)

  • 根据逆变换定理,我们可以从均匀分布中采样,然后通过反函数进行映射,得到服从目标分布的随机变量。但是,正态分布的累计分布函数无法表达为初等函数的形式,直接得到其反函数较为困难。Box-Muller变换是设置两个相互独立的正态分布的随机变量,得到二元分布函数,再进行极坐标变换,得到初等函数形式的分布函数。

    假定X,YX,Y是两个相互独立的随机变量,且均服从标准正态分布,则其概率密度函数为

    fX(x)=12πex22,fY(y)=12πey22f_X(x)=\dfrac{1}{\sqrt{2\pi}}\mathrm{e}^{-\frac{x^2}{2}}, f_Y(y)=\dfrac{1}{\sqrt{2\pi}}\mathrm{e}^{-\frac{y^2}{2}}

    由于二者相互独立,因此X,YX,Y的联合概率密度函数为

    f(x,y)=12πex2+y22f(x,y)=\dfrac{1}{2\pi}\mathrm{e}^{-\frac{x^2+y^2}{2}}

    根据极坐标变换公式X=RcosΘ,Y=RsinΘX=R\cos \Theta, Y=R\sin \Theta,有

    f(r,θ)=r2πer22f(r,\theta)=\dfrac{r}{2\pi}\mathrm{e}^{-\frac{r^2}{2}}

    因此,R,ΘR,\Theta的分布函数为

    FR(r)=P{Rr}=0r02πR2πeR22dΘdR=1er22F_R(r)=P\{R\leq r\}=\int_0^r \int_0^{2\pi}\dfrac{R}{2\pi}\mathrm{e}^{-\frac{R^2}{2}}d\Theta dR=1-\mathrm{e}^{-\frac{r^2}{2}}

    FΘ(θ)=P{Θθ}=0θ0+R2πeR22dΘdR=θ2πF_\Theta(\theta)=P\{\Theta \leq \theta \}=\int_0^\theta \int _0^{+\infty} \dfrac{R}{2\pi}\mathrm{e}^{-\frac{R^2}{2}}d\Theta dR=\dfrac{\theta}{2\pi}

    U1,U2U_1,U_2相互独立,且均服从(0,1)(0,1)上的均匀分布,经过反函数FR1F_R^{-1}映射为

    FR1(U1)=2ln(1U1)F_R^{-1}(U_1)=\sqrt{-2\ln(1-U_1)}

    由于U1U(0,1)U_1 \sim U(0,1),上式等价于

    FR1(U1)=2lnU1F_R^{-1}(U_1)=\sqrt{-2\ln U_1}

    反函数FΘ1F_{\Theta}^{-1}映射为

    FΘ1(U2)=2πU2F_{\Theta}^{-1}(U_2)=2\pi U_2

    因此,最终采样得到的X,YX,Y

    X=2lnU1cos(2πU2)X=\sqrt{-2\ln U_1} \cos(2\pi U_2)

    Y=2lnU1sin(2πU2)Y=\sqrt{-2\ln U_1} \sin(2\pi U_2)

代码实现

实现起来并不复杂,以下用JavaScript示例。

js
function randn(mean, std, count) {
  const arr = []
  for (let i = 0; i < count; i++) {
    const u1 = Math.random()
    const u2 = Math.random()
    const standard = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2)
    arr.push(standard * std + mean);
  }
  return arr
}
软件工程通关指南
Java基础知识复习笔记
Valaxy v0.28.8 驱动|主题-Yunv0.28.8