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])