
    !g                      8    d dl Zd dlmZ d dlmZ  G d d      Zy)    N)mad)minimize_scalarc                   H    e Zd ZdZddZddZddZdddd	ifd
Zdd	ifdZy)BoxCoxz<
    Mixin class to allow for a Box-Cox transformation.
    Nc                 >   t        j                  |      }t        j                  |dk        rt        d      | | j                  |fd|i|}t        j
                  |d      rt        j                  |      }||fS t        j                  ||      dz
  |z  }||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.method              ?)npasarrayany
ValueError_est_lambdaiscloselogpower)selfxlmbdar   kwargsys         W/var/www/dash_apps/app1/venv/lib/python3.12/site-packages/statsmodels/base/transform.pytransform_boxcoxzBoxCox.transform_boxcox   s    R JJqM66!q&>.//=$D$$Q /,2/'-/E
 ::eR q	A %x !U#b(E1A%x    c                    |j                         }t        j                  |      }|dk(  rNt        j                  |d      rt        j                  |      }|S t        j
                  ||z  dz   d|z        }|S t        d| d      )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.
        naiver	      r
   Method '' not understood.)lowerr   r   r   expr   r   )r   r   r   r   r   s        r   untransform_boxcoxzBoxCox.untransform_boxcoxF   s    0 JJqMWzz%$FF1I 	 HHUQY]BJ7  xx/@ABBr   c                 >   |j                         }t        |      dk7  r#t        dj                  t        |                  |d   |d   k\  rt        d      |dk(  r | j                  |fd|i|}|S |dk(  r | j
                  |fd|i|}|S t        d	| d
      )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.
           z#Bounds of length {} not understood.r   r   z Lower bound exceeds upper bound.guerreroboundsloglikr   r   )r    lenr   format_guerrero_cv_loglik_boxcox)r   r   r&   r   r   r   s         r   r   zBoxCox._est_lambdak   s    6 v;!B$fS[13 3AY&)#?@@Z%D%%aAA&AE  x'D''C&CFCE  xx/@ABBr      sdmaxiter   c                    t        |      }t        ||z        }t        j                  ||||z  z
  | ||f      }t        j                  |d      |j                         }|dk(  rt        j                  |dd      n"|dk(  rt        |d      nt        d| d      fd}	t        |	|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-   ddofr   )axiszScale 'r   c                     t        j                  t        j                  d| z
              }t        j                  |d      t        j                  |      z  S )Nr   r1   )r   divider   stdmean)r   rat
dispersionr7   s     r   optimz"BoxCox._guerrero_cv.<locals>.optim   s@    ))Jq5y(ABC66#A&55r   boundedr&   r   options)r(   intr   reshaper7   r    r6   r   r   r   r   )r   r   r&   window_lengthscaler=   nobsgroupsgrouped_datar:   resr9   r7   s              @@r   r*   zBoxCox._guerrero_cv   s    4 1vTM)* zz!DF],B$CT"J#)="9;ww|Q'D=aa8Je^\2Jwug->?@@	6 e%+%.&-/ uur   c                      t        j                  t        j                              t               fd}t	        ||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                     j                  |       \  }} d| z
  z  dz  t        j                  t        j                  |            z  z   S )Nr   g       @)r   r   r   var)r   r   rB   r   sum_xr   s     r   r:   z$BoxCox._loglik_boxcox.<locals>.optim   sG    ,,Q6HAuI&$)rvvbffQi7H)HHHr   r;   r<   )r   sumr   r(   r   r   )r   r   r&   r=   r:   rE   rB   rI   s   ``    @@r   r+   zBoxCox._loglik_boxcox   sL     rvvay!1v	I e%+%.&-/ uur   )Nr%   )r   ))r$   r%   )	__name__
__module____qualname____doc__r   r"   r   r*   r+    r   r   r   r      s;    9v#J*X 56T'_2h 2;B r   r   )numpyr   statsmodels.robustr   scipy.optimizer   r   rP   r   r   <module>rT      s     " *\ \r   