U
    Ãmœd-   ã                   @   s2   d dl Zd dlmZ d dlmZ G dd„ dƒZdS )é    N)Úmad)Úminimize_scalarc                   @   sR   e Zd ZdZddd„Zddd„Zdd
d„Zddddifdd„Zddifdd„ZdS )ÚBoxCoxz<
    Mixin class to allow for a Box-Cox transformation.
    NÚguerreroc                 K   sr   t  |¡}t  |dk¡r tdƒ‚|dkr>| j|fd|i|—Ž}t  |d¡rVt  |¡}nt  ||¡d | }||fS )a„  
        Performs a Box-Cox transformation on the data array x. If lmbda is None,
        the indicated method is used to estimate a suitable lambda parameter.

        Parameters
        ----------
        x : array_like
        lmbda : float
            The lambda parameter for the Box-Cox transform. If None, a value
            will be estimated by means of the specified method.
        method : {'guerrero', 'loglik'}
            The method to estimate the lambda parameter. Will only be used if
            lmbda is None, and defaults to 'guerrero', detailed in Guerrero
            (1993). 'loglik' maximizes the profile likelihood.
        **kwargs
            Options for the specified method.
            * For 'guerrero', this entails window_length, the grouping
              parameter, scale, the dispersion measure, and options, to be
              passed to the optimizer.
            * For 'loglik': options, to be passed to the optimizer.

        Returns
        -------
        y : array_like
            The transformed series.
        lmbda : float
            The lmbda parameter used to transform the series.

        References
        ----------
        Guerrero, Victor M. 1993. "Time-series analysis supported by power
        transformations". `Journal of Forecasting`. 12 (1): 37-48.

        Guerrero, Victor M. and Perera, Rafael. 2004. "Variance Stabilizing
        Power Transformation for Time Series," `Journal of Modern Applied
        Statistical Methods`. 3 (2): 357-369.

        Box, G. E. P., and D. R. Cox. 1964. "An Analysis of Transformations".
        `Journal of the Royal Statistical Society`. 26 (2): 211-252.
        r   zNon-positive x.NÚmethodç        ç      ð?)ÚnpÚasarrayÚanyÚ
ValueErrorÚ_est_lambdaÚiscloseÚlogÚpower)ÚselfÚxÚlmbdar   ÚkwargsÚy© r   úS/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/base/transform.pyÚtransform_boxcox   s    )

ÿþzBoxCox.transform_boxcoxÚnaivec                 C   s^   |  ¡ }t |¡}|dkrLt |d¡r2t |¡}qZt || d d| ¡}ntd |¡ƒ‚|S )a  
        Back-transforms the Box-Cox transformed data array, by means of the
        indicated method. The provided argument lmbda should be the lambda
        parameter that was used to initially transform the data.

        Parameters
        ----------
        x : array_like
            The transformed series.
        lmbda : float
            The lambda parameter that was used to transform the series.
        method : {'naive'}
            Indicates the method to be used in the untransformation. Defaults
            to 'naive', which reverses the transformation.

            NOTE: 'naive' is implemented natively, while other methods may be
            available in subclasses!

        Returns
        -------
        y : array_like
            The untransformed series.
        r   r   é   r   úMethod '{0}' not understood.)Úlowerr	   r
   r   Úexpr   r   Úformat)r   r   r   r   r   r   r   r   Úuntransform_boxcoxF   s    
zBoxCox.untransform_boxcox©éÿÿÿÿé   c                 K   s’   |  ¡ }t|ƒdkr(td t|ƒ¡ƒ‚n|d |d kr@tdƒ‚|dkr`| j|fd|i|—Ž}n.|dkr€| j|fd|i|—Ž}ntd	 |¡ƒ‚|S )
aÎ  
        Computes an estimate for the lambda parameter in the Box-Cox
        transformation using method.

        Parameters
        ----------
        x : array_like
            The untransformed data.
        bounds : tuple
            Numeric 2-tuple, that indicate the solution space for the lambda
            parameter. Default (-1, 2).
        method : {'guerrero', 'loglik'}
            The method by which to estimate lambda. Defaults to 'guerrero', but
            the profile likelihood ('loglik') is also available.
        **kwargs
            Options for the specified method.
            * For 'guerrero': window_length (int), the seasonality/grouping
              parameter. Scale ({'mad', 'sd'}), the dispersion measure. Options
              (dict), to be passed to the optimizer.
            * For 'loglik': Options (dict), to be passed to the optimizer.

        Returns
        -------
        lmbda : float
            The lambda parameter.
        r"   z$Bounds of length {0} not understood.r   r   z Lower bound exceeds upper bound.r   ÚboundsZloglikr   )r   Úlenr   r   Ú_guerrero_cvÚ_loglik_boxcox)r   r   r#   r   r   r   r   r   r   r   k   s    ÿzBoxCox._est_lambdaé   ÚsdÚmaxiteré   c                    sª   t |ƒ}t|| ƒ}t ||||  |… ||f¡}t |d¡‰| ¡ }|dkrbtj|ddd�‰ n$|dkrxt|dd�‰ ntd 	|¡ƒ‚‡ ‡fdd„}	t
|	|d	|d
�}
|
jS )aß  
        Computes lambda using guerrero's coefficient of variation. If no
        seasonality is present in the data, window_length is set to 4 (as
        per Guerrero and Perera, (2004)).

        NOTE: Seasonality-specific auxiliaries *should* provide their own
        seasonality parameter.

        Parameters
        ----------
        x : array_like
        bounds : tuple
            Numeric 2-tuple, that indicate the solution space for the lambda
            parameter.
        window_length : int
            Seasonality/grouping parameter. Default 4, as per Guerrero and
            Perera (2004). NOTE: this indicates the length of the individual
            groups, not the total number of groups!
        scale : {'sd', 'mad'}
            The dispersion measure to be used. 'sd' indicates the sample
            standard deviation, but the more robust 'mad' is also available.
        options : dict
            The options (as a dict) to be passed to the optimizer.
        r   r(   ©Zddofr   )ZaxiszScale '{0}' not understood.c                    s0   t  ˆ t  ˆd|  ¡¡}t j|dd�t  |¡ S )Nr   r+   )r	   Údivider   ÚstdÚmean)r   Úrat©Z
dispersionr.   r   r   ÚoptimÁ   s    z"BoxCox._guerrero_cv.<locals>.optimÚbounded©r#   r   Úoptions)r$   Úintr	   Zreshaper.   r   r-   r   r   r   r   r   )r   r   r#   Zwindow_lengthÚscaler4   ÚnobsÚgroupsZgrouped_datar1   Úresr   r0   r   r%   —   s&    ÿýzBoxCox._guerrero_cvc                    s@   t  t  ˆ¡¡‰tˆƒ‰ ‡ ‡‡‡fdd„}t||d|d�}|jS )a~  
        Taken from the Stata manual on Box-Cox regressions, where this is the
        special case of 'lhs only'. As an estimator for the variance, the
        sample variance is used, by means of the well-known formula.

        Parameters
        ----------
        x : array_like
        options : dict
            The options (as a dict) to be passed to the optimizer.
        c                    s4   ˆ  ˆ| ¡\}} d|  ˆ ˆ d t t |¡¡  S )Nr   g       @)r   r	   r   Úvar)r   r   ©r7   r   Zsum_xr   r   r   r1   Ú   s    z$BoxCox._loglik_boxcox.<locals>.optimr2   r3   )r	   Úsumr   r$   r   r   )r   r   r#   r4   r1   r9   r   r;   r   r&   Ë   s    ýzBoxCox._loglik_boxcox)Nr   )r   )r    r   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r%   r&   r   r   r   r   r      s   
;
%
,ÿ
4r   )Únumpyr	   Zstatsmodels.robustr   Zscipy.optimizer   r   r   r   r   r   Ú<module>   s   