a
    ߙfb@A                     @   s   d Z ddlZddlmZ ddlmZ ddlmZm	Z	 g d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)Quantity   )Fittable1DModel)	ParameterInputParameterError)
PowerLaw1DBrokenPowerLaw1DSmoothlyBrokenPowerLaw1DExponentialCutoffPowerLaw1DLogParabola1Dc                   @   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   9lib/python3.9/site-packages/astropy/modeling/powerlaws.pyevaluate.   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_deriv4   s
    
zPowerLaw1D.fit_derivc                 C   s"   | j jd u rd S | jd | j jiS Nr   r   unitinputsselfr   r   r   input_units@   s    zPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dS Nr   )r   r   r#   Zoutputsr%   Zinputs_unitZoutputs_unitr   r   r   _parameter_units_for_data_unitsF   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   


r   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   r   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   r5   r   )r   r   r6   r7   r8   r   r   r   	d_x_breakr   	d_alpha_1	d_alpha_2r   r   r   r   z   s    
zBrokenPowerLaw1D.fit_derivc                 C   s"   | j jd u rd S | jd | j jiS r    r6   r"   r#   r$   r   r   r   r&      s    zBrokenPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dS Nr   )r6   r   r(   r)   r   r   r   r*      s    z0BrokenPowerLaw1D._parameter_units_for_data_unitsN)r+   r,   r-   r.   r   r   r6   r7   r8   r/   r   r   r0   r&   r*   r   r   r   r   r   K   s   !


r   c                   @   s   e Zd ZdZe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   r1   )r   minr   r2   r   r3      r4   MbP?zSmoothness Parameterc                 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 )NrA   z delta parameter must be >= 0.001rB   rD   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 )z8One dimensional smoothly broken power law model functionF)ZsubokN          @      ?)r"   copy)
r   
zeros_like
isinstancer   r"   rE   r   maxabsexp)r   r   r6   r7   r8   rF   r   fZreturn_unitlogt	thresholditrr   r   r   r     s8    


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 parametersrG   rH   r@   rI   )r   r   rK   rM   rN   rO   )r   r   r6   r7   r8   rF   r   rQ   rP   r   r9   r:   r;   Zd_deltarR   rS   rT   rU   r   r   r   r   :  sX    






* 

* 
(*&z"SmoothlyBrokenPowerLaw1D.fit_derivc                 C   s"   | j jd u rd S | jd | j jiS r    r<   r$   r   r   r   r&   s  s    z$SmoothlyBrokenPowerLaw1D.input_unitsc                 C   s   || j d  || jd  dS r=   r(   r)   r   r   r   r*   y  s    z8SmoothlyBrokenPowerLaw1D._parameter_units_for_data_unitsN)r+   r,   r-   r.   r   r   r6   r7   r8   rF   Z	validatorr/   r   r   r0   r&   r*   r   r   r   r   r	      s"   \


6
8
r	   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   rO   )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 parametersr@   )r   rO   r   )r   r   r   r   rW   r   Zxcr   r   r   Z
d_x_cutoffr   r   r   r     s    z%ExponentialCutoffPowerLaw1D.fit_derivc                 C   s"   | j jd u 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   rW   r   r(   r)   r   r   r   r*     s    z;ExponentialCutoffPowerLaw1D._parameter_units_for_data_unitsN)r+   r,   r-   r.   r   r   r   r   rW   r/   r   r   r0   r&   r*   r   r   r   r   r
   ~  s   


r
   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   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   rV   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 parametersr@   r   )r   r   r   r   rX   r   Zlog_xxrY   r   Zd_betar   r   r   r   r   r     s    
zLogParabola1D.fit_derivc                 C   s"   | j jd u 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   r*     s    z-LogParabola1D._parameter_units_for_data_unitsN)r+   r,   r-   r.   r   r   r   r   rX   r/   r   r   r0   r&   r*   r   r   r   r   r     s   


r   )r.   Znumpyr   Zastropy.unitsr   corer   
parametersr   r   __all__r   r   r	   r
   r   r   r   r   r   <module>   s   :I kA