U
    ÃmœdM  ã                   @   s,  d Z ddlZddlmZ ddlmZ dd„ Zd-dd	„Zd.d
d„Z	d/dd„Z
d0dd„Zdd„ Zdd„ ZG dd„ dƒZG dd„ dƒZedk�r(e ddgddggddgddggg¡Ze ddgddggddgddggg¡Ze ddgddggddgddggg¡Ze ddgddggddgddggddgddggg¡Zeje d ¡ddd…dd…f d!e d ¡ddd…dd…f  f Ze dddgdddgdddggd!ddgdd"dgddd#ggg¡Zej d$d%¡Ze	eeƒZejjeedƒed&d'�Z e d  !dd%d%¡Z"ee"ƒZ#eeƒZ$e$ %d¡ e$ &¡  e$ &d(¡d)d…  e ddgddggddgddggddgddggg¡Z'e ddgddggd*dgdd+ggg¡Z(e ddgddggd,dgd*dggd+dgddggg¡Z)ee'e(ƒZ*e+e,e*ƒƒ e+e* -¡ ƒ e+e* -e¡ƒ e+e* .¡ ƒ e+e* /¡ ƒ e+e* 0¡ ƒ ee)ƒZ1e+e1 /¡ ƒ e+e1 0¡ ƒ dS )1a9   Helper and filter functions for VAR and VARMA, and basic VAR class

Created on Mon Jan 11 11:04:23 2010
Author: josef-pktd
License: BSD

This is a new version, I did not look at the old version again, but similar
ideas.

not copied/cleaned yet:
 * fftn based filtering, creating samples with fft
 * Tests: I ran examples but did not convert them to tests
   examples look good for parameter estimate and forecast, and filter functions

main TODOs:
* result statistics
* see whether Bayesian dummy observation can be included without changing
  the single call to linalg.lstsq
* impulse response function does not treat correlation, see Hamilton and jplv

Extensions
* constraints, Bayesian priors/penalization
* Error Correction Form and Cointegration
* Factor Models Stock-Watson,  ???


see also VAR section in Notes.txt

é    N)Úsignal)Úlagmatc           	      C   sb  t  | ¡} t  |¡}| jdkr.| dd…df } | jdkr@tdƒ‚| jd }|jd }|d }|jdkr‚tj| |dd…df dd�S |jdk�rt|jƒdkr¬tj| |dd�S t  | jd | d |f¡}t	|ƒD ]8}tj| dd…|f |dd…|f dd�|dd…|f< qÐ|S |jdk�r^t | dd…dd…df |¡}||| …|jd d dd…f }|S dS )	a¸  apply an autoregressive filter to a series x

    Warning: I just found out that convolve does not work as I
       thought, this likely does not work correctly for
       nvars>3


    x can be 2d, a can be 1d, 2d, or 3d

    Parameters
    ----------
    x : array_like
        data array, 1d or 2d, if 2d then observations in rows
    a : array_like
        autoregressive filter coefficients, ar lag polynomial
        see Notes

    Returns
    -------
    y : ndarray, 2d
        filtered array, number of columns determined by x and a

    Notes
    -----

    In general form this uses the linear filter ::

        y = a(L)x

    where
    x : nobs, nvars
    a : nlags, nvars, npoly

    Depending on the shape and dimension of a this uses different
    Lag polynomial arrays

    case 1 : a is 1d or (nlags,1)
        one lag polynomial is applied to all variables (columns of x)
    case 2 : a is 2d, (nlags, nvars)
        each series is independently filtered with its own
        lag polynomial, uses loop over nvar
    case 3 : a is 3d, (nlags, nvars, npoly)
        the ith column of the output array is given by the linear filter
        defined by the 2d array a[:,:,i], i.e. ::

            y[:,i] = a(.,.,i)(L) * x
            y[t,i] = sum_p sum_j a(p,j,i)*x(t-p,j)
                     for p = 0,...nlags-1, j = 0,...nvars-1,
                     for all t >= nlags


    Note: maybe convert to axis=1, Not

    TODO: initial conditions

    é   Né   zx array has to be 1d or 2dr   Zvalid)Úmodeé   )
