aboutsummaryrefslogtreecommitdiffstats
path: root/fg21sim/utils/random.py
blob: 6d835f83dbeceab0f6fd2550636d59b1fad777d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# Copyright (c) 2016 Weitian LI <liweitianux@live.com>
# MIT license

"""
Custom utilities of random number generations.
"""

import numpy as np


def spherical_uniform(n=1):
    """Uniformly pick random points on the surface of a unit sphere.
    The algorithm is described in [SpherePointPicking]_.

    Parameters
    ----------
    n : int
        Number of points to be randomly picked

    Returns
    -------
    theta : float, or 1D `~numpy.ndarray`
        The polar angles, θ ∈ [0, π]. (unit: rad)
        If ``n > 1``, then returns a 1D array containing all the generated
        coordinates. (unit: rad)
    phi : float, or 1D `~numpy.ndarray`
        The azimuthal angles, φ ∈ [0, 2π).

    NOTE
    ----
    Physicists usually adopt the (radial, polar, azimuthal) order with
    the (r, θ, φ) notation for the spherical coordinates convention, which
    is adopted here and by ``healpy``.
    However, this convention is *different* to the convention generally
    used by mathematicians.

    The following relation can be used to convert the generated (theta, phi)
    to the Galactic longitude and latitude convention:
        glon = np.rad2deg(phi)
        glat = 90.0 - np.rad2deg(theta)

    References
    ----------
    .. [SpherePointPicking]
       Wolfram MathWorld - Sphere Point Picking
       http://mathworld.wolfram.com/SpherePointPicking.html

    .. [SphericalCoordinates]
       Wolfram MathWorld - Spherical Coordinates
       http://mathworld.wolfram.com/SphericalCoordinates.html
    """
    u = np.random.uniform(size=n)
    v = np.random.uniform(size=n)
    phi = 2*np.pi * u
    theta = np.arccos(2*v - 1)
    return (theta, phi)