[英]algorithm for generating uniformly distributed random points on the N-sphere
I have not found an implementation of such an algorithm on Python我还没有在 Python 上找到这种算法的实现
Something like this:像这样的东西:
There are two input arguments:有两个输入参数:
I need to approximately evenly arrange them on the surface of the n-sphere.我需要将它们大致均匀地排列在 n 球体的表面上。
Coordinate axes are located in the center of n-1 sphere.坐标轴位于 n-1 球体的中心。 For example in 3d on a regular sphere it's possible to position the points like this
例如在常规球体上的 3d 中,可以像这样定位点
In my opinion, the Fibonacci algorithm is very good visually.在我看来,斐波那契算法在视觉上非常好。 I don't know if there is something similar for n-sphere.
我不知道 n-sphere 是否有类似的东西。 I have 512D space and I'm going to place 1000 or even 10,000 points in it.
我有 512D 空间,我将在其中放置 1000 甚至 10,000 个点。
How to do this in python?如何在python中做到这一点?
There is simple Muller and Marsaglia approach to generate uniform distribution on the surface of the hypersphere.有简单的Muller 和 Marsaglia方法可以在超球面生成均匀分布。
Generate n variables with gaussian distribution (list l
here).生成具有高斯分布的 n 个变量(在此处列出
l
)。 They form some vector.它们形成一些向量。
Find length of that vector and normalize its components to provide unit length result查找该向量的长度并将其组件归一化以提供单位长度结果
Example shows generation of one point on sphere in 10d space and also visually checks uniformity for pack of points at the circle (sphere in 2d, hystogram values should be close)示例显示在 10d 空间中在球体上生成一个点,并在视觉上检查圆上点包的均匀性(2d 中的球体,柱状图值应该接近)
import random, math
#muller-marsaglia method
def spherepicking(n):
while True: #to get rid off [0,0,0,0] case
l = [random.gauss(0, 1) for i in range(n)]
sumsq = sum([x * x for x in l])
if sumsq > 0:
break
norm = 1.0 / math.sqrt(sumsq)
pt = [x * norm for x in l]
return pt
print(spherepicking(10))
cnt = [0] * 18
for i in range(10000):
pt = spherepicking(2)
an = math.atan2(pt[1], pt[0]) + math.pi / 2
cnt[math.floor(an * 9 / math.pi)] += 1
print(cnt)
-0.31811419572739935, 0.2845442135156396, -0.2849019746359018,
-0.1326796017012003, 0.7388447238721524, -0.287062305232526,
-0.08794741714783766, 0.131707880836534, 0.22059937624019868,
-0.13047162618106062]
[554, 560, 529, 589, 534, 538, 550, 558, 578, 556, 522, 553, 561, 513, 592, 583, 593, 537]
Using the same argument as MBo: (Muller 1959, Marsaglia 1972) -[https://mathworld.wolfram.com/HyperspherePointPicking.html] I present my implementation in python using numpy:使用与 MBo 相同的参数:(Muller 1959,Marsaglia 1972)-[https://mathworld.wolfram.com/HyperspherePointPicking.html] 我使用 numpy 在 python 中展示了我的实现:
import numpy as np
def getRandomSamplesOnNSphere(N , R , numberOfSamples):
# Return 'numberOfSamples' samples of vectors of dimension N
# with an uniform distribution on the (N-1)-Sphere surface of radius R.
# RATIONALE: https://mathworld.wolfram.com/HyperspherePointPicking.html
X = np.random.default_rng().normal(size=(numberOfSamples , N))
return R / np.sqrt(np.sum(X**2, 1, keepdims=True)) * X
And if you need to generate points inside an N-Sphere you can do this (reference: https://math.stackexchange.com/q/87238 )
如果您需要在N-Sphere内生成点,您可以执行此操作(参考: https : //math.stackexchange.com/q/87238 )
import numpy as np
def getRandomSamplesInNSphere(N , R , numberOfSamples):
# Return 'numberOfSamples' samples of vectors of dimension N
# with an uniform distribution inside the N-Sphere of radius R.
# RATIONALE: https://math.stackexchange.com/q/87238
randomnessGenerator = np.random.default_rng()
X = randomnessGenerator.normal(size=(numberOfSamples , N))
U = randomnessGenerator.random((numberOfSamples , 1))
return R * U**(1/N) / np.sqrt(np.sum(X**2, 1, keepdims=True)) * X
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.