1. 如何生成高斯分布?
在java8中的实现采用了 Marsaglia polar method (Box–Muller的一种形式), 具体理论如下:
- 随机变量 服从 的均匀分布
- 计算
- 如果 , 接着计算, 否则转4
- , 独立,并且都符合高斯正态分布
代码片段:
// Random.java
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
public double nextDouble() {
return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false;
synchronized public double nextGaussian() {
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
之所以是这种方法大致的来源是:
单位圆 --> 均匀分布 --> 指数分布 --> 自由度为2的卡方分布 --> 反推出2个随机变量的表达式
2. Box–Muller 变换
Box–Muller transform 可以分为2种形式:
1. 基础形式
服从 的均匀分布,则:
, 独立并且服从标准正态分布
2. 极坐标形式
服从 的均匀分布,:
独立并且服从标准正态分布
这种方法避免了 的计算
, 当 去掉算得的 , 所以也是一种 rejection sampling
ref: