U
    e»{j]R  ã                   @   s¸   d Z ddlZddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZ ddd	d
ddgZG dd„ de
ƒZG dd„ de
ƒZG dd	„ d	e
ƒZG dd
„ d
e
ƒZG dd„ de
ƒZG dd„ de
ƒZdS )z
Power law model variants
é    N)Ú	MagnitudeÚQuantityÚ
UnitsErrorÚdimensionless_unscaledÚmagé   )ÚFittable1DModel)ÚInputParameterErrorÚ	ParameterÚ
PowerLaw1DÚBrokenPowerLaw1DÚSmoothlyBrokenPowerLaw1DÚExponentialCutoffPowerLaw1DÚLogParabola1DÚSchechter1Dc                   @   s`   e Zd ZdZeddd�Zeddd�Zeddd�Zedd„ ƒZ	ed	d
„ ƒZ
edd„ ƒZdd„ ZdS )r   aÛ  
    One dimensional power law model.

    Parameters
    ----------
    amplitude : float
        Model amplitude at the reference point
    x_0 : float
        Reference point
    alpha : float
        Power law index

    See Also
    --------
    BrokenPowerLaw1D, ExponentialCutoffPowerLaw1D, LogParabola1D

    Notes
    -----
    Model formula (with :math:`A` for ``amplitude`` and :math:`\alpha` for ``alpha``):

        .. math:: f(x) = A (x / x_0) ^ {-\alpha}

    r   z!Peak value at the reference point©ÚdefaultÚdescriptionúReference pointúPower law indexc                 C   s   | | }|||   S )z(One dimensional power law model function© )ÚxÚ	amplitudeÚx_0ÚalphaÚxxr   r   úY/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/modeling/powerlaws.pyÚevaluate4   s    zPowerLaw1D.evaluatec                 C   s@   | | }||  }|| | | }| | t  |¡ }|||gS )z?One dimensional power law derivative with respect to parameters©ÚnpÚlog)r   r   r   r   r   Úd_amplitudeÚd_x_0Úd_alphar   r   r   Ú	fit_deriv:   s
    
zPowerLaw1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS ©Nr   ©r   ÚunitÚinputs©Úselfr   r   r   Úinput_unitsF   s    zPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dœS ©Nr   )r   r   ©r(   Úoutputs©r*   Zinputs_unitZoutputs_unitr   r   r   Ú_parameter_units_for_data_unitsL   s    þz*PowerLaw1D._parameter_units_for_data_unitsN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r   r   Ústaticmethodr   r$   Úpropertyr+   r0   r   r   r   r   r      s   


c                   @   sl   e Zd ZdZeddd�Zeddd�Zeddd�Zeddd�Ze	dd	„ ƒZ
e	d
d„ ƒZedd„ ƒZdd„ ZdS )r   aV  
    One dimensional power law model with a break.

    Parameters
    ----------
    amplitude : float
        Model amplitude at the break point.
    x_break : float
        Break point.
    alpha_1 : float
        Power law index for x < x_break.
    alpha_2 : float
        Power law index for x > x_break.

    See Also
    --------
    PowerLaw1D, ExponentialCutoffPowerLaw1D, LogParabola1D

    Notes
    -----
    Model formula (with :math:`A` for ``amplitude`` and :math:`\alpha_1`
    for ``alpha_1`` and :math:`\alpha_2` for ``alpha_2``):

        .. math::

            f(x) = \left \{
                     \begin{array}{ll}
                       A (x / x_{break}) ^ {-\alpha_1} & : x < x_{break} \\
                       A (x / x_{break}) ^ {-\alpha_2} & :  x > x_{break} \\
                     \end{array}
                   \right.
    r   úPeak value at break pointr   úBreak pointú"Power law index before break pointú!Power law index after break pointc                 C   s(   t  | |k ||¡}| | }|||   S )z/One dimensional broken power law model function)r   Úwhere)r   r   Úx_breakÚalpha_1Úalpha_2r   r   r   r   r   r   z   s    zBrokenPowerLaw1D.evaluatec                 C   sx   t  | |k ||¡}| | }||  }|| | | }| | t  |¡ }	t  | |k |	d¡}
t  | |k|	d¡}|||
|gS )zFOne dimensional broken power law derivative with respect to parametersr   )r   r;   r    )r   r   r<   r=   r>   r   r   r!   Ú	d_x_breakr#   Ú	d_alpha_1Ú	d_alpha_2r   r   r   r$   ‚   s    
zBrokenPowerLaw1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS r%   ©r<   r'   r(   r)   r   r   r   r+   ‘   s    zBrokenPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dœS ©Nr   )r<   r   r-   r/   r   r   r   r0   —   s    þz0BrokenPowerLaw1D._parameter_units_for_data_unitsN)r1   r2   r3   r4   r
   r   r<   r=   r>   r5   r   r$   r6   r+   r0   r   r   r   r   r   S   s   !


c                   @   sš   e Zd ZdZeddddd�Zeddd�Zed	d
d�Zeddd�Zedddd�Z	ej
dd„ ƒZe	j
dd„ ƒZ	edd„ ƒZedd„ ƒZedd„ ƒZdd„ ZdS )r   a+
  One dimensional smoothly broken power law model.

    Parameters
    ----------
    amplitude : float
        Model amplitude at the break point.
    x_break : float
        Break point.
    alpha_1 : float
        Power law index for ``x << x_break``.
    alpha_2 : float
        Power law index for ``x >> x_break``.
    delta : float
        Smoothness parameter.

    See Also
    --------
    BrokenPowerLaw1D

    Notes
    -----
    Model formula (with :math:`A` for ``amplitude``, :math:`x_b` for
    ``x_break``, :math:`\alpha_1` for ``alpha_1``,
    :math:`\alpha_2` for ``alpha_2`` and :math:`\Delta` for
    ``delta``):

        .. math::

            f(x) = A \left( \frac{x}{x_b} \right) ^ {-\alpha_1}
                   \left\{
                      \frac{1}{2}
                      \left[
                        1 + \left( \frac{x}{x_b}\right)^{1 / \Delta}
                      \right]
                   \right\}^{(\alpha_1 - \alpha_2) \Delta}


    The change of slope occurs between the values :math:`x_1`
    and :math:`x_2` such that:

        .. math::
            \log_{10} \frac{x_2}{x_b} = \log_{10} \frac{x_b}{x_1}
            \sim \Delta


    At values :math:`x \lesssim x_1` and :math:`x \gtrsim x_2` the
    model is approximately a simple power law with index
    :math:`\alpha_1` and :math:`\alpha_2` respectively.  The two
    power laws are smoothly joined at values :math:`x_1 < x < x_2`,
    hence the :math:`\Delta` parameter sets the "smoothness" of the
    slope change.

    The ``delta`` parameter is bounded to values greater than 1e-3
    (corresponding to :math:`x_2 / x_1 \gtrsim 1.002`) to avoid
    overflow errors.

    The ``amplitude`` parameter is bounded to positive values since
    this model is typically used to represent positive quantities.


    Examples
    --------
    .. plot::
        :include-source:

        import numpy as np
        import matplotlib.pyplot as plt
        from astropy.modeling import models

        x = np.logspace(0.7, 2.3, 500)
        f = models.SmoothlyBrokenPowerLaw1D(amplitude=1, x_break=20,
                                            alpha_1=-2, alpha_2=2)

        plt.figure()
        plt.title("amplitude=1, x_break=20, alpha_1=-2, alpha_2=2")

        f.delta = 0.5
        plt.loglog(x, f(x), '--', label='delta=0.5')

        f.delta = 0.3
        plt.loglog(x, f(x), '-.', label='delta=0.3')

        f.delta = 0.1
        plt.loglog(x, f(x), label='delta=0.1')

        plt.axis([x.min(), x.max(), 0.1, 1.1])
        plt.legend(loc='lower center')
        plt.grid(True)
        plt.show()

    r   r   r7   T)r   Úminr   r   r8   r   éþÿÿÿr9   é   r:   çü©ñÒMbP?zSmoothness Parameter)r   rD   r   c                 C   s   t  |dk¡rtdƒ‚d S )Nr   zamplitude parameter must be > 0©r   Úanyr	   ©r*   Úvaluer   r   r   r     s    z"SmoothlyBrokenPowerLaw1D.amplitudec                 C   s   t  |dk ¡rtdƒ‚d S )NrG   z delta parameter must be >= 0.001rH   rJ   r   r   r   Údelta  s    zSmoothlyBrokenPowerLaw1D.deltac                 C   s$  | | }t j|dd�}t|tƒr.|j}|j}nd}t  |¡| }	d}
|	|
k}| ¡ rz||| |   d|| |   ||< |	|
 k }| ¡ r²||| |   d|| |   ||< t  |	¡|
k}| ¡ �r
t  	|	| ¡}d| d }||| |   ||| |   ||< |�r t||ddd�S |S )	z8One dimensional smoothly broken power law model functionF)ÚsubokNé   ç       @ç      ð?T)r'   ÚcopyrM   )
r   Ú
zeros_likeÚ
isinstancer   r'   rK   r    ÚmaxÚabsÚexp)r   r   r<   r=   r>   rL   r   ÚfZreturn_unitÚlogtÚ	thresholdÚiÚtÚrr   r   r   r     s0    
 ÿ
 ÿ
&z!SmoothlyBrokenPowerLaw1D.evaluatec                 C   sú  | | }t  |¡| }t  |¡}t  |¡}	t  |¡}
t  |¡}t  |¡}t  |¡}d}||k}| ¡ �r||| |   d|| |   ||< || | |	|< || | | |
|< || | t  d¡  ||< || t  || ¡ |t  d¡   ||< || ||  t  d¡  ||< || k }| ¡ �rÚ||| |   d|| |   ||< || | |	|< || | | |
|< || t  || ¡ |t  d¡   ||< || | t  d¡ ||< || ||  t  d¡  ||< t  |¡|k}| ¡ �rìt  || ¡}d| d }||| |   ||| |   ||< || | |	|< || ||| | d |   | |
|< || t  || ¡ |t  |¡   ||< || | t  |¡  ||< || ||  t  |¡|d|  | t  || ¡   ||< |	|
|||gS )zWOne dimensional smoothly broken power law derivative with respect
        to parametersrN   rO   rF   rP   )r   r    rR   rT   rU   rV   )r   r   r<   r=   r>   rL   r   rX   rW   r!   r?   r@   rA   Zd_deltarY   rZ   r[   r\   r   r   r   r$   E  sX    






 ÿ* 

 ÿ* 
&"ÿ*ÿ&þÿz"SmoothlyBrokenPowerLaw1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS r%   rB   r)   r   r   r   r+   „  s    z$SmoothlyBrokenPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dœS rC   r-   r/   r   r   r   r0   Š  s    þz8SmoothlyBrokenPowerLaw1D._parameter_units_for_data_unitsN)r1   r2   r3   r4   r
   r   r<   r=   r>   rL   Ú	validatorr5   r   r$   r6   r+   r0   r   r   r   r   r   ž   s,   \   ÿ


7
>
c                   @   sl   e Zd ZdZeddd�Zeddd�Zeddd�Zeddd�Ze	dd	„ ƒZ
e	d
d„ ƒZedd„ ƒZdd„ ZdS )r   a  
    One dimensional power law model with an exponential cutoff.

    Parameters
    ----------
    amplitude : float
        Model amplitude
    x_0 : float
        Reference point
    alpha : float
        Power law index
    x_cutoff : float
        Cutoff point

    See Also
    --------
    PowerLaw1D, BrokenPowerLaw1D, LogParabola1D

    Notes
    -----
    Model formula (with :math:`A` for ``amplitude`` and :math:`\alpha` for ``alpha``):

        .. math:: f(x) = A (x / x_0) ^ {-\alpha} \exp (-x / x_{cutoff})

    r   úPeak value of modelr   r   r   zCutoff pointc                 C   s&   | | }|||   t  |  | ¡ S )z;One dimensional exponential cutoff power law model function)r   rV   )r   r   r   r   Úx_cutoffr   r   r   r   r   ±  s    z$ExponentialCutoffPowerLaw1D.evaluatec                 C   sj   | | }| | }||  t  | ¡ }|| | | }| | t  |¡ }	||  | |d  }
|||	|
gS )zd
        One dimensional exponential cutoff power law derivative with respect to parameters
        rF   )r   rV   r    )r   r   r   r   r_   r   Zxcr!   r"   r#   Z
d_x_cutoffr   r   r   r$   ¸  s    z%ExponentialCutoffPowerLaw1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS r%   r&   r)   r   r   r   r+   È  s    z'ExponentialCutoffPowerLaw1D.input_unitsc                 C   s*   || j d  || j d  || jd  dœS )Nr   )r   r_   r   r-   r/   r   r   r   r0   Î  s    ýz;ExponentialCutoffPowerLaw1D._parameter_units_for_data_unitsN)r1   r2   r3   r4   r
   r   r   r   r_   r5   r   r$   r6   r+   r0   r   r   r   r   r   ‘  s   


c                   @   sl   e Zd ZdZeddd�Zeddd�Zeddd�Zeddd�Ze	d	d
„ ƒZ
e	dd„ ƒZedd„ ƒZdd„ ZdS )r   a•  
    One dimensional log parabola model (sometimes called curved power law).

    Parameters
    ----------
    amplitude : float
        Model amplitude
    x_0 : float
        Reference point
    alpha : float
        Power law index
    beta : float
        Power law curvature

    See Also
    --------
    PowerLaw1D, BrokenPowerLaw1D, ExponentialCutoffPowerLaw1D

    Notes
    -----
    Model formula (with :math:`A` for ``amplitude`` and
    :math:`\alpha` for ``alpha`` and :math:`\beta` for ``beta``):

        .. math:: f(x) = A \left(
                \frac{x}{x_{0}}\right)^{- \alpha - \beta \log{\left (\frac{x}{x_{0}}
            \right )}}

    r   r^   r   r   r   r   zPower law curvaturec                 C   s(   | | }| |t  |¡  }|||  S )z+One dimensional log parabola model functionr   )r   r   r   r   Úbetar   Úexponentr   r   r   r   ù  s    zLogParabola1D.evaluatec                 C   sp   | | }t  |¡}| ||  }|| }| | |d  }	|| || | ||   }
| | | }||
||	gS )zBOne dimensional log parabola derivative with respect to parametersrF   r   )r   r   r   r   r`   r   Zlog_xxra   r!   Zd_betar"   r#   r   r   r   r$     s    
zLogParabola1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS r%   r&   r)   r   r   r   r+     s    zLogParabola1D.input_unitsc                 C   s   || j d  || jd  dœS r,   r-   r/   r   r   r   r0     s    þz-LogParabola1D._parameter_units_for_data_unitsN)r1   r2   r3   r4   r
   r   r   r   r`   r5   r   r$   r6   r+   r0   r   r   r   r   r   Ö  s   


c                   @   sf   e Zd ZdZeddd�Zedddd�Zed	d
d�Zedd„ ƒZ	dd„ Z
dd„ Zedd„ ƒZdd„ ZdS )r   a@  
    Schechter luminosity function (`Schechter 1976
    <https://ui.adsabs.harvard.edu/abs/1976ApJ...203..297S/abstract>`_),
    parameterized in terms of magnitudes.

    Parameters
    ----------
    phi_star : float
        The normalization factor in units of number density.

    m_star : float
        The characteristic magnitude where the power-law form of the
        function cuts off.

    alpha : float
        The power law index, also known as the faint-end slope. Must not
        have units.

    See Also
    --------
    PowerLaw1D, ExponentialCutoffPowerLaw1D, BrokenPowerLaw1D

    Notes
    -----
    Model formula (with :math:`\phi^{*}` for ``phi_star``, :math:`M^{*}`
    for ``m_star``, and :math:`\alpha` for ``alpha``):

    .. math::

        n(M) \ dM = (0.4 \ln 10) \ \phi^{*} \
            [{10^{0.4 (M^{*} - M)}}]^{\alpha + 1} \
            \exp{[-10^{0.4 (M^{*} - M)}]} \ dM

    ``phi_star`` is the normalization factor in units of number density.
    ``m_star`` is the characteristic magnitude where the power-law form
    of the function cuts off into the exponential form. ``alpha`` is
    the power-law index, defining the faint-end slope of the luminosity
    function.

    Examples
    --------
    .. plot::
        :include-source:

        from astropy.modeling.models import Schechter1D
        import astropy.units as u
        import matplotlib.pyplot as plt
        import numpy as np

        phi_star = 4.3e-4 * (u.Mpc ** -3)
        m_star = -20.26
        alpha = -1.98
        model = Schechter1D(phi_star, m_star, alpha)
        mag = np.linspace(-25, -17)

        fig, ax = plt.subplots()
        ax.plot(mag, model(mag))
        ax.set_yscale('log')
        ax.set_xlim(-22.6, -17)
        ax.set_ylim(1.e-7, 1.e-2)
        ax.set_xlabel('$M_{UV}$')
        ax.set_ylabel('$\phi$ [mag$^{-1}$ Mpc$^{-3}]$')

    References
    ----------
    .. [1] Schechter 1976; ApJ 203, 297
           (https://ui.adsabs.harvard.edu/abs/1976ApJ...203..297S/abstract)

    .. [2] `Luminosity function <https://en.wikipedia.org/wiki/Luminosity_function_(astronomy)>`_
    rP   z/Normalization factor in units of number densityr   g      4ÀzCharacteristic magnitudeT)r   r   r   g      ð¿zFaint-end slopec                 C   sN   | | }t |tƒr>|jtkr4t|jtd�}| t¡S tdƒ‚ndd|  S d S )N)r'   z5The units of magnitude and m_star must be a magnitudeé
   gš™™™™™Ù¿)	rS   r   r'   r   r   rK   Útor   r   )Z	magnitudeÚm_starZ
