Source code for irfpy.util.isotropy
""" Functions for isotropic distribution
.. autosummary::
getRandom
getRandom_tp
"""
import numpy as np
[docs]def getRandom_tp(size=None):
r""" Return the randomly generated distribution in |theta| and |phi|
:param size: The size of the array.
:return: Randomly generated isotropic distribution.
(theta, phi) = retval in radians
:rtype: (2, size[0], size[1], ...)-shaped numpy array.
>>> rnd = getRandom_tp()
>>> rnd.shape
(2,)
>>> rnd = getRandom_tp(size=(2, 4)) # (3, 2, 4) array will be returned.
>>> rnd.shape
(2, 2, 4)
*Way of generation*
The polar angle, |theta|, should distribute considering the area at spherical surface,
namely depending on :math:`\sin\theta`.
To realize this, one can start from uniform random, convert it according to
.. math::
\theta = \cos^{-1} (1-2P)
where P is the (array of) value generated from random distribution.
The azimuth angle, |phi|, is random in the range of (0, 2 |pi|).
"""
if size is None:
size = 1
theta_random = np.random.uniform(low=0, high=1, size=size)
theta_random = 1 - 2 * theta_random
theta_random = np.clip(theta_random, -1, 1) # To confirm the range.
theta_random = np.arccos(theta_random)
phi_random = np.random.uniform(low=0, high=np.pi * 2, size=size)
values = np.array([theta_random, phi_random])
if size == 1:
values = np.squeeze(values)
return values
[docs]def getRandom(size=None):
r""" Return the randomly generated distribution
:param size: The size of the array.
:return: Randomly generated isotropic distribution.
Unit vector.
:rtype: (3, size[0], size[1], ...)-shaped numpy array.
>>> np.random.seed(0) # Set the random seed.
>>> rnd = getRandom()
>>> rnd.shape
(3,)
>>> print('{:.3f}'.format((rnd ** 2).sum()))
1.000
>>> rnd = getRandom(size=(2, 4)) # (3, 2, 4) array will be returned.
>>> rnd.shape
(3, 2, 4)
*Way of generation*
The polar angle, |theta|, should distribute considering the area at spherical surface,
namely depending on :math:`\sin\theta`.
To realize this, one can start from uniform random, convert it according to
.. math::
\theta = \cos^{-1} (1-2P)
where P is the (array of) value generated from random distribution.
The azimuth angle, |phi|, is random in the range of (0, 2 |pi|).
"""
theta_random, phi_random = getRandom_tp(size)
x = np.sin(theta_random) * np.cos(phi_random)
y = np.sin(theta_random) * np.sin(phi_random)
z = np.cos(theta_random)
return np.array([x, y, z])