ÚnpZasarrayÚndimÚ
ValueErrorÚshaper   ZconvolveÚminÚzerosÚrange)	ÚxÚaÚnvarÚnlagsZntrimÚresultÚiZyfZyvalid© r   úV/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/tsa/varma_process.pyÚ	varfilter%   s,    9






6"r   r   c           
      C   sP  | j \}}}||krtdƒ t |d ||f¡}| d |ddd…dd…f< | dd…  |d|…dd…dd…f< |dkrêtd|d ƒD ]d}t ||f¡}td|ƒD ]0}	|t | |	  |||	 dd…dd…f ¡7 }q |||dd…dd…f< q„|dk�rLt|d |d ƒD ]D}t| dd… j ||d || d…dd…dd…f j ƒ tdƒ‚�q|S )aý  creates inverse ar filter (MA representation) recursively

    The VAR lag polynomial is defined by ::

        ar(L) y_t = u_t  or
        y_t = -ar_{-1}(L) y_{t-1} + u_t

    the returned lagpolynomial is arinv(L)=ar^{-1}(L) in ::

        y_t = arinv(L) u_t



    Parameters
    ----------
    ar : ndarray, (nlags,nvars,nvars)
        matrix lagpolynomial, currently no exog
        first row should be identity

    Returns
    -------
    arinv : ndarray, (nobs,nvars,nvars)


    Notes
    -----

    ú.exogenous variables not implemented not testedr   r   Nr   éÿÿÿÿz+waiting for generalized ufuncs or something)r   Úprintr   r   r   ÚdotÚNotImplementedError)
ÚarÚnobsÚversionr   ÚnvarsÚnvarsexZarinvr   ÚtmpÚpr   r   r   Úvarinversefilter„   s"    $.
6r$   c                 C   sþ   | j \}}}|d }|j d }||kr.tdƒ |j d |krDtdƒ‚|dkrdt || |f¡}|}	n8t||j d ƒ}	t ||	 |f¡}|||	|j d  |	…< |||	d…< t|	|	| ƒD ]B}
td|ƒD ]2}||
  t ||
| dd…f | |  ¡7  < qÄq¶|S )aE  generate an VAR process with errors u

    similar to gauss
    uses loop

    Parameters
    ----------
    ar : array (nlags,nvars,nvars)
        matrix lagpolynomial
    u : array (nobs,nvars)
        exogenous variable, error term for VAR

    Returns
    -------
    sar : array (1+nobs,nvars)
        sample of var process, inverse filtered u
        does not trim initial condition y_0 = 0

    Examples
    --------
    # generate random sample of VAR
    nobs, nvars = 10, 2
    u = numpy.random.randn(nobs,nvars)
    a21 = np.array([[[ 1. ,  0. ],
                     [ 0. ,  1. ]],

                    [[-0.8,  0. ],
                     [ 0.,  -0.6]]])
    vargenerate(a21,u)

    # Impulse Response to an initial shock to the first variable
    imp = np.zeros((nobs, nvars))
    imp[0,0] = 1
    vargenerate(a21,imp)

    r   r   r   zu needs to have nvars columnsN)r   r   r
   r   r   Úmaxr   r   )r   ÚuÚ
initvaluesr   r    r!   Znlagsm1r   ZsarÚstartr   r#   r   r   r   Úvargenerate¸   s$    %
2r)   c           	         sˆ   t  | j¡}||  || 7  < t  | j¡}t  |¡}| |¡ t  | j¡‰|ˆ|< ˆ| ‰ ‡ ‡fdd„ttˆ ƒƒD ƒ}| |t	|ƒ< |S )aÅ  pad with zeros along one axis, currently only axis=0


    can be used sequentially to pad several axis

    Examples
    --------
    >>> padone(np.ones((2,3)),1,3,axis=1)
    array([[ 0.,  1.,  1.,  1.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  0.,  0.,  0.]])

    >>> padone(np.ones((2,3)),1,1, fillvalue=np.nan)
    array([[ NaN,  NaN,  NaN],
           [  1.,   1.,   1.],
           [  1.,   1.,   1.],
           [ NaN,  NaN,  NaN]])
    c                    s   g | ]}t ˆ| ˆ | ƒ‘qS r   ©Úslice©Ú.0Úk©ZendindZstartindr   r   Ú
