简体   繁体   中英

Generating random vectors of Euclidean norm <= 1 in Python?

More specifically, given a natural number d, how can I generate random vectors in R^d such that each vector x has Euclidean norm <= 1?

Generating random vectors via numpy.random.rand(1,d) is no problem, but the likelihood of such a random vector having norm <= 1 is predictably bad for even not-small d. For example, even for d = 10 about 0.2% percent of such random vectors have appropriately small norm. So that seems like a silly solution.

EDIT: Re: Walter's comment, yes, I'm looking for a uniform distribution over vectors in the unit ball in R^d.

根据Wolfram Mathworld关于超球点选择的文章和Nate Eldredge对math.stackexchange.com上类似问题的回答 ,您可以通过生成d独立高斯随机变量和均匀分布在随机数上的随机数U来生成这样的向量。闭区间[0, 1] ,然后将向量归一化为范数U^(1/d)

Based on the answer by user2357112, you need something like this:

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

(this is my second Python program, so don't shoot at me...)

The tricks are that

  • the combination of d independent gaussian variables with same σ is a gaussian distribution in d dimensions, which, remarkably, has spherical symmetry,
  • the gaussian distribution in d dimensions can be projected onto the unit sphere by dividing by the norm, and
  • the uniform distribution in a d-dimensional unit sphere has cumulative radial distribution r d (which is what you need to invert )

this is the Python / Numpy code I am using. Since it does not use loops, is much faster:

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

The second array of random numbers ( unif ) is needed as second scaling factor because otherwise all the vectors will have euclidean norm equal to one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM