
    M/PhL                        d Z ddlZddlmZ ddlmZ d Zd*dZd+dZ	d,d	Z
d-d
Zd Zd Z G d d          Z G d d          Zedk    r ej        ddgddggddgddggg          Z ej        ddgddggddgddggg          Z ej        ddgddggddgddggg          Z ej        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j        d          dddddf         d ej        d          dddddf         z  f         Z ej        g dg dg dgg dg dg d gg          Zej                            d!d"          Z e	ee          Zej                             eed          ed#$          Z e d         !                    dd"d"          Z" ee"          Z# ee          Z$e$%                    d           e$&                                 e$&                    d%          d&d           ej        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        ddgddggd'dgdd(ggg          Z( ej        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)          Z1 e+e1/                                            e+e10                                           dS dS ).a9   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                 6   t          j        |           } t          j        |          }| j        dk    r| dddf         } | j        dk    rt          d          | j        d         }|j        d         }|dz  }|j        dk    r!t          j        | |dddf         d          S |j        dk    rt          |j                  dk    rt          j        | |d          S t          j        | j        d         |z
  dz   |f          }t          |          D ]4}t          j        | dd|f         |dd|f         d          |dd|f<   5|S |j        dk    rBt          j        | dddddf         |          }||| |j        d         dz  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   valid)mode   )
npasarrayndim
ValueErrorshaper   convolveminzerosrange)	xanvarnlagsntrimresultiyfyvalids	            ]/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/tsa/varma_process.py	varfilterr   $   s   r 	
1A

1Av{{aaafIvzz566671:DGAJE1HE 	v{{q!AAAdF)':::: 
1qw<<1?1ag6666
 171:e+A-t455t 	H 	HA /!AAAaC&!AAAaC&wGGGF111Q3KK	
1 _Qqqq4x[!,,E5&L"(1+q.23 
    r   c                    | j         \  }}}||k    rt          d           t          j        |dz   ||f          }| d         |dddddf<   | dd          |d|ddddf<   |dk    rzt	          d|dz             D ]f}t          j        ||f          }t	          d|          D ]1}	|t          j        | |	          |||	z
  ddddf                   z  }2|||ddddf<   g|dk    r_t	          |dz   |dz             D ]H}t          | dd         j         ||dz
  ||z
  dddddf         j                    t          d          |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nvarsexarinvr   tmpps
             r   varinversefilterr.      s   : HE5'>???Hd1fgu-..Ea5E!AAAaaa%LQRR&E!E'!!!AAA+!||qa 	 	A(E%=))C1U^^ 5 5rvr!ufU1Q3qqq7^444E!AAAaaa%LL!||uQwtAv&& 	U 	UA"QRR&,ac!E'"nQQQqqq&8 9 ?@@@ &&STTTLr   c                 F   | j         \  }}}|dz
  }|j         d         }||k    rt          d           |j         d         |k    rt          d          |t          j        ||z   |f          }|}	nIt          ||j         d                   }	t          j        ||	z   |f          }|||	|j         d         z
  |	<   |||	d<   t          |	|	|z             D ]L}
t          d|          D ]9}||
xx         t          j        ||
|z
  ddf         | |                    z  cc<   :M|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*   nlagsm1r'   sarstartr   r-   s               r   vargenerater6      sX   J HE5'aiG71:D>???wqzU8999hWe,--GZ-a011hU
E*++/9E*"1%%e+,CK5t$$ 0 0q 	0 	0AFFFbfS1QQQZA///FFFF	0 Jr   c                   	
 t          j        | j                  }||xx         ||z   z  cc<   t          j        | j                  }t          j        |          }|                    |           t          j        | j                  
