Exemplo n.º 1
0
def test_schechter():

    from skypy.utils.random import schechter
    from skypy.utils.special import gammaincc

    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)

    # Test the schechter function, sampling dimensionless x values
    alpha = -1.3
    x_min = 1e-10
    x_max = 1e2

    x = schechter(alpha, x_min, x_max, size=1000)

    assert np.all(x >= x_min)
    assert np.all(x <= x_max)

    # Test the distribution of galaxy properties follows the right distribution
    cdf = schechter_cdf_gen(alpha, x_min, x_max)
    _, p = kstest(x, cdf)
    assert p > 0.01

    # Test output shape when scale is a scalar
    scale = 5
    samples = schechter(alpha, x_min, x_max, scale=scale)
    assert np.shape(samples) == np.shape(scale)

    # Test output shape when scale is an array
    scale = np.random.uniform(size=10)
    samples = schechter(alpha, x_min, x_max, scale=scale)
    assert np.shape(samples) == np.shape(scale)
Exemplo n.º 2
0
def subhalo_mass_sampler(halo_mass, nsubhalos, alpha, beta,
                         x, m_min, resolution=100):
    r'''Subhalo mass sampler.
    This function samples the original, unstriped masses of subhaloes from the
    subhalo mass function of their parent halo with a constant mass stripping
    factor given by equation (1) in [1]_ and the upper subhalo mass limit from
    [2]_.

    Parameters
    -----------
    halo_mass : (nm, ) array_like
        The mass of the halo parent, in units of solar mass.
    nsubhalos: (nm, ) array_like
        Array of the number of subhalos assigned to parent halos with mass `halo_mass`.
    alpha, beta : float
        Parameters that determines the subhalo Schechter function. Its the amplitude
        is defined by equation 2 in [1].
    x : float
        Parameter that accounts for the added mass of the original, unstripped
        subhalos.
    m_min : float
        Original mass of the least massive subhalo, in units of solar mass.
        Current stripped mass is given by :math:`m_{min} / x`.
    resolution: int, optional
        Resolution of the inverse transform sampling spline. Default is 100.

    Returns
    --------
    sample: (nh, ) array_like
        List of original masses drawn from the subhalo mass function for each
        parent halo, in units of solar mass. The length corresponds to the total
        number of subhalos for all parent halos, i.e. `np.sum(nsubhalos)`.

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

    This example samples 100 subhalos for a parent halo of mass 1.0E12 Msun:

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

    References
    ----------
    .. [1] Vale, A. and Ostriker, J.P. (2004), arXiv: astro-ph/0402500.
    .. [2] Vale, A. and Ostriker, J.P. (2004), arXiv: astro-ph/0511816.
    '''
    halo_mass = np.atleast_1d(halo_mass)
    nsubhalos = np.atleast_1d(nsubhalos)
    subhalo_list = []
    for M, n in zip(halo_mass, nsubhalos):
        x_min = m_min / (x * beta * M)
        x_max = 0.5 / (x * beta)
        subhalo_mass = schechter(alpha, x_min, x_max, resolution, size=n, scale=x * beta * M)
        subhalo_list.append(subhalo_mass)
    return np.concatenate(subhalo_list)
Exemplo n.º 3
0
def test_schechter_gamma():

    from skypy.utils.random import schechter

    # when alpha > 0, x_min ≈ 0, x_max ≈ ∞, distribution is gamma
    # n.b. if alpha < 0 the distribution becomes too steep to resolve accurately
    alpha = np.random.uniform(0, 2)
    x_min = 1e-20
    x_max = 1e+20
    scale = 2.5

    x = schechter(alpha, x_min, x_max, resolution=100000, size=1000, scale=scale)

    _, p = kstest(x, 'gamma', args=(alpha+1, 0, scale))
    assert p > 0.01
Exemplo n.º 4
0
def press_schechter(n,
                    m_star,
                    size=None,
                    x_min=0.00305,
                    x_max=1100.0,
                    resolution=100):
    """Sampling from Press-Schechter mass function (1974).

    Masses following the Press-Schechter mass function following the
    Press et al. [1]_ formalism.

    Parameters
    ----------
    n : float or int
        The n parameter in the Press-Schechter mass function.
    m_star : float or int
        Factors parameterising the characteristic mass.
    size: int, optional
         Output shape of luminosity samples.
    x_min, x_max : float or int, optional
        Lower and upper bounds in units of M*.
    resolution : int, optional
        Resolution of the inverse transform sampling spline. Default is 100.

    Returns
    -------
    mass : array_like
        Drawn masses from the Press-Schechter mass function.

    Examples
    --------
    >>> import skypy.halo.mass as mass
    >>> n, m_star = 1, 1e9
    >>> sample = mass.press_schechter(n, m_star, size=1000, x_min=1e-10,
    ...                               x_max=1e2, resolution=1000)

    References
    ----------
    .. [1] Press, W. H. and Schechter, P., APJ, (1974).

    """

    alpha = -0.5 * (n + 9.0) / (n + 3.0)

    x_sample = schechter(alpha, x_min, x_max, resolution=resolution, size=size)

    return m_star * np.power(x_sample, 3.0 / (n + 3.0))