factor_expr   r   r   Ú_factorj  s    


ÿzSchechter1D._factorc                 C   s6   |   ||¡}dt d¡ | ||d   t | ¡ S )z-Schechter luminosity function model function.çš™™™™™Ù?rb   r   ©re   r   r    rV   )r*   r   Úphi_starrd   r   Úfactorr   r   r   r   z  s    zSchechter1D.evaluatec           
      C   s‚   |   ||¡}dt d¡ ||d   t | ¡ }|| }|d d t d¡ | dt d¡ | |  }|t |¡ }	|||	gS )z^
        Schechter luminosity function derivative with respect to
        parameters.
        rf   rb   r   rg   )
r*   r   rh   rd   r   ri   Z
d_phi_starÚfuncZd_m_starr#   r   r   r   r$   �  s    &ÿzSchechter1D.fit_derivc                 C   s"   | j jd krd S | jd | j jiS r%   )rd   r'   r(   r)   r   r   r   r+   ‘  s    zSchechter1D.input_unitsc                 C   s   || j d  || jd  dœS )Nr   )rd   rh   r-   r/   r   r   r   r0   —  s    þz+Schechter1D._parameter_units_for_data_unitsN)r1   r2   r3   r4   r
   rh   rd   r   r5   re   r   r$   r6   r+   r0   r   r   r   r   r     s   G ÿ

)r4   Únumpyr   Zastropy.unitsr   r   r   r   r   Úcorer   Ú
parametersr	   r
   Ú__all__r   r   r   r   r   r   r   r   r   r   Ú<module>   s$   ú
<K tEF