8

我需要在 4 维球体上均匀分布点。我知道这不像选择 3 个角度和使用极坐标那么简单。

在 3 个维度中我使用

from random import random

u=random()
costheta = 2*u -1 #for distribution between -1 and 1
theta = acos(costheta)
phi = 2*pi*random

x=costheta
y=sin(theta)*cos(phi)
x=sin(theta)*sin(phi)

这给出了 x、y 和 z 的均匀分布。

如何获得 4 个维度的类似分布?

4

4 回答 4

9

然而,一种标准的方法,也许不是最快的,是使用穆勒的方法在 N 球上生成均匀分布的点:

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d

N = 600
dim = 3

norm = np.random.normal
normal_deviates = norm(size=(dim, N))

radius = np.sqrt((normal_deviates**2).sum(axis=0))
points = normal_deviates/radius

fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
ax.scatter(*points)
ax.set_aspect('equal')
plt.show()

在此处输入图像描述

只需更改dim = 3dim = 4在 4 球体上生成点。

于 2013-04-08T18:30:57.237 回答
2

在 4D 空间中取一个坐标正态分布的点,计算其单位向量。这将在单位 4 球体上。

from random import random
import math
x=random.normalvariate(0,1)
y=random.normalvariate(0,1)
z=random.normalvariate(0,1)
w=random.normalvariate(0,1)
r=math.sqrt(x*x + y*y + z*z + w*w)
x/=r
y/=r
z/=r
w/=r
print (x,y,z,w)
于 2013-04-08T14:31:56.913 回答
1

我喜欢@unutbu 的回答,如果高斯采样真的创建了一个均匀间隔的球形分布(不像从立方体采样),但是为了避免在高斯分布上采样并且必须证明这一点,有一个简单的解决方案:在均匀分布上采样分布在球体上(不是在立方体上)。

  1. 在均匀分布上生成点。
  2. 计算每个点的平方半径(避免平方根)。
  3. 丢弃点
    • 丢弃平方半径大于 1 的点(因此,非平方半径大于 1)。
    • 丢弃太接近零半径的点,以避免在下一步中与除法相关的数值不稳定性。
  4. 对于保留的每个采样点,将采样点除以范数,以便将其重新归一化为单位半径。
  5. 由于丢弃的样品,清洗并重复更多点。

这显然适用于 n 维空间,因为半径在更高维中始终是 L2 范数。

它速度很快,可以避免在高斯分布上进行平方根和采样,但它不是矢量化算法。

于 2017-11-15T22:39:08.227 回答
1

I found a good solution for sampling from N-dim sphere. The main idea is:

If Y is drawn from the uncorrelated multivariate normal distribution, then S = Y / ||Y|| has the uniform distribution on the unit d-sphere. Multiplying S by U1/d, where U has the uniform distribution on the unit interval (0,1), creates the uniform distribution in the unit d-dimensional ball.

Here is the python code to do this:

Y = np.random.multivariate_normal(mean=[0], cov=np.eye(1,1), size=(n_dims, n_samples))
Y = np.squeeze(Y, -1)
Y /= np.sqrt(np.sum(Y * sample_isotropic, axis=0))
U = np.random.uniform(low=0, high=1, size=(n_samples)) ** (1/n_dims)
Y *= distr * radius # in my case radius is one

This is what I get for the sphere:

sphere

于 2018-09-15T06:57:50.513 回答