在Python中生成Euclidean范数< = 1的随机向量?

时间:2016-06-01 20:04:26

标签: python numpy random

更具体地说,给定自然数d,如何在R ^ d中生成随机向量,使得每个向量x具有欧几里德范数<= 1?

通过numpy.random.rand(1,d)生成随机向量没有问题,但是这种具有范数&lt; = 1的随机向量的可能性对于即使不小的d也是可预测的。例如,即使对于d = 10,约0.2%的这种随机向量具有适当小的范数。所以这似乎是一个愚蠢的解决方案。

编辑:回复:沃尔特的评论,是的,我正在寻找R ^ d中单位球中向量的均匀分布。

3 个答案:

答案 0 :(得分:9)

基于Wolfram Mathworld关于hypersphere point picking的文章和Nate Eldredge's answer关于math.stackexchange.com上的类似问题,你可以通过生成d独立高斯的向量来生成这样的向量随机变量和随机数U在闭区间[0, 1]上均匀分布,然后将向量归一化为范数U^(1/d)

答案 1 :(得分:3)

根据user2357112的回答,你需要这样的东西:

import numpy as np
...
inv_d = 1.0 / d
for ...:
    gauss = np.random.normal(size=d)
    length = np.linalg.norm(gauss)
    if length == 0.0:
        x = gauss
    else:
        r = np.random.rand() ** inv_d
        x = np.multiply(gauss, r / length)
        # conceptually: / length followed by * r
    # do something with x

(这是我的第二个Python程序,所以不要向我开枪......)

技巧就是那个

  • 具有相同σ的d个独立高斯变量的组合是d维的高斯分布,显着地具有球对称性,
  • d维中的高斯分布可以通过除以范数投影到单位球上,
  • d维单位球体中的均匀分布具有累积径向分布r d (这是你need to invert

答案 2 :(得分:-1)

这是我正在使用的Python / Numpy代码。由于它不使用循环,因此速度更快:

n_vectors=1000
d=2

rnd_vec=np.random.uniform(-1, 1, size=(n_vectors, d))                # the initial random vectors
unif=np.random.uniform(size=n_vectors)                               # a second array random numbers
scale_f=np.expand_dims(np.linalg.norm(rnd_vec, axis=1)/unif, axis=1) # the scaling factors
rnd_vec=rnd_vec/scale_f                                              # the random vectors in R^d

需要第二个随机数组( unif )作为第二个缩放因子,否则所有向量都将具有等于1的欧几里德范数。