Exemplo n.º 5
0
def test_schechter():

    # Test the schechter function, sampling dimensionless x values
    alpha = -1.3
    x_min = 1e-10
    x_max = 1e2

    def calc_cdf(x):
        a = special.upper_incomplete_gamma(alpha + 1, x_min)
        b = special.upper_incomplete_gamma(alpha + 1, x)
        c = special.upper_incomplete_gamma(alpha + 1, x_min)
        d = special.upper_incomplete_gamma(alpha + 1, x_max)
        return (a - b) / (c - d)

    sample = random.schechter(alpha,
                              x_min=x_min,
                              x_max=x_max,
                              resolution=100,
                              size=1000)

    # Test the distribution of galaxy properties follows the right distribution
    p_value = scipy.stats.kstest(sample, calc_cdf)[1]
    assert p_value > 0.01
Exemplo n.º 6
0
def herbel_luminosities(redshift,
                        alpha,
                        a_m,
                        b_m,
                        size=None,
                        x_min=0.00305,
                        x_max=1100.0,
                        resolution=100):
    r"""Model of Herbel et al (2017)

    Luminosities following the Schechter luminosity function following the
    Herbel et al. [1]_ model.

    Parameters
    ----------
    redshift : (nz,) array-like
        The redshift values at which to sample luminosities.
    alpha : float or int
        The alpha parameter in the Schechter luminosity function.
    a_m, b_m : float or int
        Factors parameterising the characteristic absolute magnitude M_* as
        a linear function of redshift according to Equation 3.3 in [1]_.
    size: int, optional
         Output shape of luminosity samples. If size is None and redshift
         is a scalar, a single sample is returned. If size is None and
         redshift is an array, an array of samples is returned with the same
         shape as redshift.
    x_min, x_max : float or int, optional
        Lower and upper luminosity bounds in units of L*.
    resolution : int, optional
        Resolution of the inverse transform sampling spline. Default is 100.

    Returns
    -------
    luminosity : array_like
        Drawn luminosities from the Schechter luminosity function.

    Notes
    -----
    The Schechter luminosity function is given as

    .. math::
        \Phi(L, z) = \frac{\Phi_\star(z)}{L_\star(z)}
            \left(\frac{L}{L_\star(z)}\right)^\alpha
            /exp\left(-\frac{L}{L_\star(z)}\right) \;.

    Here the luminosity is defined as

    .. math::

        L = 10^{-0.4M} \;,

    with absolute magnitude :math:`M`. Furthermore, Herbel et al. [1]_
    introduced

    .. math::

        \Phi_\star(z) = b_\phi \exp(a_\phi z) \;,
        M_\star(z) = a_M z + b_M \;.

    Now we have to rescale the Schechter function by the comoving element and
    get

    .. math::

        \phi(L,z) = \frac{d_H d_M^2}{E(z)}  \Phi(L,z)\;.

    Examples
    --------
    >>> import skypy.galaxy.luminosity as lum

    Sample 100 luminosity values at redshift z = 1.0 with
    a_m = -0.9408582, b_m = -20.40492365, alpha = -1.3.

    >>> luminosities = lum.herbel_luminosities(1.0, -1.3, -0.9408582,
    ...                                         -20.40492365, size=100)

    Sample a luminosity value for every redshift in an array z with
    a_m = -0.9408582, b_m = -20.40492365, alpha = -1.3.

    >>> z = np.linspace(0,2, 100)
    >>> luminosities = lum.herbel_luminosities(z, -1.3, -0.9408582,
    ...                                         -20.40492365)

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

    """

    if size is None and np.shape(redshift):
        size = np.shape(redshift)

    luminosity_star = _calculate_luminosity_star(redshift, a_m, b_m)

    x_sample = schechter(alpha, x_min, x_max, resolution=100, size=size)

    return luminosity_star * x_sample
Exemplo n.º 7
0
def schechter_smf(alpha, m_star, x_min, x_max, resolution=100, size=None):
    r""" Stellar masses following the Schechter mass function [1]_.

    Parameters
    ----------
    alpha : float
        The alpha parameter in the Schechter stellar mass function.
    m_star : (nm,) array-like
        Characteristic stellar mass M_*.
    size: int, optional
         Output shape of stellar mass samples. If size is None and m_star
         is a scalar, a single sample is returned. If size is None and
         m_star is an array, an array of samples is returned with the same
         shape as m_star.
    x_min, x_max : float
        Lower and upper bounds for the random variable x in units of M_*.
    resolution : int, optional
        Resolution of the inverse transform sampling spline. Default is 100.

    Returns
    -------
    stellar mass : (nm,) array_like
        Drawn stellar masses from the Schechter stellar mass function in units
        of the solar mass.

    Notes
    -----
    The stellar mass probability distribution (pdf) follows a Schechter
    profile of the form

    .. math::

        \Phi(M) = \frac{1}{M_*} \left(\frac{M}{M_*}\right)^\alpha
            \exp\left(-\frac{M}{M_*}\right) \;.

    From this pdf one can sample the stellar masses.

    Examples
    --------
    >>> from skypy.galaxy import stellar_mass

    Sample 100 stellar masses values at redshift z = 1.0 with alpha = -1.4,
    m_star = 10**10.67, x_min = 0.0002138 and x_max = 213.8

    >>> masses = stellar_mass.schechter_smf(-1.4, 10**10.67, 0.0002138,
    ...                               213.8, size=100)

    References
    ----------
    .. [1] Mo, H., Van den Bosch, F., & White, S. (2010). Galaxy Formation and
        Evolution. Cambridge: Cambridge University Press.
        doi:10.1017/CBO9780511807244

    """

    if size is None and np.shape(m_star):
        size = np.shape(m_star)

    x_sample = schechter(alpha, x_min, x_max, resolution=resolution, size=size)

    return m_star * x_sample