[英]algorithm for generating uniformly distributed random points on the N-sphere
我還沒有在 Python 上找到這種算法的實現
像這樣的東西:
有兩個輸入參數:
我需要將它們大致均勻地排列在 n 球體的表面上。
坐標軸位於 n-1 球體的中心。 例如在常規球體上的 3d 中,可以像這樣定位點
在我看來,斐波那契算法在視覺上非常好。 我不知道 n-sphere 是否有類似的東西。 我有 512D 空間,我將在其中放置 1000 甚至 10,000 個點。
如何在python中做到這一點?
有簡單的Muller 和 Marsaglia方法可以在超球面生成均勻分布。
生成具有高斯分布的 n 個變量(在此處列出l
)。 它們形成一些向量。
查找該向量的長度並將其組件歸一化以提供單位長度結果
示例顯示在 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]
使用與 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.