|
|<   
|z   		
f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                 H    g | ]}t          |         |                   S  slice.0kendindstartinds     r   
<listcomp>zpadone.<locals>.<listcomp>  +    IIIuXa[&),,IIIr   )
r   arrayr   emptyfillr   r   r   lentuple)r   frontbackaxis	fillvaluer   shapearroutmyslicer?   r@   s            @@r   padonerO      s    & HQWE	$KKKEDL!KKKx  H
(5//CHHYxHHTN FIIIIIeCKK6H6HIIIG CgJr   c                 R   t          j        | j                  }||xx         ||z   z  cc<   t          j        | j                  }t          j        | j                  ||<   |z   f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                 H    g | ]}t          |         |                   S r9   r:   r<   s     r   rA   ztrimone.<locals>.<listcomp>,  rB   r   )r   rC   r   r   r   r   rF   rG   )	r   rH   rI   rJ   r   rL   rN   r?   r@   s	          @@r   trimonerR     s     HQWE	$KKKEDL!KKKx  HxHHTNFIIIIIeCKK6H6HIIIG U7^^r   c                     | j         \  }}}t          j        t          j        ||          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   nvarexs       r   ar2fullrW   3  sE     E45V$$T!!!AAAX.s233r   c                     | dd          S )zconvert full (rhs) lagpolynomial into a reduced, left side lagpoly array

    this is mainly a reminder about the definition
    r   Nr9   )r&   s    r   ar2lhsrY   :  s    
 qrrF7Nr   c                   2    e Zd ZdZd Zd Zd Zd Z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                 <    || _         |j        \  | _        | _        d S N)yr   r'   r)   )selfr^   s     r   __init__z_Var.__init__T  s     !	4:::r   c                    || _         | j        }t          | j        |dd          }|ddd|f         | _        |dd|df         | _        t          j                            | j        | j        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


        bothin)trimoriginalNr"   rcondr   r   r   )r   r)   r   r^   yredxredr   linalglstsq
estresultsreshapearlhsrW   arhatrssxredrank)r_   r   r)   lmatress        r   fitz_Var.fitX  s    6 

 dfe&4@@@6E6N	566N	ioodi"o==V^^E5%88
TZ((
q6Ar   c                 n    t          | d          st          | j        | j                  | _        | j        S )z:calculate estimated timeseries (yhat) for sample

        yhat)hasattrr   r^   ro   rv   r_   s    r   predictz_Var.predict  s3    
 tV$$ 	6!$&$*55DIyr   c                     | j         ddddf         t          j                            t          j        | j        j        | j                            dddddf         z  | _        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)rp   r   rj   invr$   ri   Tparamcovrx   s    r   covmatz_Var.covmat  s\    ( $tAAA+.IMM"&di8899!!!AAAd(CDr   r   Nc                 t    |t          j        || j        f          }t          | j        || j                  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)r2   )r   r   r)   r6   ro   r^   )r_   horizr1   s      r   forecastz_Var.forecast  s8     9%,--A4:qTV<<<<r   )r   N)	__name__
__module____qualname____doc__r`   rt   ry   r~   r   r9   r   r   r[   r[   B  sr         "( ( (' ' 'R  E E E.= = = = = =r   r[   c                   T    e Zd ZdZddZddZddZddZd	 Zd
 Z	ddZ
ddZ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                    || _         || _        |j        \  }}}|||c| _        | _        | _        |dd |f         t          j        |          k                                     | _	        | j        't          j        |          d         | _        d| _
        n6|d         t          j        |          k                                     | _
        |j        d         | _        ||k    | _        |dd           | _        d S )Nr   )N.Tr   )r&   mar   r   nvarallr)   r   rU   allisstructuredisindependentmalagshasexogarm1)r_   r&   r   r   r   r)   s         r   r`   zVarmaPoly.__init__  s     "w/4gu,
DL$*!#AfufH!> C C E EE7?fUmmH-DG!%D&(erve}}&<%A%A%C%C!CDhqkVG			r   r&   c                     ||}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   r_   r   names      r   vstackzVarmaPoly.vstack  sY     =AAT\\AAT\\AA5666yyT\***r   c                     ||}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   r   r   r   r"   )r&   r   r   swapaxesrm   r   r|   r   s      r   hstackzVarmaPoly.hstack  sj     =AAT\\AAT\\AA5666zz!A&&r4<88::r   verticalc                     ||}n+|dk    r| j         }n|dk    r| j        }nt          d          |                    d| j                  }|j        \  }}t          j        ||          }||ddd|f<   |S )zDstack lagpolynomial vertically in 2d square array with eye

        Nr&   r   r   r"   )r>   )r&   r   r   rm   r   r   r   rU   )r_   r   r   orientationastackedlenpkr)   amats           r   stacksquarezVarmaPoly.stacksquare  s     =AAT\\AAT\\AA566699R..~uveu%%%!QQQvvXr   c                     t          j        | 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   r_   r   s     r   vstackarma_minus1zVarmaPoly.vstackarma_minus1  sD     NDGABBK5a88yyT\***r   c                     t          j        | 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   r   r&   r   r   rm   r   r   s     r   hstackarma_minus1zVarmaPoly.hstackarma_minus1  sR    
 NDGABBK5a88zz!A&&r4<888r   c                    ||}n;| j         r$|                     | j                  dd          }n| j        dd          }|                     |          }t	          j        t          j                            |                    ddd         }|| _        t	          j	        |          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"   )r   
