Esempio n. 1
0
 def calc_pdf(m, alpha, mass_star, mass_min, mass_max):
     lg = gammaln(alpha + 1)
     c = np.fabs(special.gammaincc(alpha + 1, mass_min / mass_star))
     d = np.fabs(special.gammaincc(alpha + 1, mass_max / mass_star))
     norm = np.exp(lg) * (c - d)
     return 1. / mass_star * np.power(m / mass_star, alpha) * \
         np.exp(-m / mass_star) / norm
Esempio n. 2
0
def _schechter_cdf(x, x_min, x_max, alpha):
    a = special.gammaincc(alpha + 1, x_min)
    b = special.gammaincc(alpha + 1, x)
    c = special.gammaincc(alpha + 1, x_min)
    d = special.gammaincc(alpha + 1, x_max)

    return (a - b) / (c - d)
Esempio n. 3
0
def test_gammaincc_array():
    # test with vector a
    npt.assert_allclose(gammaincc([-1.2, 1.2], 1.5),
                        [0.008769092458747352, 0.28893139222051745])

    # test with vector x
    npt.assert_allclose(gammaincc(1.2, [0.5, 1.5]),
                        [0.6962998597584569, 0.28893139222051745])

    # test with vector a and x
    npt.assert_allclose(gammaincc([1.2, -1.2], [0.5, 1.5]),
                        [0.6962998597584569, 0.008769092458747352])

    # test with broadcast
    npt.assert_allclose(gammaincc([[1.2], [-1.2]], [0.5, 1.5]),
                        [[0.6962998597584569, 0.28893139222051745],
                         [0.1417443053403289, 0.008769092458747352]])
Esempio n. 4
0
def number_subhalos(halo_mass, alpha, beta, gamma_M, x, m_min, noise=True):
    r'''Number of subhalos.
    This function calculates the number of subhalos above a given initial mass
    for a parent halo of given mass according to the model of Vale & Ostriker
    2004 [1]_ equation (7). The number of subhalos returned can optionally be
    sampled from a Poisson distribution with that mean.

    Parameters
    -----------
    halo_mass : (nm, ) array_like
        The mass of the halo parent, in units of solar mass.
    alpha, beta : float
        Parameters that determines the subhalo Schechter function. Its the amplitude
        is defined by equation (2) in [1].
    gamma_M : float
        Present day mass fraction in subhalos.
    x : float
        Parameter that accounts for the added mass of the original, unstripped
        subhalos.
    m_min : array_like
        Original mass of the least massive subhalo, in units of solar mass.
        Current stripped mass is given by :math:`x m_{min}`.
    noise : bool, optional
        Poisson-sample the number of subhalos. Default is `True`.

    Returns
    --------
    nsubhalos: array_like
        Array of the number of subhalos assigned to parent halos with mass halo_mass.

    Examples
    ---------
    >>> import numpy as np
    >>> from skypy.halo import mass

    This gives the number of subhalos in a parent halo of mass :math:`10^{12} M_\odot`

    >>> halo, min_sh = 1.0e12, 1.0e6
    >>> alpha, beta, gamma_M = 1.9, 1.0, 0.3
    >>> x = 3
    >>> nsh = mass.number_subhalos(halo, alpha, beta, gamma_M, x, min_sh)

    References
    ----------
    .. [1] Vale, A. and Ostriker, J.P. (2005), arXiv: astro-ph/0402500.
    '''
    # m_min is the minimum original subhalo mass
    x_low = m_min / (x * beta * halo_mass)
    # Subhalo amplitude from equation [2]
    A = gamma_M / (beta * gamma(2.0 - alpha))
    # The mean number of subhalos above a mass threshold
    # can be obtained by integrating equation (1) in [1]
    n_subhalos = A * gammaincc(1.0 - alpha, x_low) * gamma(1.0 - alpha)

    # Random number of subhalos following a Poisson distribution
    # with mean n_subhalos
    return np.random.poisson(n_subhalos) if noise else n_subhalos
Esempio n. 5
0
def test_gammaincc_precision():
    # test precision against precomputed values
    values_file = get_pkg_data_filename('data/gammaincc.txt')
    a, x, v = np.loadtxt(values_file).T
    g = gammaincc(a, x)

    # collect where the assertion will fail before it does,
    # so we can have a more informative message
    fail = ~np.isclose(g, v, rtol=1e-10, atol=0)
    lines = []
    if np.any(fail):
        for numbers in zip(a[fail], x[fail], g[fail], v[fail]):
            lines.append('gammaincc(%g, %g) = %g != %g)' % numbers)

    # now do the assertion
    npt.assert_allclose(g, v, rtol=1e-10, atol=0, err_msg='\n'.join(lines))
Esempio n. 6
0
def test_gammaincc_neg_x_array():
    # negative x in array raises an exception
    with pytest.raises(ValueError):
        gammaincc(0.5, [3.0, 2.0, 1.0, 0.0, -1.0])
Esempio n. 7
0
def test_gammaincc_neg_x_scalar():
    # negative x raises an exception
    with pytest.raises(ValueError):
        gammaincc(0.5, -1.0)
Esempio n. 8
0
def test_gammaincc_scalar():
    # test with scalar input and expect scalar output
    npt.assert_allclose(gammaincc(1.2, 1.5), 0.28893139222051745)
