U
    mdlZ                     @  s  d dl mZ d dlmZ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mZ d dlmZ d d	lmZ d d
lmZmZmZmZ dddddddddddgZdFddZdGddZdHddZdId"d#d$d%d&d'd(dZdJd)dZ d*d Z!d+d Z"d,d- Z#d.d/ Z$d0d1 Z%d2d Z&d3d Z'd4d Z(d5d Z)d6d Z*d7d8 Z+d9d: Z,d;d< Z-d=d> Z.d?d@ Z/dAdB Z0dCd"dDdEdZ1dS )K    )annotations)lrangeLiteralN)	DataFrame)offsets)	to_offset)_is_recarray_is_using_pandas)ValueWarning)NDArray)
array_like	bool_likeint_likestring_likelagmat	lagmat2ds	add_trendduplication_matrixelimination_matrixcommutation_matrixvecvechunvecunvechfreq_to_periodcFskipc                 C  s  t |d}t|ddd}t|ddd}dddg}|d	kr@|  S |d
krZ|dd }d}nB|dksj|dkr|dd }|dkr|dd }d}n|dkrd}t| rddlm} t|t| d}|rt| t	j
rt	| } q|  } n
t| } t| }ttjd|d tjd|d }	t|	}	|dkr@|	dddf }	d
|krJ|rfdd }
| |
d}n0tjt| dd}|dk}|| d dk@ }|}t|rJ|dkr | jdkrd}nHt| jd | }t| t	jr| j}ddd |D }d| d}| d| d}t|n*|d krJ|dd }|	ddddf }	|rTdnd!}|rt	j|	| j|d"}	|	| g} t	j| dd| dd} n|	| g} t| dd| } | S )#a  
    Add a trend and/or constant to an array.

    Parameters
    ----------
    x : array_like
        Original array of data.
    trend : str {'n', 'c', 't', 'ct', 'ctt'}
        The trend to add.

        * 'n' add no trend.
        * 'c' add constant only.
        * 't' add trend only.
        * 'ct' add constant and linear trend.
        * 'ctt' add constant and linear and quadratic trend.
    prepend : bool
        If True, prepends the new data to the columns of X.
    has_constant : str {'raise', 'add', 'skip'}
        Controls what happens when trend is 'c' and a constant column already
        exists in x. 'raise' will raise an error. 'add' will add a column of
        1s. 'skip' will return the data without change. 'skip' is the default.

    Returns
    -------
    array_like
        The original data with the additional trend columns.  If x is a
        pandas Series or DataFrame, then the trend column names are 'const',
        'trend' and 'trend_squared'.

    See Also
    --------
    statsmodels.tools.tools.add_constant
        Add a constant column to an array.

    Notes
    -----
    Returns columns as ['ctt','ct','c'] whenever applicable. There is currently
    no checking for an existing trend.
    prependtrend)nr   tctcttoptionshas_constant)raiseaddr   constZtrend_squaredr   r   N   r   r!   r       r"   )recarray_exception)dtypec                 S  s2   zt | dkot | dkW S    Y dS X d S )Ng        F)npptpany)s r1   Q/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/tsa/tsatools.pysafe_is_const}   s    z add_trend.<locals>.safe_is_constaxisr&   zx is constant.z, c                 S  s   g | ]}t |qS r1   str.0r   r1   r1   r2   
<listcomp>   s     zadd_trend.<locals>.<listcomp>z3x contains one or more constant columns. Column(s) z are constant.z Adding a constant with trend='z' is not allowed.r   indexcolumns)r   r   copyr   statsmodels.tools.sm_exceptionsr+   NotImplementedErrorr	   
isinstancepdZSeriesr   r-   
asanyarraylenvanderarangeZfloat64Zfliplrapplyr.   r/   ndimshaper>   join
ValueErrorr=   concatcolumn_stack)xr   r   r%   r>   Z
trendorderr+   	is_pandasnobsZtrendarrr3   Z	col_constZptp0Zcol_is_constZnz_constZbase_errZ
const_colsmsgorderr1   r1   r2   r   &   s    (
  



 






r)   Tc           
      C  sV  t |d}t|d}t| ddd} |dkr.d}|dk rD| jd | }| jdkr^| dddf } | dd|f }|d	kr|d }nV|d