reduceformr&   r   r   sortrj   eigvalsareigenvaluesabsr   r_   r   r   evs       r   getisstationaryzVarmaPoly.getisstationary  s    " =AA  !__TW--abb11WQRR[L""WRY&&t,,--ddd3r

Q##%%%r   c                    ||}n9| j         r#|                     | j                  dd         }n| j        dd         }|j        d         dk    r&t	          j        g t          j                  | _        dS |                     |          }t	          j	        t          j
                            |                    ddd         }|| _        t	          j        |          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"   )r   r   r   r   r   rC   complexmaeigenvaluesr   r   rj   r   r   r   r   s       r   getisinvertiblezVarmaPoly.getisinvertible;  s    " =AA!  OODG,,QRR0GABBK71:??!#"bj!9!9D4""WRY&&t,,--ddd3r

Q##%%%r   c                    |j         dk    rt          d          |j        \  }}}t          j        |          }	 t          j                            |dd|ddf                   }n(# t          j        j        $ r t          dd          w xY wt          |          D ] }t          j	        |||                   ||<   !|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   
empty_likerj   r{   LinAlgErrorr   r$   )r_   apolyr   r*   r)   r   a0invlags           r   r   zVarmaPoly.reduceform]  s     :??3444 %wM%  	?IMM!AfufaaaK.11EEy$ 	? 	? 	?4=? ? ?	? << 	/ 	/CVE5:..AcFFs   ,A( (%Br]   )Nr&   )Nr&   r   )r   r   r   r   r`   r   r   r   r   r   r   r   r   r9   r   r   r   r     s         .    + + + +; ; ; ;   &+ + +9 9 9& & & &: &  &  &  &D    r   r   __main__      ?        gg333333皙?g?gr
   皙?)r   r   r   )r   r   r   )r   r   r   )r   r   r   )r   g333333?r   )r   r   g?i  r   r"   rf      ig?g333333?gffffff)r   r]   )r   r   r   r   )r   r   r   )2r   numpyr   scipyr   statsmodels.tsa.tsatoolsr   r   r.   r6   rO   rR   rW   rY   r[   r   r   rC   a21a22a23a24rT   rU   a31a32randomrandnutar2srj   rk   rs   rm   bhatro   vrt   r   ar23ma22ar23nsvpr#   varsr   r   r   r   vp2r9   r   r   <module>r      s   :           + + + + + +\ \ \~1 1 1 1h: : : :z       F   84 4 4  p= p= p= p= p= p= p= p=f| | | | | | | |~ z
"(rR\R\# R\D\#$ % %C "(rR\R\# R\D\#$ % %C "(rR\R\# S\D\#$ % %C "(rR\R\# R\D\# R\D\#$ % %C %q		$qqq(#S4!!!8)<%<<
=C
"(''''''''') ('''''''')	* + +C 
a	 	 B;s2D
)//&&a..$b/
9
9Cq6>>!Aa  DGDMME 	T

AEE!HHHJJLLLJJrNN34428blR\# R\D\# R\D\#$ % %D 28blR\# R\C["# $ $D RX"R\# R\D\# R\D\#$ % %F 
4		B	E$$r((OOO	E"))++	E"))C..	E"


 
 !!!	E"



	E"




)F

C	E#



   	E#



     m r   