Esempio n. 9
0
def test_gammaincc_edge_cases():
    # gammaincc is zero for x = inf
    assert gammaincc(1.2, np.inf) == 0
    assert gammaincc(-1.2, np.inf) == 0
    assert gammaincc(0, np.inf) == 0
    npt.assert_equal(gammaincc([1.2, 2.2], np.inf), [0, 0])
    npt.assert_equal(gammaincc([-1.2, -2.2], np.inf), [0, 0])
    npt.assert_equal(gammaincc([0.0, 1.0], np.inf), [0, 0])

    # gammaincc is zero for a = -1, -2, -3, ...
    assert gammaincc(-1.0, 0.5) == 0
    assert gammaincc(-2.0, 0.5) == 0
    npt.assert_equal(gammaincc([-1.0, -2.0], 0.5), [0, 0])

    # gammaincc is unity for a > 0 and x = 0
    assert gammaincc(0.5, 0) == 1
    assert gammaincc(1.5, 0) == 1
    npt.assert_equal(gammaincc([0.5, 1.5], 0), [1, 1])

    # gammaincc is zero for a nonpositive integer and x = 0
    assert gammaincc(0, 0) == 0
    assert gammaincc(-1, 0) == 0
    assert gammaincc(-2, 0) == 0
    npt.assert_equal(gammaincc([0, -1, -2], 0), [0, 0, 0])

    # gammaincc is infinity for a negative noninteger and x = 0
    assert gammaincc(-0.5, 0) == -np.inf
    assert gammaincc(-1.5, 0) == np.inf
    assert gammaincc(-2.5, 0) == -np.inf
    npt.assert_equal(gammaincc([-0.5, -1.5], 0), [-np.inf, np.inf])
Esempio n. 10
0
def herbel_pdf(redshift, alpha, a_phi, b_phi, a_m, b_m, cosmology,
               luminosity_min):
    r"""Calculates the redshift pdf of the Schechter luminosity function
    according to the model of Herbel et al. [1]_ equation (3.6).

    That is, changing the absolute magnitude M in equation (3.2) to luminosity
    L, integrate over all possible L and multiplying by the comoving element
    using a flat :math:`\Lambda \mathrm{CDM}` model to get the corresponding
    pdf.

    Parameters
    ----------
    redshift : array_like
        Input redshifts.
    alpha : float or scalar
        The alpha parameter in the Schechter luminosity function
    a_phi, b_phi : float or scalar
        Parametrisation factors of the normalisation factor Phi_* as a function
        of redshift according to Herbel et al. [1]_ equation (3.4).
    a_m, b_m : float or scalar
        Parametrisation factors of the characteristic absolute magnitude M_* as
        a function of redshift according to Herbel et al. [1]_ equation (3.3).
    cosmology : instance
        Instance of an Astropy Cosmology class.
    luminosity_min : float or scalar
        Cut-off luminosity value such that the Schechter luminosity function
        diverges for L -> 0

    Returns
    -------
    pdf : ndarray or float
    Un-normalised probability density function as a function of redshift
    according to Herbel et al. [1]_.

    Notes
    -----
    This module calculates the function

    .. math::

        \mathrm{pdf}(z) = \Phi_\star(z) \cdot \frac{d_H d_M^2}{E(z)} \cdot
            \Gamma\left(\alpha + 1, \frac{L_\mathrm{min}}{L_\star(z)}\right)\:,

    with :math:`\Phi_\star(z) = b_\phi \exp(a_\phi z)` and the second term the
    comoving element.

    References
    ----------
    .. [1] Herbel J., Kacprzak T., Amara A. et al., 2017, Journal of Cosmology
           and Astroparticle Physics, Issue 08, article id. 035 (2017)

    Examples
    --------
    >>> from skypy.galaxy.redshift import herbel_pdf
    >>> import skypy.utils.astronomy as astro
    >>> from astropy.cosmology import FlatLambdaCDM
    >>> import numpy as np

    Calculate the pdf for 100 redshift values between 0 and 2 with
    a_m = -0.9408582, b_m = -20.40492365, a_phi = -0.10268436,
    b_phi = 0.00370253, alpha = -1.3 for a flat cosmology.

    >>> cosmology = FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725)
    >>> redshift = np.linspace(0, 2, 100)
    >>> luminosity_min = astro.luminosity_from_absolute_magnitude(-16.0)
    >>> redshift = herbel_pdf(redshift=redshift, alpha=-1.3,
    ...                     a_phi=-0.10268436,a_m=-0.9408582, b_phi=0.00370253,
    ...                     b_m=-20.40492365, cosmology=cosmology,
    ...                     luminosity_min=luminosity_min)
    """
    dv = cosmology.differential_comoving_volume(redshift).value
    x = luminosity_min \
        * 1./astro.luminosity_from_absolute_magnitude(a_m*redshift + b_m)
    lg = sc.gammaln(alpha + 1)
    gx = np.fabs(special.gammaincc(alpha + 1, x))
    pdf = dv * b_phi * np.exp(a_phi * redshift + lg) * gx
    return pdf
Esempio n. 11
0
 def schechter_cdf_gen(alpha, x_min, x_max):
     a = gammaincc(alpha + 1, x_min)
     b = gammaincc(alpha + 1, x_max)
     return lambda x: (a - gammaincc(alpha + 1, x)) / (a - b)
Esempio n. 12
0
def test_gammaincc_neg_x_array():
    # negative x in array raises an exception
    gammaincc(0.5, [3.0, 2.0, 1.0, 0.0, -1.0])
Esempio n. 13
0
def test_gammaincc_neg_x_scalar():
    # negative x raises an exception
    gammaincc(0.5, -1.0)
Esempio n. 14
0
 def calc_cdf(x):
     a = special.gammaincc(alpha + 1, x_min)
     b = special.gammaincc(alpha + 1, x)
     c = special.gammaincc(alpha + 1, x_min)
     d = special.gammaincc(alpha + 1, x_max)
     return (a - b) / (c - d)