
    'YHhC'                         d Z ddlmZmZ ddlmZ ddlZddlZddl	Z
ddlmZ ddlmZ ddlmZ ddlmZ  G d	 d
      Zy)a  
Author: Kishan Manani
License: BSD-3 Clause

An implementation of MSTL [1], an algorithm for time series decomposition when
there are multiple seasonal components.

This implementation has the following differences with the original algorithm:
- Missing data must be handled outside of this class.
- The algorithm proposed in the paper handles a case when there is no
seasonality. This implementation assumes that there is at least one seasonal
component.

[1] K. Bandura, R.J. Hyndman, and C. Bergmeir (2021)
MSTL: A Seasonal-Trend Decomposition Algorithm for Time Series with Multiple
Seasonal Patterns
https://arxiv.org/pdf/2107.13462.pdf
    )OptionalUnion)SequenceN)boxcox)ArrayLike1D)STL)freq_to_periodc                      e Zd ZdZdddddddedeeeee   f      deeeee   f      deee	e
f      d	ed
eee
eeedf   f      fdZd Zd Zdeeee   df   deeee   df   deee   ee   f   fdZdeeee   df   dee   fdZdeeee   df   dedee   fdZdefdZedeee   ee   f   fd       Zed
edefd       Zededee   fd       Zed        Zy)MSTLa
  
    MSTL(endog, periods=None, windows=None, lmbda=None, iterate=2,
         stl_kwargs=None)

    Season-Trend decomposition using LOESS for multiple seasonalities.

    .. versionadded:: 0.14.0

    Parameters
    ----------
    endog : array_like
        Data to be decomposed. Must be squeezable to 1-d.
    periods : {int, array_like, None}, optional
        Periodicity of the seasonal components. If None and endog is a pandas
        Series or DataFrame, attempts to determine from endog. If endog is a
        ndarray, periods must be provided.
    windows : {int, array_like, None}, optional
        Length of the seasonal smoothers for each corresponding period.
        Must be an odd integer, and should normally be >= 7 (default). If None
        then default values determined using 7 + 4 * np.arange(1, n + 1, 1)
        where n is number of seasonal components.
    lmbda : {float, str, None}, optional
        The lambda parameter for the Box-Cox transform to be applied to `endog`
        prior to decomposition. If None, no transform is applied. If "auto", a
        value will be estimated that maximizes the log-likelihood function.
    iterate : int, optional
        Number of iterations to use to refine the seasonal component.
    stl_kwargs: dict, optional
        Arguments to pass to STL.

    See Also
    --------
    statsmodels.tsa.seasonal.STL

    References
    ----------
    .. [1] K. Bandura, R.J. Hyndman, and C. Bergmeir (2021)
        MSTL: A Seasonal-Trend Decomposition Algorithm for Time Series with
        Multiple Seasonal Patterns. arXiv preprint arXiv:2107.13462.

    Examples
    --------
    Start by creating a toy dataset with hourly frequency and multiple seasonal
    components.

    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> import pandas as pd
    >>> pd.plotting.register_matplotlib_converters()
    >>> np.random.seed(0)
    >>> t = np.arange(1, 1000)
    >>> trend = 0.0001 * t ** 2 + 100
    >>> daily_seasonality = 5 * np.sin(2 * np.pi * t / 24)
    >>> weekly_seasonality = 10 * np.sin(2 * np.pi * t / (24 * 7))
    >>> noise = np.random.randn(len(t))
    >>> y = trend + daily_seasonality + weekly_seasonality + noise
    >>> index = pd.date_range(start='2000-01-01', periods=len(t), freq='h')
    >>> data = pd.DataFrame(data=y, index=index)

    Use MSTL to decompose the time series into two seasonal components
    with periods 24 (daily seasonality) and 24*7 (weekly seasonality).

    >>> from statsmodels.tsa.seasonal import MSTL
    >>> res = MSTL(data, periods=(24, 24*7)).fit()
    >>> res.plot()
    >>> plt.tight_layout()
    >>> plt.show()

    .. plot:: plots/mstl_plot.py
    N   )periodswindowslmbdaiterate
stl_kwargsendogr   r   r   r   r   c                   || _         | j                  |      | _        | j                  j                  d   | _        || _        | j                  ||      \  | _        | _        || _	        | j                  |r|      | _        y i       | _        y )Nr   )r   _to_1d_array_yshapenobsr   _process_periods_and_windowsr   r   r   _remove_overloaded_stl_kwargs_stl_kwargs)selfr   r   r   r   r   r   s          Q/var/www/html/planif/env/lib/python3.12/site-packages/statsmodels/tsa/stl/mstl.py__init__zMSTL.__init__h   s     
##E*GGMM!$	
%)%F%FW&
"dl ==$J
*,
    c           	         t        | j                        }|dk(  rdn| j                  }| j                  dk(  r"t	        | j
                  d      \  }}|| _        n:| j                  r"t	        | j
                  | j                        }n| j
                  }| j                  j                  dd      }| j                  j                  dd      }t        j                  || j                  f      }|}t        |      D ]u  }	t        |      D ]e  }
|||
   z   }t        d|| j                  |
   | j                  |
   d| j                  j                  ||	      }|j                   ||
<   |||
   z
  }g w t        j"                  |j$                        }j&                  }|j(                  }||z
  }t+        | j,                  t.        j0                  t.        j2                  f      r| j,                  j4                  }t/        j0                  ||d
      }t/        j0                  ||d      }t/        j0                  ||d      }t/        j0                  ||d      }| j                  D cg c]  }d| 	 }}|j6                  dk(  rt/        j0                  ||d      }nt/        j2                  |||      }ddlm}  ||||||      S c c}w )z
        Estimate a trend component, multiple seasonal components, and a
        residual component.

        Returns
        -------
        DecomposeResult
            Estimation results.
           autoN)r   
