このquestionのアルゴリズムは、多次元ボールから効率的にサンプルする方法を教えてくれます。同様に、多次元リングから同様に効率的にサンプルする方法はありますか?r1<r<r2
拒絶のない多次元リング内のサンプル均一
あまりにも複雑ではないスケーリング関数の変更が望まれます。 r*(gammainc(s2/2,n/2).^(1/n))./sqrt(s2)
です。 (Mediocrity免責事項:元のスケーリング関数の代数/幾何学をまだ考えていない)。 copypasted
オリジナルMATLABコード:Daniel's answerからデモと
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);
等価Pythonコード:
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')
どのように多くの次元? –
@Yves任意の番号です。実際には、これは最初に2Dのおもちゃの問題で使用され、次に6Dの中間で、次に数百の次元の問題で使用されます。 –
@MBo完了。マークダウンのレンダリングに問題がありました。 –