kr| jd }nB|dk r| jd | d }|| jd kr| jd }tdt |}t||dd}t	|}t	|| jd }	|r.||kr|
|| n|	
|	| t| |d|f || |d|	f fS )a  
    Returns an array with lags included given an array.

    Parameters
    ----------
    x : array_like
        An array or NumPy ndarray subclass. Can be either a 1d or 2d array with
        observations in columns.
    col : int or None
        `col` can be an int of the zero-based column index. If it's a
        1d array `col` can be None.
    lags : int
        The number of lags desired.
    drop : bool
        Whether to keep the contemporaneous variable for the data.
    insert : bool or int
        If True, inserts the lagged values after `col`. If False, appends
        the data. If int inserts the lags at int.

    Returns
    -------
    array : ndarray
        Array with lags

    Examples
    --------

    >>> import statsmodels.api as sm
    >>> data = sm.datasets.macrodata.load()
    >>> data = data.data[['year','quarter','realgdp','cpi']]
    >>> data = sm.tsa.add_lag(data, 'realgdp', lags=2)

    Notes
    -----
    Trims the array both forward and backward, so that the array returned
    so that the length of the returned array is len(`X`) - lags. The lags are
    returned in increasing order, ie., t-1,t-2,...,t-lags
    lagsdroprO   r*   )rI   Nr   r)   TFz<insert > number of variables, inserting at the last positionZBoth)trim)r   r   r   rJ   rI   warningswarnr
   r   r   popr=   r-   rN   )
rO   colrT   rU   insertZcontempZins_idxZndlagsZ
first_colsZ	last_colsr1   r1   r2   add_lag   s>    '





r\   c                 C  s   t |d}t |d}| jdkr2t|dkr2| j} n| jdkrDtd| jd }|dkrh| | jdd }n>tjt	t
||d d}tj|| }| t|| }| jdkrt|dkr|j}|S )	a  
    Detrend an array with a trend of given order along axis 0 or 1.

    Parameters
    ----------
    x : array_like, 1d or 2d
        Data, if 2d, then each row or column is independently detrended with
        the same trendorder, but independent trend estimates.
    order : int
        The polynomial order of the trend, zero is constant, one is
        linear trend, two is quadratic trend.
    axis : int
        Axis can be either 0, observations by rows, or 1, observations by
        columns.

    Returns
    -------
    ndarray
        The detrended series is the residual of the linear regression of the
        data on the trend of given order.
    rS   r5   r*   r)   z0x.ndim > 2 is not implemented until it is neededr   r4   )N)r   rI   intTrA   rJ   Zmeanr-   rF   rG   floatZlinalgZpinvdot)rO   rS   r5   rQ   ZresidZtrendsbetar1   r1   r2   detrend   s"    