inner_iter
outer_iter)r   r   periodseasonal)r"   r#   observed)indexnametrendresidrobust_weight	seasonal_r&   )r(   columnsr   )DecomposeResult )lenr   r   r   r   r   	est_lmbdar   popnpzerosr   ranger   r   fitr&   squeezeTr*   weights
isinstancer   pdSeries	DataFramer(   ndimstatsmodels.tsa.seasonalr/   )r   num_seasonsr   yr   stl_inner_iterstl_outer_iterr&   deseas_iresr*   rwr+   r(   r%   colsr/   s                      r   r7   zMSTL.fit~   sm    $,,'"a'!T\\ ::dggT2HAu"DNZZtwwdjj1AA ))--lDA))--lDA 88;		":;w 
	.A;' 	.(1+-  <<?!\\!_ &&	
 #N#K  "ll(1+-	.
	. ::hjj)		[[ djj299bll";<JJ$$E		!5z:AIIe5w?EIIe5w?E2UAB7;||DVix(DDD}}!99XUL<<tL 	=q(E5"== Es   'Kc           	      p    d| j                    d| j                   d| j                   d| j                   d	S )NzMSTL(endog, periods=z
, windows=z, lmbda=z
, iterate=))r   r   r   r   )r   s    r   __str__zMSTL.__str__   sF    ~ &~ &jj\ "~Q	(	
r   returnc                      j                  |      }|r2 j                  |t        |            } j                  ||      \  }}n' j                  |t        |            }t	        |      }t        |      t        |      k7  rt        d      t         fd|D              r<t        j                  dt               t         fd|D              }|d t        |       }||fS )N)rA   )Periods and windows must have same lengthc              3   B   K   | ]  }|j                   d z  k\    ywr   Nr   .0r%   r   s     r   	<genexpr>z4MSTL._process_periods_and_windows.<locals>.<genexpr>   s     =6vQ&=s   zTA period(s) is larger than half the length of time series. Removing these period(s).c              3   H   K   | ]  }|j                   d z  k  s|  ywrR   rS   rT   s     r   rV   z4MSTL._process_periods_and_windows.<locals>.<genexpr>   s%      !Q0Fs   "")_process_periods_process_windowsr1   _sort_periods_and_windowssorted
ValueErroranywarningswarnUserWarningtuple)r   r   r   s   `  r   r   z!MSTL._process_periods_and_windows   s    
 ''0++GW+NG#==gwOGW++GW+NGWoGw<3w<'HII =W==MM-.9  %, G nG-Gr   c                 \    || j                         f}|S t        |t              r|f}|S 	 |S N)_infer_periodr;   int)r   r   s     r   rX   zMSTL._process_periods   sE     ?))+-G
 	 %jG  r   rA   c                 \    || j                  |      }|S t        |t              r|f}|S 	 |S rc   )_default_seasonal_windowsr;   re   )r   r   rA   s      r   rY   zMSTL._process_windows   sD    
 ?44[AG
 	 %jG  r   c                     d }t        | j                  t        j                  t        j                  f      r!t        | j                  j                  dd       }|t        d      t        |      }|S )Ninferred_freqz%Unable to determine period from endog)	r;   r   r<   r=   r>   getattrr(   r\   r	   )r   freqr%   s      r   rd   zMSTL._infer_period   sZ    djj299bll";<4::++_dCD<DEE%r   c                     t        |       t        |      k7  rt        d      t        t        t        | |             \  } }| |fS )NrP   )r1   r\   zipr[   )r   r   s     r   rZ   zMSTL._sort_periods_and_windows  sF     w<3w<'HIIs7G'< =>r   c                 @    g d}|D ]  }| j                  |d         | S )Nr$   )r3   )r   argsargs      r   r   z"MSTL._remove_overloaded_stl_kwargs  s*    . 	&CNN3%	&r   nc                 @    t        d t        d| dz         D              S )Nc              3   ,   K   | ]  }d d|z  z     yw)      Nr0   )rU   rG   s     r   rV   z1MSTL._default_seasonal_windows.<locals>.<genexpr>  s     81QQY8s   r    )ra   r6   )rq   s    r   rg   zMSTL._default_seasonal_windows  s    8aQ888r   c                     t        j                  t        j                  t        j                  |             t         j                        }|j
                  dk7  rt        d      |S )N)dtyper    zy must be a 1d array)r4   ascontiguousarrayr8   asarraydoubler?   r\   )xrB   s     r   r   zMSTL._to_1d_array  sE      BJJqM!:"))L66Q;344r   )__name__
__module____qualname____doc__r   r   r   re   r   floatstrdictboolr   r7   rM   ra   r   rX   rY   rd   staticmethodrZ   r   rg   r   r0   r   r   r   r       s   EV 8<7;-1BF

 %Xc] 234	

 %Xc] 234
 eSj)*
 
 T#uS$_'="=>?
,>>@
 sHSM4/0  sHSM4/0  
x}hsm+	,	 <	S(3-56		#	sHSM4/0  
#	s   	x}hsm+	,    $ 4   9S 9Xc] 9 9  r   r   )r   typingr   r   collections.abcr   r^   numpyr4   pandasr<   scipy.statsr   statsmodels.tools.typingr   statsmodels.tsa.stl._stlr   statsmodels.tsa.tsatoolsr	   r   r0   r   r   <module>r      s3   $ # $     0 ( 3 r   