我还没有在Python上找到这种算法的实现
类似这样的东西:
有两个输入参数:
我需要将它们大致均匀地排列在n球的表面上。
坐标轴位于n-1个球体的中心。 例如,在3D规则球体上,可以定位点like this
我认为,斐波那契算法在视觉上非常好。 我不知道n球是否存在类似的东西。 我有512D空间,我要在其中放置1000点甚至10,000点。
如何在python中执行此操作?
答案 0 :(得分:2)
有一种简单的Muller and Marsaglia方法可以在超球面上生成均匀的分布。
生成具有高斯分布的n个变量(此处列出l
)。它们形成一些向量。
找到该矢量的长度并对其分量进行归一化以提供单位长度结果
示例显示了在10d空间中在球体上生成一个点,并在视觉上检查了圆上的点包的均匀性(在2d中的球体,hystogram值应接近)
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]
答案 1 :(得分:1)
使用与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
而且,如果您需要在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