rc   forwardexr^   z0Literal[('forward', 'backward', 'both', 'none')]zLiteral[('ex', 'sep', 'in')]boolzKNDArray | DataFrame | tuple[NDArray, NDArray] | tuple[DataFrame, DataFrame])maxlagrV   original
use_pandasreturnc                   sz  t |d}t|d}t|dddd}t|ddd	}| }t| d
ddd} t|doR|}|dkr`dn|}| }|r|dkrtdd}| j\}}	|dkr|	}||krtdt	|| |	|d  f}
t
dt|d D ]8}| |
|| || | |	||  |	|| d  f< q|dkr d}n|dkr0|}ntd|dkrLt|
}n|}|r.|} t| trdd | jD }tt|| jd krtdnt| jg}dd |D }t
|D ]*}t|d  | fdd|D  qt|
d| | j|d}
|
j|d }|dkr`|| }|j|dd}n2|
|||df }|d kr`|
||d|f }|d krr||fS |S dS )!a,	  
    Create 2d array of lags.

    Parameters
    ----------
    x : array_like
        Data; if 2d, observation in rows and variables in columns.
    maxlag : int
        All lags from zero to maxlag are included.
    trim : {'forward', 'backward', 'both', 'none', None}
        The trimming method to use.

        * 'forward' : trim invalid observations in front.
        * 'backward' : trim invalid initial observations.
        * 'both' : trim invalid observations on both sides.
        * 'none', None : no trimming of observations.
    original : {'ex','sep','in'}
        How the original is treated.

        * 'ex' : drops the original array returning only the lagged values.
        * 'in' : returns the original array and the lagged values as a single
          array.
        * 'sep' : returns a tuple (original array, lagged values). The original
                  array is truncated to have the same number of rows as
                  the returned lagmat.
    use_pandas : bool
        If true, returns a DataFrame when the input is a pandas
        Series or DataFrame.  If false, return numpy ndarrays.

    Returns
    -------
    lagmat : ndarray
        The array with lagged observations.
    y : ndarray, optional
        Only returned if original == 'sep'.

    Notes
    -----
    When using a pandas DataFrame or Series with use_pandas=True, trim can only
    be 'forward' or 'both' since it is not possible to consistently extend
    index values.

    Examples
    --------
    >>> from statsmodels.tsa.tsatools import lagmat
    >>> import numpy as np
    >>> X = np.arange(1,7).reshape(-1,2)
    >>> lagmat(X, maxlag=2, trim="forward", original='in')
    array([[ 1.,  2.,  0.,  0.,  0.,  0.],
       [ 3.,  4.,  1.,  2.,  0.,  0.],
       [ 5.,  6.,  3.,  4.,  1.,  2.]])

    >>> lagmat(X, maxlag=2, trim="backward", original='in')
    array([[ 5.,  6.,  3.,  4.,  1.,  2.],
       [ 0.,  0.,  5.,  6.,  3.,  4.],
       [ 0.,  0.,  0.,  0.,  5.,  6.]])

    >>> lagmat(X, maxlag=2, trim="both", original='in')
    array([[ 5.,  6.,  3.,  4.,  1.,  2.]])

    >>> lagmat(X, maxlag=2, trim="none", original='in')
    array([[ 1.,  2.,  0.,  0.,  0.,  0.],
       [ 3.,  4.,  1.,  2.,  0.,  0.],
       [ 5.,  6.,  3.,  4.,  1.,  2.],
       [ 0.,  0.,  5.,  6.,  3.,  4.],
       [ 0.,  0.,  0.,  0.,  5.,  6.]])
    rg   ri   rV   Trd   backwardbothnoneoptionalr$   rh   )re   sepinr#   rO   r*   N)rI   r,   rn   )rn   rl   zEtrim cannot be 'none' or 'backward' when used on Series or DataFramesr   )re   rq   zmaxlag should be < nobsr)   )rn   rd   )rl   rm   ztrim option not validc                 S  s   g | ]}t |qS r1   r6   r8   r1   r1   r2   r:     s     zlagmat.<locals>.<listcomp>zSColumns names must be distinct after conversion to string (if not already strings).c                 S  s   g | ]}t |qS r1   r6   r9   rZ   r1   r1   r2   r:     s     c                   s   g | ]}t |d    qS )z.L.r6   rs   Zlag_strr1   r2   r:     s     r<   )rq   re   r4   rq   )r   r   r   r   r	   lowerrL   rJ   r-   zerosranger^   rE   rB   r   r>   setr7   nameextendr=   ilocrU   )rO   rg   rV   rh   ri   origrP   ZdropidxrQ   nvarZlmkZstartobsZstopobsZ	x_columnsr>   ZlagrT   Zleadsr1   rt   r2   r   (  s    I


 

 






c              	   C  s  t |d}t |ddd}t|dddd}|dkr4|}t||}t| d}| jd	krt|rbt| } q| dddf } n| jd
ks| jdkrtd| j\}}	|r@|r@t	| j
ddd
f ||ddd}
|
j
ddd|d	 f g}td	|	D ]D}t	| j
dd|f ||ddd}
||
j
dd||d	 f  qtj|d	dS |rPt| } t	| ddd
f ||ddddd|d	 f g}td	|	D ]<}|t	| dd|f ||dddd||d	 f  qt|S )a  
    Generate lagmatrix for 2d array, columns arranged by variables.

    Parameters
    ----------
    x : array_like
        Data, 2d. Observations in rows and variables in columns.
    maxlag0 : int
        The first variable all lags from zero to maxlag are included.
    maxlagex : {None, int}
        The max lag for all other variables all lags from zero to maxlag are
        included.
    dropex : int
        Exclude first dropex lags from other variables. For all variables,
        except the first, lags from dropex to maxlagex are included.
    trim : str
        The trimming method to use.

        * 'forward' : trim invalid observations in front.
        * 'backward' : trim invalid initial observations.
        * 'both' : trim invalid observations on both sides.
        * 'none' : no trimming of observations.
    use_pandas : bool
        If true, returns a DataFrame when the input is a pandas
        Series or DataFrame.  If false, return numpy ndarrays.

    Returns
    -------
    ndarray
        The array with lagged observations, columns ordered by variable.

    Notes
    -----
    Inefficient implementation for unequal lags, implemented for convenience.
    maxlag0maxlagexT)rp   rV   rk   ro   Nr)   r   r*   z'Only supports 1 and 2-dimensional data.rr   )rV   rh   ri   r4   )rV   rh   )r   r   maxr	   rI   rC   r   rL   rJ   r   r{   rw   appendrM   r-   rD   rN   )rO   r   r   ZdropexrV   ri   rg   rP   rQ   r}   rT   Zlagslir~   r1   r1   r2   r     sd    &




        "
.  c                 C  s
   |  dS )NF)ravelmatr1   r1   r2   r     s    c                 C  s   | j tt| S N)r_   take_triu_indicesrE   r   r1   r1   r2   r     s    c                 C  s   t | \}}||  | S r   )r-   Ztril_indicesr   rowscolsr1   r1   r2   _tril_indices"  s    r   c                 C  s   t | \}}||  | S r   )r-   triu_indicesr   r1   r1   r2   r   '  s    r   c                 C  s   t | \}}||  | S r   )r-   diag_indicesr   r1   r1   r2   _diag_indices,  s    r   c                 C  s8   t tt| }|| t| ks&t| j||fddS )Nr   rS   )r^   r-   sqrtrE   AssertionErrorreshape)vr~   r1   r1   r2   r   1  s    c                 C  sl   ddt ddt|     }tt |}t ||f}| |t |< ||j }|t |  d  < |S )Ng      ?r;   r)      r*   )	r-   r   rE   r^   roundrv   r   r_   r   )r   r   resultr1   r1   r2   r   7  s    
c                 C  s6   t | d} t| | d  d }tdd |D jS )z
    Create duplication matrix D_n which satisfies vec(S) = D_n vech(S) for
    symmetric matrix S

    Returns
    -------
    D_n : ndarray
    r   r)   r*   c                 S  s   g | ]}t | qS r1   )r   r   )r9   rO   r1   r1   r2   r:   Q  s     z&duplication_matrix.<locals>.<listcomp>)r   r-   eyearrayr_   )r   tmpr1   r1   r2   r   F  s    	
c                 C  s8   t | d} ttt| | f}t| |  |dk S )z
    Create the elimination matrix L_n which satisfies vech(M) = L_n vec(M) for
    any matrix M

    Parameters
    ----------

    Returns
    -------
    r   r   )r   r   r-   ZtrilZonesr   )r   Zvech_indicesr1   r1   r2   r   T  s    
c                 C  sP   t | d} t |d}t| | }t| | j| |fdd}|j| ddS )z
    Create the commutation matrix K_{p,q} satisfying vec(A') = K_{p,q} vec(A)

    Parameters
    ----------
    p : int
    q : int

    Returns
    -------
    K : ndarray (pq x pq)
    pqr   r   r   r4   )r   r-   r   rG   r   r   r   )r   r   Kindicesr1   r1   r2   r   d  s
    

c              	   C  s~   t | d }t | d }tdt| D ]N}|| }t|D ]$}||  |||| d   8  < q>|d| |d|< q*|S )z
    Transforms params to induce stationarity/invertability.

    Parameters
    ----------
    params : array_like
        The AR coefficients

    Reference
    ---------
    Jones(1980)
    r*   r)   N)r-   tanhrw   rE   )params	newparamsr   jakiterr1   r1   r2   _ar_transparamsy  s    "r   c                 C  s   |   } |   }tt| d ddD ]Z}| | }t|D ]0}| | || || d    d|d   ||< q8|d| | d|< q$dt|  }|S )z
    Inverse of the Jones reparameterization

    Parameters
    ----------
    params : array_like
        The transformed AR coefficients
    r)   r   r;   r*   N)r?   rw   rE   r-   Zarctanh)r   r   r   r   r   Z
invarcoefsr1   r1   r2   _ar_invtransparams  s    	

r   c              	   C  s   dt |   dt |     }dt |   dt |     }tdt| D ]N}|| }t|D ]$}||  |||| d   7  < qj|d| |d|< qV|S )z
    Transforms params to induce stationarity/invertability.

    Parameters
    ----------
    params : ndarray
        The ma coeffecients of an (AR)MA model.

    Reference
    ---------
    Jones(1980)
    r)   N)r-   expr?   rw   rE   )r   r   r   r   br   r1   r1   r2   _ma_transparams  s    $$"r   c                 C  s   |   }tt| d ddD ]Z}| | }t|D ]0}| | || || d    d|d   ||< q0|d| | d|< qtd|  d|    }|S )z
    Inverse of the Jones reparameterization

    Parameters
    ----------
    params : ndarray
        The transformed MA coefficients
    r)   r   r;   r*   N)r?   rw   rE   r-   log)Zmacoefsr   r   r   r   Z
invmacoefsr1   r1   r2   _ma_invtransparams  s    	

r   c                   s8   t  d d  t fddt ddD S )a  
    Returns the successive differences needed to unintegrate the series.

    Parameters
    ----------
    x : array_like
        The original series
    d : int
        The number of differences of the differenced series.

    Returns
    -------
    y : array_like
        The increasing differences from 0 to d-1 of the first d elements
        of x.

    See Also
    --------
    unintegrate
    dNc                   s    g | ]}t  | d  qS )r   )r-   diff)r9   ir   rO   r1   r2   r:     s     z&unintegrate_levels.<locals>.<listcomp>r   r;   )r   r-   Zasarrayrw   )rO   r   r1   r   r2   unintegrate_levels  s    
r   c                 C  s\   t |dd }t|dkr@|d}tttj|| f |S |d }ttj|| f S )ay  
    After taking n-differences of a series, return the original series

    Parameters
    ----------
    x : array_like
        The n-th differenced series
    levels : list
        A list of the first-value in each differenced series, for
        [first-difference, second-difference, ..., n-th difference]

    Returns
    -------
    y : array_like
        The original series de-differenced

    Examples
    --------
    >>> x = np.array([1, 3, 9., 19, 8.])
    >>> levels = unintegrate_levels(x, 2)
    >>> levels
    array([ 1.,  2.])
    >>> unintegrate(np.diff(x, 2), levels)
    array([  1.,   3.,   9.,  19.,   8.])
    Nr)   r;   r   )listrE   rY   unintegrater-   ZcumsumZr_)rO   ZlevelsZx0r1   r1   r2   r     s    
r   zstr | offsets.DateOffset)freqrj   c                 C  s   t | tjst| } t | tjs$t| j } | dks@| drDdS | dksV| drZdS | dksl| drpd	S | d
ks| drdS | dkrdS | dkrdS | dkrdS td	| dS )a$  
    Convert a pandas frequency to a periodicity

    Parameters
    ----------
    freq : str or offset
        Frequency to convert

    Returns
    -------
    int
        Periodicity of freq

    Notes
    -----
    Annual maps to 1, quarterly maps to 4, monthly to 12, weekly to 52.
    A)zA-zAS-r)   Q)zQ-zQS-   M)zM-ZMS   WzW-4   D   B   H   zDfreq {} not understood. Please report if you think this is in error.N)
rB   r   Z
DateOffsetr   r   Z	rule_codeupper
startswithrL   format)r   r1   r1   r2   r     s.    
)r   Fr   )Nr)   FT)r)   r   )rd   re   F)Nr   rd   F)2
__future__r   Zstatsmodels.compat.pythonr   r   rW   numpyr-   ZpandasrC   r   Zpandas.tseriesr   Zpandas.tseries.frequenciesr   Zstatsmodels.tools.datar   r	   r@   r
   Zstatsmodels.tools.typingr   Zstatsmodels.tools.validationr   r   r   r   __all__r   r\   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r1   r1   r2   <module>   sl   
 
P
1           
W"