B
    q\>                 @   s   d Z ddlmZ ddlZddlmZ ddlmZm	Z	 ddl
mZ 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dS )z
Power law model variants
    )OrderedDictN   )Fittable1DModel)	ParameterInputParameterError)Quantity
PowerLaw1DBrokenPowerLaw1DSmoothlyBrokenPowerLaw1DExponentialCutoffPowerLaw1DLogParabola1Dc               @   sZ   e Zd ZdZeddZeddZe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   )defaultc             C   s   | | }|||   S )z(One dimensional power law model function )x	amplitudex_0alphaxxr   r   9lib/python3.7/site-packages/astropy/modeling/powerlaws.pyevaluate1   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_deriv7   s
    
zPowerLaw1D.fit_derivc             C   s    | j jd krd S d| j jiS d S )Nr   )r   unit)selfr   r   r   input_unitsC   s    zPowerLaw1D.input_unitsc             C   s   t d|d fd|d fgS )Nr   r   r   y)r   )r   inputs_unitoutputs_unitr   r   r   _parameter_units_for_data_unitsJ   s    z*PowerLaw1D._parameter_units_for_data_unitsN)__name__
__module____qualname____doc__r   r   r   r   staticmethodr   r   propertyr   r"   r   r   r   r   r      s   


c               @   sd   e Zd ZdZeddZeddZeddZe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   )r   c             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   v   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 d| j jiS d S )Nr   )r*   r   )r   r   r   r   r      s    zBrokenPowerLaw1D.input_unitsc             C   s   t d|d fd|d fgS )Nr*   r   r   r   )r   )r   r    r!   r   r   r   r"      s    z0BrokenPowerLaw1D._parameter_units_for_data_unitsN)r#   r$   r%   r&   r   r   r*   r+   r,   r'   r   r   r(   r   r"   r   r   r   r   r	   O   s    



c               @   s   e Zd ZdZedddZeddZeddZeddZe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   )r   min)r      gMbP?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 )NgMbP?z delta parameter must be >= 0.001)r   r3   r   )r   r4   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S |S dS )z8One dimensional smoothly broken power law model functionF)ZsubokN   g       @g      ?)r   copy)
r   
zeros_like
isinstancer   r   r4   r   maxabsexp)r   r   r*   r+   r,   r5   r   fZreturn_unitlogt	thresholditrr   r   r   r     s,    
&
&
&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}| rt || }d| d }||| |   ||| |   ||< || | |	|< || ||| | d |   | |
|< || t ||  |t |   ||< || | t |  ||< || ||  t ||d|  | t ||    ||< |	|
|||gS )zZOne dimensional smoothly broken power law derivative with respect
           to parametersr6   g       @r2   g      ?)r   r   r8   r:   r;   r<   )r   r   r*   r+   r,   r5   r   r>   r=   r   r-   r.   r/   Zd_deltar?   r@   rA   rB   r   r   r   r   @  sH    






&* 

&* 
&(*<z"SmoothlyBrokenPowerLaw1D.fit_derivc             C   s    | j jd krd S d| j jiS d S )Nr   )r*   r   )r   r   r   r   r   y  s    z$SmoothlyBrokenPowerLaw1D.input_unitsc             C   s   t d|d fd|d fgS )Nr*   r   r   r   )r   )r   r    r!   r   r   r   r"     s    z8SmoothlyBrokenPowerLaw1D._parameter_units_for_data_unitsN)r#   r$   r%   r&   r   r   r*   r+   r,   r5   Z	validatorr'   r   r   r(   r   r"   r   r   r   r   r
      s   [


89c               @   sd   e Zd ZdZeddZeddZeddZe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   )r   c             C   s&   | | }|||   t |  |  S )z;One dimensional exponential cutoff power law model function)r   r<   )r   r   r   r   x_cutoffr   r   r   r   r     s    z$ExponentialCutoffPowerLaw1D.evaluatec             C   sj   | | }| | }||  t |  }|| | | }| | t | }	||  | |d  }
|||	|
gS )zROne dimensional exponential cutoff power law derivative with respect to parametersr2   )r   r<   r   )r   r   r   r   rC   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 d| j jiS d S )Nr   )r   r   )r   r   r   r   r     s    z'ExponentialCutoffPowerLaw1D.input_unitsc             C   s&   t d|d fd|d fd|d fgS )Nr   r   rC   r   r   )r   )r   r    r!   r   r   r   r"     s    
z;ExponentialCutoffPowerLaw1D._parameter_units_for_data_unitsN)r#   r$   r%   r&   r   r   r   r   rC   r'   r   r   r(   r   r"   r   r   r   r   r     s   



c               @   sd   e Zd ZdZeddZeddZeddZeddZe	dd Z
e	dd Zed	d
 Zdd ZdS )r   at  
    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   c             C   s(   | | }| |t |  }|||  S )z+One dimensional log parabola model function)r   r   )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 parametersr2   )r   r   )r   r   r   r   rD   r   Zlog_xxrE   r   Zd_betar   r   r   r   r   r     s    
zLogParabola1D.fit_derivc             C   s    | j jd krd S d| j jiS d S )Nr   )r   r   )r   r   r   r   r     s    zLogParabola1D.input_unitsc             C   s   t d|d fd|d fgS )Nr   r   r   r   )r   )r   r    r!   r   r   r   r"     s    z-LogParabola1D._parameter_units_for_data_unitsN)r#   r$   r%   r&   r   r   r   r   rD   r'   r   r   r(   r   r"   r   r   r   r   r     s   



)r&   collectionsr   Znumpyr   Zcorer   Z
parametersr   r   Zastropy.unitsr   __all__r   r	   r
   r   r   r   r   r   r   <module>   s   ;J mB