<listcomp>  s     zpadone.<locals>.<listcomp>)
r   Úarrayr   ÚemptyÚfillr   r	   r   ÚlenÚtuple)	r   ÚfrontÚbackÚaxisÚ	fillvaluer   ÚshapearrÚoutÚmyslicer   r/   r   Úpadoneõ   s    

r=   c                    sp   t  | j¡}||  || 8  < t  | j¡}t  | j¡‰|ˆ|< ˆ| ‰ ‡ ‡fdd„ttˆ ƒƒD ƒ}| t|ƒ S )a;  trim number of array elements along one axis


    Examples
    --------
    >>> xp = padone(np.ones((2,3)),1,3,axis=1)
    >>> xp
    array([[ 0.,  1.,  1.,  1.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  0.,  0.,  0.]])
    >>> trimone(xp,1,3,1)
    array([[ 1.,  1.,  1.],
           [ 1.,  1.,  1.]])
    c                    s   g | ]}t ˆ| ˆ | ƒ‘qS r   r*   r,   r/   r   r   r0   -  s     ztrimone.<locals>.<listcomp>)r   r1   r   r   r	   r   r4   r5   )r   r6   r7   r8   r   r:   r<   r   r/   r   Útrimone  s    r>   c                 C   s6   | j \}}}tjt ||¡ddd…dd…f |  f S )z?make reduced lagpolynomial into a right side lagpoly array
    N)r   r   Úr_Úeye)r   r   r   Znvarexr   r   r   Úar2full4  s    rA   c                 C   s   | dd…  S )z�convert full (rhs) lagpolynomial into a reduced, left side lagpoly array

    this is mainly a reminder about the definition
    r   Nr   )r   r   r   r   Úar2lhs;  s    rB   c                   @   s:   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zddd„ZdS )Ú_Vara<  obsolete VAR class, use tsa.VAR instead, for internal use only


    Examples
    --------

    >>> v = Var(ar2s)
    >>> v.fit(1)
    >>> v.arhat
    array([[[ 1.        ,  0.        ],
            [ 0.        ,  1.        ]],

           [[-0.77784898,  0.01726193],
            [ 0.10733009, -0.78665335]]])

    c                 C   s   || _ |j\| _| _d S )N)Úyr   r   r    )ÚselfrD   r   r   r   Ú__init__U  s    z_Var.__init__c                 C   sž   || _ | j}t| j|ddd�}|dd…d|…f | _|dd…|d…f | _tjj| j| jdd�}|| _	|d  
|||¡| _t| jƒ| _|d | _|d	 | _dS )
a«  estimate parameters using ols

        Parameters
        ----------
        nlags : int
            number of lags to include in regression, same for all variables

        Returns
        -------
        None, but attaches

        arhat : array (nlags, nvar, nvar)
            full lag polynomial array
        arlhs : array (nlags-1, nvar, nvar)
            reduced lag polynomial for left hand side
        other statistics as returned by linalg.lstsq : need to be completed



        This currently assumes all parameters are estimated without restrictions.
        In this case SUR is identical to OLS

        estimation results are attached to the class instance


        ZbothÚin)ZtrimÚoriginalNr   ©Zrcondr   r   r   )r   r    r   rD   ZyredÚxredr   ÚlinalgÚlstsqZ
estresultsÚreshapeZarlhsrA   ÚarhatÚrssZxredrank)rE   r   r    ZlmatÚresr   r   r   ÚfitY  s    
z_Var.fitc                 C   s    t | dƒst| j| jƒ| _| jS )z:calculate estimated timeseries (yhat) for sample

        Úyhat)Úhasattrr   rD   rN   rR   ©rE   r   r   r   Úpredict‚  s    
