在多维环中均匀采样而不会被拒绝 [英] Sample uniformly in a multidimensional ring without rejection
问题描述
这个问题中的算法告诉我们如何有效地从多维球中抽样。有没有一种方法可以有效地从多维环中进行抽样,即有 r1
我希望那个缩放函数
r *(gammainc(s2 / 2,n / 2)。^(1 / n))./ sqrt(s2)
是可能的。 (Mediocrity免责声明:还没有计算出原始缩放函数的代数/几何)。
原始matlab代码copypasted:
函数X = randsphere(m,n,r)
%这个函数返回一个m乘n的数组X,其中
%中的每一行具有n个笛卡尔坐标
%均匀分布在具有
%radius r的n维超球体的
%内部的随机点,并且居中起源。函数
%'randn'最初用于生成m组具有独立多元
%正态分布的n
%随机变量,均值为0,方差为1.
%Then不完全伽马函数'gammainc',
%被用于径向映射这些点,以适应具有统一的%空间分布的有限半径r的
%超球面。
%Roger Stafford - 12/23/05
X = randn(m,n);
s2 = sum(X. ^ 2,2);
X = X. * repmat(r *(gammainc(s2 / 2,n / 2)。^(1 / n))./ sqrt(s2),1,n)。
来自 Daniel's answer :
import numpy as np
from scipy.special import gammainc
from matplotlib import pyplot as plt
def sample(center,radius,n_per_sphere):
r = radius
ndim = center.size
x = np.random.normal(大小=(n_per_sphere,ndim))
ssq = np.sum(x ** 2,axis = 1)
fr = r * gammainc(ndim / 2,ssq / 2)**(1 / ndim)/np.sqrt(ssq)
frtiled = np.tile(fr.reshape(n_per_sphere,1),(1,ndim))
p = center + np.multiply(x,frtiled)
返回p
fig1 = plt.figure(1)
ax1 = fig1.gca()
center = np.array([0,0])
$ radius = 1
p = sample(center,radius,10000)
ax1.scatter(p [:,0],p [:,1],s = 0.5)
ax1。 add_artist(plt.Circle(center,radius,fill = False,color ='0.5'))
ax1.set_xlim(-1.5,1.5)
ax1.set_ylim(-1.5,1.5)
ax1.set_aspect('equal')
最后一种方法这里 (1)适用于任何维度球体:
指向一个球体:
- 生成N个高斯随机变量 x1,x2..xN
- 得到x的范数[ i]
$ pre $ L $ S $ S $ = x1 / L
ux2 = x2 / L
...
然后向量ux [i]的分布在曲面上是均匀的S
- 在范围内生成均匀随机数
R_NPow = RandomUniform(R_Inner
N ,R_Outer
N )
并得到半径(如 $ b $ 然后计算结果点坐标: (1)Muller,ME关于在点上均匀生成点的方法的注意点。通讯。协会。 COMPUT。马赫。 2,19-20,1959年4月。 The algorithm in this question tells us how to efficiently sample from a multidimensional ball. Is there a way to similarly efficiently sample from a multidimensional ring , i.e. have I hope that a not too complex modification of that scaling function
Original matlab code copypasted: Equivalent python code with demo from Daniel's answer:
The last method here(1) is suitable for any dimensional sphere: To pick a random point on a sphere: Then the distribution of the vectors ux[i] is uniform over the surface SN-1 To provide uniform distribution in the ring: and get radius (like this 2D case) then calculate resulting point coordinates: (1) Muller, M. E. "A Note on a Method for Generating Points Uniformly on -Dimensional Spheres." Comm. Assoc. Comput. Mach. 2, 19-20, Apr. 1959. 这篇关于在多维环中均匀采样而不会被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! R = R_NPow
1 / N
res_x1 = R * ux1
res_x2 = R * ux2
...
res_xn = R * uxn
r1<r<r2
r*(gammainc(s2/2,n/2).^(1/n))./sqrt(s2)
is possible. (Mediocrity disclaimer: haven't even figured the algebra/geometry for the original scaling function yet).function X = randsphere(m,n,r)
% This function returns an m by n array, X, in which
% each of the m rows has the n Cartesian coordinates
% of a random point uniformly-distributed over the
% interior of an n-dimensional hypersphere with
% radius r and center at the origin. The function
% 'randn' is initially used to generate m sets of n
% random variables with independent multivariate
% normal distribution, with mean 0 and variance 1.
% Then the incomplete gamma function, 'gammainc',
% is used to map these points radially to fit in the
% hypersphere of finite radius r with a uniform % spatial distribution.
% Roger Stafford - 12/23/05
X = randn(m,n);
s2 = sum(X.^2,2);
X = X.*repmat(r*(gammainc(s2/2,n/2).^(1/n))./sqrt(s2),1,n);
import numpy as np
from scipy.special import gammainc
from matplotlib import pyplot as plt
def sample(center,radius,n_per_sphere):
r = radius
ndim = center.size
x = np.random.normal(size=(n_per_sphere, ndim))
ssq = np.sum(x**2,axis=1)
fr = r*gammainc(ndim/2,ssq/2)**(1/ndim)/np.sqrt(ssq)
frtiled = np.tile(fr.reshape(n_per_sphere,1),(1,ndim))
p = center + np.multiply(x,frtiled)
return p
fig1 = plt.figure(1)
ax1 = fig1.gca()
center = np.array([0,0])
radius = 1
p = sample(center,radius,10000)
ax1.scatter(p[:,0],p[:,1],s=0.5)
ax1.add_artist(plt.Circle(center,radius,fill=False,color='0.5'))
ax1.set_xlim(-1.5,1.5)
ax1.set_ylim(-1.5,1.5)
ax1.set_aspect('equal')
- generate N Gaussian random variables x1,x2..xN
- get norm of x[i] L = Sqrt(x1*x1 + x2*x2 + .. + xn*xn)
ux1 = x1 / L
ux2 = x2 / L
...
- generate uniform random in rangeR_NPow = RandomUniform(R_Inner
N, R_Outer
N)R = R_NPow
1/Nres_x1 = R * ux1
res_x2 = R * ux2
...
res_xn = R * uxn