从单位圆均匀采样

我们要解决的问题是:如何使用一个在 [0,1] 上服从均匀分布的随机数生成器 random(),来实现从单位圆内均匀采样得到二维坐标 (x, y)? 要求:不能使用拒绝采样。


:brain: 思路分析:

我们希望从单位圆内部(即满足 x^2 + y^2 \leq 1 的区域)中均匀地采样点。由于单位圆是一个二维区域,我们可以考虑将其转换为极坐标形式:

x = r \cos\theta,\quad y = r \sin\theta

其中:

  • r \in [0,1] 是到原点的距离(半径)
  • \theta \in [0, 2\pi] 是角度

:white_check_mark: 第一步:找出联合分布函数

(x, y) 在单位圆上服从均匀分布,则其联合概率密度函数为常数(因为是均匀分布),且在整个单位圆面积上的积分等于 1。

所以:

f_{X,Y}(x,y) = \frac{1}{\pi},\quad \text{当 } x^2 + y^2 \leq 1

将该分布转换为极坐标下的联合分布:

f_{R,\Theta}(r,\theta) = f_{X,Y}(r\cos\theta, r\sin\theta) \cdot |J|

其中 J 是雅可比行列式,在极坐标变换下有:

|J| = r

所以:

f_{R,\Theta}(r,\theta) = \frac{1}{\pi} \cdot r = \frac{r}{\pi},\quad 0 \leq r \leq 1,\; 0 \leq \theta < 2\pi

:white_check_mark: 第二步:求边缘分布

f_R(r)

f_R(r) = \int_0^{2\pi} f_{R,\Theta}(r,\theta) d\theta = \int_0^{2\pi} \frac{r}{\pi} d\theta = \frac{r}{\pi} \cdot 2\pi = 2r

f_\Theta(\theta)

f_\Theta(\theta) = \int_0^1 f_{R,\Theta}(r,\theta) dr = \int_0^1 \frac{r}{\pi} dr = \frac{1}{\pi} \cdot \frac{1}{2} = \frac{1}{2\pi}

这说明:

  • R \Theta 相互独立的随机变量
  • \Theta \sim U(0, 2\pi)
  • R 的概率密度函数为 f_R(r) = 2r r \in [0,1]

:white_check_mark: 第三步:构造反函数进行逆变换采样

我们现在要从这两个分布中采样:

对于 \Theta

因为它是均匀分布在 [0, 2\pi] 上的:

\theta = 2\pi \cdot u_1,\quad u_1 \sim U(0,1)

对于 R

它的概率密度函数是 f_R(r) = 2r ,求其累积分布函数(CDF):

F_R(r) = \int_0^r 2t dt = r^2

令:

u_2 = F_R(r) = r^2 \Rightarrow r = \sqrt{u_2},\quad u_2 \sim U(0,1)

:white_check_mark: 第四步:最终算法步骤

给定一个可以在 [0,1] 上采样的函数 random(),我们可以通过以下步骤从单位圆中均匀采样:

:abacus: 算法步骤如下:

  1. random() 生成两个独立的 [0,1] 均匀分布随机数 u_1, u_2
  2. 计算:
    \theta = 2\pi u_1
    r = \sqrt{u_2}
  3. 得到笛卡尔坐标:
    x = r \cos\theta,\quad y = r \sin\theta

这样得到的点 (x, y) 就是从单位圆内均匀采样得到的。


:white_check_mark: 示例代码(Python)

import math
import random

def sample_unit_circle():
    u1 = random.random()
    u2 = random.random()
    theta = 2 * math.pi * u1
    r = math.sqrt(u2)
    x = r * math.cos(theta)
    y = r * math.sin(theta)
    return x, y

附:

:bullseye: 一、采样问题

假设我们有一个连续型随机变量 X ,它的累积分布函数(CDF)为:

F_X(x) = P(X \leq x)

并且该函数是严格单调递增的(即一一对应)。

我们的目标是:
:backhand_index_pointing_right: 如何使用 [0,1] 上的均匀分布随机数 U(0,1) 来生成服从 F_X(x) 的随机数?


:brain: 二、逆变换采样原理(Inversion Method)

:white_check_mark: 定理陈述:

U \sim U(0,1) 是一个在 [0,1] 上的均匀分布随机变量, F^{-1}(u) 是某个分布函数 F(x) 的反函数,则:

X = F^{-1}(U) \Rightarrow X \sim F(x)

换句话说:

如果你从 [0,1] 均匀分布中取一个随机数 U ,然后计算 F^{-1}(U) ,那么这个值就服从以 F(x) 为 CDF 的分布。


:triangular_ruler: 三、证明过程

  1. U \sim U(0,1) ,且 F(x) 是连续且严格单调递增的。
  2. 定义 X = F^{-1}(U)
  3. 我们要计算 X 的分布函数 P(X \leq x)
P(X \leq x) = P(F^{-1}(U) \leq x) = P(U \leq F(x)) = F(x)

:white_check_mark: 得证!


:abacus: 四、算法

给定一个目标分布的 CDF F(x) ,若能求出其反函数 F^{-1}(u) ,则可以按以下步骤生成服从该分布的样本:

步骤:

  1. 从 [0,1] 均匀分布中生成一个随机数 u \sim U(0,1)
  2. 计算 x = F^{-1}(u)
  3. 返回 x ,它服从分布 F(x)

2 Likes

QA

  • Q: 为什么要从 x, y 变换为极坐标

  • A: 分布关于 x,y 不独立,但关于 r, \theta 是独立的

  • Q: 如果不开根号会怎么样?即按照 r \sim U(0,1), \theta \sim U(0,2 \pi) 的方式计算出坐标

  • A: 会使得采样出的点更集中在原点附近,参考 文章 的实验结果:


错误的采样

理论分析:

f_{X,Y}(x,y) = \frac{1}{2\pi \sqrt{x^2 + y^2}},\quad x^2 + y^2 \leq 1

这说明:

  • 分布不是常数,而是随 r = \sqrt{x^2 + y^2} 变化
  • 越靠近原点(即 r \rightarrow 0 ),密度越大
  • 所以:点集中在圆心附近


正确的采样

练习题:从单位球均匀采样。请给出理论分析、代码、实验截图。