z_Var.predictc                 C   sF   | j dddd…f tj t | jj| j¡¡dd…dd…df  | _dS )aÔ   covariance matrix of estimate
        # not sure it's correct, need to check orientation everywhere
        # looks ok, display needs getting used to
        >>> v.rss[None,None,:]*np.linalg.inv(np.dot(v.xred.T,v.xred))[:,:,None]
        array([[[ 0.37247445,  0.32210609],
                [ 0.1002642 ,  0.08670584]],

               [[ 0.1002642 ,  0.08670584],
                [ 0.45903637,  0.39696255]]])
        >>>
        >>> v.rss[0]*np.linalg.inv(np.dot(v.xred.T,v.xred))
        array([[ 0.37247445,  0.1002642 ],
               [ 0.1002642 ,  0.45903637]])
        >>> v.rss[1]*np.linalg.inv(np.dot(v.xred.T,v.xred))
        array([[ 0.32210609,  0.08670584],
               [ 0.08670584,  0.39696255]])
       N)rO   r   rK   Úinvr   rJ   ÚTZparamcovrT   r   r   r   Úcovmat‹  s    *ÿz_Var.covmatr   Nc                 C   s*   |dkrt  || jf¡}t| j|| jd�S )a£  calculates forcast for horiz number of periods at end of sample

        Parameters
        ----------
        horiz : int (optional, default=1)
            forecast horizon
        u : array (horiz, nvars)
            error term for forecast periods. If None, then u is zero.

        Returns
        -------
        yforecast : array (nobs+horiz, nvars)
            this includes the sample and the forecasts
        N)r'   )r   r   r    r)   rN   rD   )rE   Zhorizr&   r   r   r   Úforecast¢  s    z_Var.forecast)r   N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__rF   rQ   rU   rX   rY   r   r   r   r   rC   C  s   )	rC   c                   @   sd   e Zd ZdZddd„Zddd„Zddd	„Zddd„Zdd„ Zdd„ Z	ddd„Z
ddd„Zdd„ ZdS )Ú	VarmaPolya¼  class to keep track of Varma polynomial format


    Examples
    --------

    ar23 = np.array([[[ 1. ,  0. ],
                     [ 0. ,  1. ]],

                    [[-0.6,  0. ],
                     [ 0.2, -0.6]],

                    [[-0.1,  0. ],
                     [ 0.1, -0.1]]])

    ma22 = np.array([[[ 1. ,  0. ],
                     [ 0. ,  1. ]],

                    [[ 0.4,  0. ],
                     [ 0.2, 0.3]]])


    Nc                 C   s¶   || _ || _|j\}}}|||  | _| _| _|dd |…f t |¡k ¡  | _	| jd krrt |¡d | _d| _
n|d t |¡k ¡  | _
|jd | _||k| _|dd …  | _d S )Nr   )N.Tr   )r   Úmar   r   Únvarallr    r   r@   ÚallÚisstructuredÚisindependentZmalagsZhasexogZarm1)rE   r   r_   r   r`   r    r   r   r   rF   Î  s    "

zVarmaPoly.__init__r   c                 C   sD   |dk	r|}n(|dkr| j }n|dkr.| j}ntdƒ‚| d| j¡S )z4stack lagpolynomial vertically in 2d array

        Nr   r_   úno array or name givenr   )r   r_   r
   rM   r`   ©rE   r   Únamer   r   r   ÚvstackÞ  s    zVarmaPoly.vstackc                 C   sN   |dk	r|}n(|dkr| j }n|dkr.| j}ntdƒ‚| dd¡ d| j¡jS )z6stack lagpolynomial horizontally in 2d array

        Nr   r_   rd   r   r   r   )r   r_   r
   ÚswapaxesrM   r`   rW   re   r   r   r   Úhstackí  s    zVarmaPoly.hstackÚverticalc                 C   st   |dk	r|}n(|dkr| j }n|dkr.| j}ntdƒ‚| d| j¡}|j\}}tj||d�}||dd…d|…f< |S )zDstack lagpolynomial vertically in 2d square array with eye

        Nr   r_   rd   r   )r.   )r   r_   r
   rM   r`   r   r   r@   )rE   r   rf   ZorientationZastackedZlenpkr    Úamatr   r   r   Ústacksquareü  s    
