如何在编程语言中生成一些长度固定为 r 的同分布伪随机向量?
How to generate some identically distributed pseudo-random vectors with a fixed length r in a programming language?
例如,对于维度d=2
,这意味着我们可以生成一个随机角度0<=a<2*pi
,然后我们就可以使用
(x_1,x_2)=(r*cos(a),r*sin(a))
作为随机向量。
然而,对于维度 d>=3
,我们不能只生成一个角度并用它来表示向量。那么我们如何生成这样一个向量(x_1,...,x_d)
,它在x_1^2+x_2^2+...+x_d^2=r^2
上同分布?
我刚刚想出了一个新想法,我们可以生成一个向量 (x_1,...,x_d)
,使得所有 i
的 -r<=x_i<r
,如果 x_1^2+x_2^2+...+x_d^2<=r^2
和如果 x_1^2+x_2^2+...+x_d^2>r^2
,请放弃它。
但是有个缺点就是如果d
很大的话,x_1^2+x_2^2+...+x_d^2<=r^2
变的概率会很小。有没有更好的解决方案?
生成独立且服从标准正态分布的随机变量(X_1, X_2, ... X_d),然后除以sqrt(X_1^2+...+X_d^2)/r.
独立正态分布的联合分布是旋转对称的不仅是正确的,它还表征了正态分布。
您可以使用 Box-Muller transform.
从均匀随机变量中高效地生成具有标准正态分布的独立变量对
我看到了两种解决方法。
最直接的方法是,在伪代码中:
1. build n-dimensional vector x[0] through x[n-1] with random components
2. find radius
3. go to step 1 if radius > r; otherwise, normalize to radius r
这是不确定的,因为无法知道在找到可接受的球体之前需要循环多少次。此外,发现坏点的概率随着维数的增加而上升。
要理解原因(感谢评论者!),请想象一个 1x1 的正方形。在里面加一个r=1的圆圈。用随机点填充正方形。圆心和圆之间的所有点投影到圆上时都是均匀分布的。圆圈和正方形边界之间的所有点都不是——因为有太多的点,比如 45º;并且 none 在,比方说,90º。
非直截了当的版本是二维方法的概括:
1. assume that we are on an n-sphere; generate angles phi[0], ...phi[n-2]
for a polar-coordinates point
2. convert to cartesian coordinates x[0] through x[n-1]
根据维基百科n-sphere页面,公式为
x[0] = r*cos(phi[0]);
x[1] = r*sin(phi[0])*cos(phi[1]);
x[2] = r*sin(phi[0])*sin(phi[1]);
...
x[n-2] = r*sin(phi[0])*sin(phi[1])* /*...*/ sin(phi[n-3])*sin(phi[n-2])
x[n-1] = r*sin(phi[0])*cos(phi[1])* /*...*/ sin(phi[n-3])*cos(phi[n-2])
实际算法可以更有效地实现(sin(phi[0]
)正在计算很多,例如)
为了避免不确定性,我推荐第二种方法。
编辑
上面没有列出的推荐方法在 Douglas 的回答和许多参考站点中:
例如,对于维度d=2
,这意味着我们可以生成一个随机角度0<=a<2*pi
,然后我们就可以使用
(x_1,x_2)=(r*cos(a),r*sin(a))
作为随机向量。
然而,对于维度 d>=3
,我们不能只生成一个角度并用它来表示向量。那么我们如何生成这样一个向量(x_1,...,x_d)
,它在x_1^2+x_2^2+...+x_d^2=r^2
上同分布?
我刚刚想出了一个新想法,我们可以生成一个向量 (x_1,...,x_d)
,使得所有 i
的 -r<=x_i<r
,如果 x_1^2+x_2^2+...+x_d^2<=r^2
和如果 x_1^2+x_2^2+...+x_d^2>r^2
,请放弃它。
但是有个缺点就是如果d
很大的话,x_1^2+x_2^2+...+x_d^2<=r^2
变的概率会很小。有没有更好的解决方案?
生成独立且服从标准正态分布的随机变量(X_1, X_2, ... X_d),然后除以sqrt(X_1^2+...+X_d^2)/r.
独立正态分布的联合分布是旋转对称的不仅是正确的,它还表征了正态分布。
您可以使用 Box-Muller transform.
从均匀随机变量中高效地生成具有标准正态分布的独立变量对我看到了两种解决方法。
最直接的方法是,在伪代码中:
1. build n-dimensional vector x[0] through x[n-1] with random components
2. find radius
3. go to step 1 if radius > r; otherwise, normalize to radius r
这是不确定的,因为无法知道在找到可接受的球体之前需要循环多少次。此外,发现坏点的概率随着维数的增加而上升。
要理解原因(感谢评论者!),请想象一个 1x1 的正方形。在里面加一个r=1的圆圈。用随机点填充正方形。圆心和圆之间的所有点投影到圆上时都是均匀分布的。圆圈和正方形边界之间的所有点都不是——因为有太多的点,比如 45º;并且 none 在,比方说,90º。
非直截了当的版本是二维方法的概括:
1. assume that we are on an n-sphere; generate angles phi[0], ...phi[n-2]
for a polar-coordinates point
2. convert to cartesian coordinates x[0] through x[n-1]
根据维基百科n-sphere页面,公式为
x[0] = r*cos(phi[0]);
x[1] = r*sin(phi[0])*cos(phi[1]);
x[2] = r*sin(phi[0])*sin(phi[1]);
...
x[n-2] = r*sin(phi[0])*sin(phi[1])* /*...*/ sin(phi[n-3])*sin(phi[n-2])
x[n-1] = r*sin(phi[0])*cos(phi[1])* /*...*/ sin(phi[n-3])*cos(phi[n-2])
实际算法可以更有效地实现(sin(phi[0]
)正在计算很多,例如)
为了避免不确定性,我推荐第二种方法。
编辑
上面没有列出的推荐方法在 Douglas 的回答和许多参考站点中: