If you just want to do this for the unit circle, you can use numpy.random.uniform
to choose the angle \$\theta\$ defining the unit vector.
If you want to deal with the more general case of the \$n\$-sphere, there is a method mentioned on Wikipedia.
To generate uniformly distributed random points on the \$(n − 1)\$-sphere (i.e., the surface of the \$n\$-ball), Marsaglia (1972) gives the following algorithm.
Generate an \$n\$-dimensional vector of normal deviates (it suffices to use \$N(0, 1)\$, although in fact the choice of the variance is arbitrary), \$\mathbf{x}=(x_1,x_2,\ldots,x_n)\$.
Now calculate the "radius" of this point, \$r=\sqrt{x_1^2+x_2^2+\cdots+x_n^2}\$.
The vector \$\frac{1}{r} \mathbf{x}\$ is uniformly distributed over the surface of the unit n-ball.
My attempt at translating that into Python would be
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
r = np.sqrt((x*x).sum())
return x / r
def gen_rand_vecs(dims, number):
return [get_rand_vec(dims) for _ in xrange(number)]
@Veedrac's answer alerted me to the existence of np.linalg.norm
, which gives us
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
return x / np.linalg.norm(x)
Or
def gen_rand_vecs(dims, number):
return map(lambda x: x / np.linalg.norm(x),
[np.random.standard_normal(dims) for _ in xrange(number)])
If you just want to do this for the unit circle, you can use numpy.random.uniform
to choose the angle \$\theta\$ defining the unit vector.
If you want to deal with the more general case of the \$n\$-sphere, there is a method mentioned on Wikipedia.
To generate uniformly distributed random points on the \$(n − 1)\$-sphere (i.e., the surface of the \$n\$-ball), Marsaglia (1972) gives the following algorithm.
Generate an \$n\$-dimensional vector of normal deviates (it suffices to use \$N(0, 1)\$, although in fact the choice of the variance is arbitrary), \$\mathbf{x}=(x_1,x_2,\ldots,x_n)\$.
Now calculate the "radius" of this point, \$r=\sqrt{x_1^2+x_2^2+\cdots+x_n^2}\$.
The vector \$\frac{1}{r} \mathbf{x}\$ is uniformly distributed over the surface of the unit n-ball.
My attempt at translating that into Python would be
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
r = np.sqrt((x*x).sum())
return x / r
def gen_rand_vecs(dims, number):
return [get_rand_vec(dims) for _ in xrange(number)]
If you just want to do this for the unit circle, you can use numpy.random.uniform
to choose the angle \$\theta\$ defining the unit vector.
If you want to deal with the more general case of the \$n\$-sphere, there is a method mentioned on Wikipedia.
To generate uniformly distributed random points on the \$(n − 1)\$-sphere (i.e., the surface of the \$n\$-ball), Marsaglia (1972) gives the following algorithm.
Generate an \$n\$-dimensional vector of normal deviates (it suffices to use \$N(0, 1)\$, although in fact the choice of the variance is arbitrary), \$\mathbf{x}=(x_1,x_2,\ldots,x_n)\$.
Now calculate the "radius" of this point, \$r=\sqrt{x_1^2+x_2^2+\cdots+x_n^2}\$.
The vector \$\frac{1}{r} \mathbf{x}\$ is uniformly distributed over the surface of the unit n-ball.
My attempt at translating that into Python would be
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
r = np.sqrt((x*x).sum())
return x / r
def gen_rand_vecs(dims, number):
return [get_rand_vec(dims) for _ in xrange(number)]
@Veedrac's answer alerted me to the existence of np.linalg.norm
, which gives us
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
return x / np.linalg.norm(x)
Or
def gen_rand_vecs(dims, number):
return map(lambda x: x / np.linalg.norm(x),
[np.random.standard_normal(dims) for _ in xrange(number)])
If you just want to do this for the unit circle, you can use numpy.random.uniform
to choose the angle \$\theta\$ defining the unit vector.
If you want to deal with the more general case of the \$n\$-sphere, there is a method mentioned on Wikipedia.
To generate uniformly distributed random points on the \$(n − 1)\$-sphere (i.e., the surface of the \$n\$-ball), Marsaglia (1972) gives the following algorithm.
Generate an \$n\$-dimensional vector of normal deviates (it suffices to use \$N(0, 1)\$, although in fact the choice of the variance is arbitrary), \$\mathbf{x}=(x_1,x_2,\ldots,x_n)\$.
Now calculate the "radius" of this point, \$r=\sqrt{x_1^2+x_2^2+\cdots+x_n^2}\$.
The vector \$\frac{1}{r} \mathbf{x}\$ is uniformly distributed over the surface of the unit n-ball.
My attempt at translating that into Python would be
def get_rand_vec(dims):
x = np.random.standard_normal(dims)
r = np.sqrt((x*x).sum())
return x / r
def gen_rand_vecs(dims, number):
return [get_rand_vec(dims) for _ in xrange(number)]