zVarmaPoly.stacksquarec                 C   s2   t  | jdd… | jdd… fd¡}| d| j¡S )z;stack ar and lagpolynomial vertically in 2d array

        r   Nr   r   )r   Úconcatenater   r_   rM   r`   ©rE   r   r   r   r   Úvstackarma_minus1  s    $zVarmaPoly.vstackarma_minus1c                 C   s:   t  | jdd… | jdd… fd¡}| dd¡ d| j¡S )zustack ar and lagpolynomial vertically in 2d array

        this is the Kalman Filter representation, I think
        r   Nr   r   r   )r   rm   r   r_   rh   rM   r`   rn   r   r   r   Úhstackarma_minus1  s    $zVarmaPoly.hstackarma_minus1c                 C   sz   |dk	r|}n.| j r,|  | j¡dd…  }n| jdd…  }|  |¡}t tj |¡¡ddd… }|| _t 	|¡dk  
¡ S )a>  check whether the auto-regressive lag-polynomial is stationary

        Returns
        -------
        isstationary : bool

        *attaches*

        areigenvalues : complex array
            eigenvalues sorted by absolute value

        References
        ----------
        formula taken from NAG manual

        Nr   r   )rb   Ú
reduceformr   rl   r   ÚsortrK   ÚeigvalsZareigenvaluesÚabsra   ©rE   r   rk   Zevr   r   r   Úgetisstationary  s    
zVarmaPoly.getisstationaryc                 C   s˜   |dk	r|}n*| j r*|  | j¡dd… }n| jdd… }|jd dkrZt g tj¡| _dS |  |¡}t 	tj
 |¡¡ddd… }|| _t |¡dk  ¡ S )a>  check whether the auto-regressive lag-polynomial is stationary

        Returns
        -------
        isinvertible : bool

        *attaches*

        maeigenvalues : complex array
            eigenvalues sorted by absolute value

        References
        ----------
        formula taken from NAG manual

        Nr   r   Tr   )rc   rq   r_   r   r   r1   ÚcomplexZmaeigenvaluesrl   rr   rK   rs   rt   ra   ru   r   r   r   Úgetisinvertible<  s    
zVarmaPoly.getisinvertiblec                 C   s”   |j dkrtdƒ‚|j\}}}t |¡}z"tj |dd|…dd…f ¡}W n" tjjk
rl   tddƒ‚Y nX t|ƒD ]}t 	||| ¡||< qv|S )z.

        this assumes no exog, todo

        r   zapoly needs to be 3dr   Nzmatrix not invertiblezask for implementation of pinv)
r	   r
   r   r   Z
empty_likerK   rV   ZLinAlgErrorr   r   )rE   Zapolyr   r!   r    r   Za0invZlagr   r   r   rq   ^  s    

"ÿ
zVarmaPoly.reduceform)N)Nr   )Nr   )Nr   rj   )N)N)rZ   r[   r\   r]   rF   rg   ri   rl   ro   rp   rv   rx   rq   r   r   r   r   r^   ¶  s   





"r^   Ú__main__g      ð?g        gš™™™™™é¿g333333ã¿gš™™™™™¹?gš™™™™™É?gš™™™™™¹¿r   gš™™™™™é?g333333ã?gÍÌÌÌÌÌì?iè  r   r   rI   é   iâÿÿÿgš™™™™™Ù?g333333Ó?gffffffþ¿)r   )N)r   r   r   r   )r   r   r   )2r]   Únumpyr   Zscipyr   Zstatsmodels.tsa.tsatoolsr   r   r$   r)   r=   r>   rA   rB   rC   r^   rZ   r1   Za21Za22Za23Za24r?   r@   Za31Za32ÚrandomZrandnÚutZar2srK   rL   rP   rM   ZbhatrN   ÚvrQ   rY   Zar23Zma22Zar23nsZvpr   Úvarsrg   rp   rv   rx   Zvp2r   r   r   r   Ú<module>   sÊ   _
4
=
#
s @

ÿÿý
ÿÿý
ÿÿý
ÿÿÿú	Bþþü	


ÿÿÿú	
ÿÿý
ÿÿÿú	
