
    M/Phv?              
       4   d Z ddlZddlmZ ddlmZ ddlmZ  G d de          Z	d Z
edk    rgd	 Zd
ZddgZddgZ ej        e          Zddgedd<    ej        e          Zded<    ej        eed          Z ej        eee          Z eedd                     ej        e          Zej                            e          Z ej        e          Z ej        eez            Z e ej        ej         edd         edd         edd         f         d                      ej        dgee          Z! ee!dd                     ej        e!          Z" ej        e          Z# ej        e"e#z            j$        Z% ee%dd                     eedd                     e ej        ej         e%dd         e%dd         e%dd         f         d                      ej        e          Z&ee&d e'e          <    ej        e          Z(ee(d e'e          <    ej        e&          Z) ej        e(          Z* ej        e*e)z  ez            Z+ ee+dd                     eedd                     e eee+                     ddgZddgZ e	g dddge          Z,eZ- ej.        dej/        e-          Z0 ej.        ddej/        z  e-          Z1ddl2m3Z4  e4j5        d            e4j6                     e,7                    d          \  Z8Z9 ee8j:                    e4j;        e8          Z< e4j=        d            e4j6                     e,>                    d          \  Z?Z1 ee?j:                    e4j;        e1e?          Z< e4j=        d             e4j6                     e,@                    d          \  ZAZB eeAj:                    e4j;        eBeA          Z< e4j=        d!            e4j6                     e,C                    d          ZD eeDj:                    e4j;        eD          Z< e4j=        d"            e4j6                     e,E                    e0          \  ZFZG eeFj:                    e4j;        e0eF            e4j=        d#            e4j6                      e
e,j        e0          ZH eeHj:                    e4j;        e0eH          Z< e4j=        d$            e4j6                     e,I                    e-          \  ZJZK eeKj:                    e4j;        e0eK          Z< e4j=        d%           d&ZLe,M                    eLd'z             eLd         ZddlNmOZP  e4j6                      ePjQ        e%          \  ZRZS ed(eRj:                   eRT                                ZR e4j;        eSeR            e4j=        d)           dd*lUmVZV  eVedd+          \  ZWZX e4j6                      ed,eXj:                    e4j;        eXT                                          Z< eeXdd                     e4j=        d-            e4j6                    ZYe,Z                    eY           dS dS ).a  
Created on Mon Dec 14 19:53:25 2009

Author: josef-pktd

generate arma sample using fft with all the lfilter it looks slow
to get the ma representation first

apply arma filter (in ar representation) to time series to get white noise
but seems slow to be useful for fast estimation for nobs=10000

change/check: instead of using marep, use fft-transform of ar and ma
    separately, use ratio check theory is correct and example works
    DONE : feels much faster than lfilter
    -> use for estimation of ARMA
    -> use pade (scipy.interpolate) approximation to get starting polynomial
       from autocorrelation (is autocorrelation of AR(p) related to marep?)
       check if pade is fast, not for larger arrays ?
       maybe pade does not do the right thing for this, not tried yet
       scipy.pade([ 1.    ,  0.6,  0.25, 0.125, 0.0625, 0.1],2)
       raises LinAlgError: singular matrix
       also does not have roots inside unit circle ??
    -> even without initialization, it might be fast for estimation
    -> how do I enforce stationarity and invertibility,
       need helper function

get function drop imag if close to zero from numpy/scipy source, where?

    N)signal)ArmaProcessc                        e Zd ZdZ fdZddZd ZddZd Zdd	Z	d
 Z
d Zd Zd Zd Zd ZddZd ZddZd dZd Zd!dZd"dZ xZS )#ArmaFfta  fft tools for arma processes

    This class contains several methods that are providing the same or similar
    returns to try out and test different implementations.

    Notes
    -----
    TODO:
    check whether we do not want to fix maxlags, and create new instance if
    maxlag changes. usage for different lengths of timeseries ?
    or fix frequency and length for fft

    check default frequencies w, terminology norw  n_or_w

    some ffts are currently done without padding with zeros

    returns for spectral density methods needs checking, is it always the power
    spectrum hw*hw.conj()

    normalization of the power spectrum, spectral density: not checked yet, for
    example no variance of underlying process is used

    c                    t                                          ||           t          j        |          | _        t          j        |          | _        || _        t          j                            |          | _	        t          j                            |          | _
        t          |          | _        t          |          | _        d S N)super__init__npasarrayarmanobs
polynomial
Polynomialarpolymapolylennarnma)selfr   r   n	__class__s       _/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/sandbox/tsa/fftarma.pyr
   zArmaFft.__init__C   s    R   *R..*R..	m..r22m..r22r77r77    Tc                     |r6t           j        |t          j        |t          |          z
            f         S t           j        t          j        |t          |          z
            |f         S )a  pad 1d array with zeros at end to have length maxlag
        function that is a method, no self used

        Parameters
        ----------
        arr : array_like, 1d
            array that will be padded with zeros
        maxlag : int
            length of array after padding
        atend : bool
            If True (default), then the zeros are added to the end, otherwise
            to the front of the array

        Returns
        -------
        arrp : ndarray
            zero-padded array

        Notes
        -----
        This is mainly written to extend coefficient arrays for the lag-polynomials.
        It returns a copy.

        )r   r_zerosr   )r   arrmaxlagatends       r   padarrzArmaFft.padarrP   sX    2  	95bhvc#hh777885&S/22C788r   c                     t           j        | j        t          j        || j        z
            f         }t           j        | j        t          j        || j        z
            f         }||fS )ab  construct AR and MA polynomials that are zero-padded to a common length

        Parameters
        ----------
        maxlag : int
            new length of lag-polynomials

        Returns
        -------
        ar : ndarray
            extended AR polynomial coefficients
        ma : ndarray
            extended AR polynomial coefficients

        )r   r   r   r   r   r   r   )r   r    arpadmapads       r   padzArmaFft.pado   sT      dgrxtx8889dgrxtx8889e|r   Nc                     |t          | j                  }t          j        |                     | j        |                    S )a  Fourier transform of AR polynomial, zero-padded at end to n

        Parameters
        ----------
        n : int
            length of array after zero-padding

        Returns
        -------
        fftar : ndarray
            fft of zero-padded ar polynomial
        )r   r   fftr"   r   r   s     r   fftarzArmaFft.fftar   6     9DGAwt{{47A..///r   c                     |t          | j                  }t          j        |                     | j        |                    S )a  Fourier transform of MA polynomial, zero-padded at end to n

        Parameters
        ----------
        n : int
            length of array after zero-padding

        Returns
        -------
        fftar : ndarray
            fft of zero-padded ar polynomial
        )r   r   r(   r"   r   r)   s     r   fftmazArmaFft.fftma   r+   r   c                 j    || j         }|                     |          |                     |          z  S )a  Fourier transform of ARMA polynomial, zero-padded at end to n

        The Fourier transform of the ARMA process is calculated as the ratio
        of the fft of the MA polynomial divided by the fft of the AR polynomial.

        Parameters
        ----------
        n : int
            length of array after zero-padding

        Returns
        -------
        fftarma : ndarray
            fft of zero-padded arma polynomial
        )r   r-   r*   r)   s     r   fftarmazArmaFft.fftarma   s/      9	A

1

1-.r   c                     |}t          j        d|z            dz  t          j        z  }|                     d|z            }||                                z  j        dz  t          j        z  |fS )zraw spectral density, returns Fourier transform

        n is number of points in positive spectrum, the actual number of points
        is twice as large. different from other spd methods with fft
                 ?)r(   fftfreqr   pir/   conjreal)r   nposr   whws        r   spdzArmaFft.spd   sc     K!q 25(\\!A#27799"S(250!33r   c                    |                      | j        |          }|                      | j        |          }t          j        t          j        |                    t          j        t          j        |                    z  }t          j        |          dz  t          j        z  }t          |dz  dz
  dd          }||	                                z  j
        |fS )zpower spectral density using fftshift

        currently returns two-sided according to fft frequencies, use first half
        r1      N)r"   r   r   r(   fftshiftr3   r   r4   slicer5   r6   )r   r   mapaddedarpaddedr9   r8   wslices          r   spdshiftzArmaFft.spdshift   s     ;;tw**;;tw**WS\(++,,sws|H7M7M/N/NNKNNQ&q!tAvtT**27799"A%%r   c                 .   t          j         | j        |          t          j         | j        |          z  }t          j        |          dz  t          j        z  }t          d|dz  d          }t	          j        |          dz  dz  t          j        z  |fS )zpower spectral density using padding to length n done by fft

        currently returns two-sided according to fft frequencies, use first half
        r1   Nr2   )r(   r   r   r3   r   r4   r>   abs)r   r   r9   r8   rA   s        r   	spddirectzArmaFft.spddirect   s{     WTWa  3747A#6#66KNNQ&tQT4((r

A$RU*A--r   c                    t          j         t          j        | j        ddd         | j        f         |          t          j         t          j        | j        ddd         | j        f         |          z  }||                                z  S )z/this looks bad, maybe with an fftshift
        N)r(   r   r   r   r   r5   r   r   r9   s      r   _spddirect2zArmaFft._spddirect2   so     gbeDGDDbDM$'12A66'"%"dg 56::;27799r   c                 D    |                      | j        | j        |          S )zspectral density for frequency using polynomial roots

        builds two arrays (number of roots, number of frequencies)
        )	_spdrootsarrootsmaroots)r   r8   s     r   spdrootszArmaFft.spdroots   s    
 ~~dlDL!<<<r   c                 z   t          j        |          j        }t          j        |          }d|z  }d|z  }d|dz  z   d|z  |z  z
  }d|dz  z   d|z  |z  z
  }dt           j        z  |                    d          z  |                    d          z  }t          j        |          |                                fS )a  spectral density for frequency using polynomial roots

        builds two arrays (number of roots, number of frequencies)

        Parameters
        ----------
        arroots : ndarray
            roots of ar (denominator) lag-polynomial
        maroots : ndarray
            roots of ma (numerator) lag-polynomial
        w : array_like
            frequencies for which spd is calculated

        Notes
        -----
        this should go into a function
              ?r<   r1   r2   rG   )r   
atleast_2dTcosr4   prodsqueeze)r   rL   rM   r8   coswnumdenr9   s           r   rK   zArmaFft._spdroots   s    $ M!vayyW*W*'1*nq'zD00'1*nq'zD0025[388B<<'#((2,,6z"~~qyy{{**r   2   c                     t           j                            |                     |                    } |t          j        d|z                      }t          j        ||                                z  dz  t           j        z            }||fS )zspectral density from MA polynomial representation for ARMA process

        References
        ----------
        Cochrane, section 8.3.3
                      ?r2   )r   r   r   arma2maexpreal_if_closer5   r4   )r   r8   r   mpolyr9   r:   s         r   spdpolyzArmaFft.spdpoly  sq     ((c):):;;U26"q&>>""rBGGII~3BE9::Avr   c                     |j         d         }|| j        k    r| j        }n+|                     |          |                     |          z  }|t	          j        |          z  }t	          j        |          S )aw  
        filter a timeseries with the ARMA filter

        padding with zero is missing, in example I needed the padding to get
        initial conditions identical to direct filter

        Initial filtered observations differ from filter2 and signal.lfilter, but
        at end they are the same.

        See Also
        --------
        tsa.filters.fftconvolve

        r   )shaper/   r-   r*   r(   ifft)r   xr   r/   tmpffts        r   filterzArmaFft.filter  se     GAJlGGjjmmdjjmm3G371::%xr   r   c                 "   ddl m} |snp|dk    r7|                     ||j        d         d| j        | j        z   z  z   d          }n3|                     ||j        d         t          |          z   d          } ||| j        | j                  S )a  filter a time series using fftconvolve3 with ARMA filter

        padding of x currently works only if x is 1d
        in example it produces same observations at beginning as lfilter even
        without padding.

        TODO: this returns 1 additional observation at the end
        r   )fftconvolve3autor1   F)r!   )	statsmodels.tsa.filtersrh   r"   rb   r   r   intr   r   )r   rd   r&   rh   s       r   filter2zArmaFft.filter20  s     	988888 	CF]]AqwqzAtx/@,AAOOAAAqwqzCHH4EBBA|Atw000r   d   c                 D   |*t          j        dt           j        |          dddf         }t          |          }dt           j        z  |d         d|dd         t          j        |t          j        d|          z            z                      d          z  z   z  }|S )z
        not really a method
        just for comparison, not efficient for large n or long acf

        this is also similarly use in tsa.stattools.periodogram with window
        Nr   r2   r1   r<   )r   linspacer4   r   rS   arangesum)r   acovfnfreqr8   nacr9   s         r   acf2spdfreqzArmaFft.acf2spdfreqE  s     9Arue,,QQQW5A%jj25[E!HqrrRVAbi#6F6F4F-G-G!G L LQ O OOP Q	r   c                     |                      |          }t          j        t          j        ||                                z            d          d|         S )a  autocovariance from spectral density

        scaling is correct, but n needs to be large for numerical accuracy
        maybe padding with zero in fft would be faster
        without slicing it returns 2-sided autocovariance with fftshift

        >>> ArmaFft([1, -0.5], [1., 0.4], 40).invpowerspd(2**8)[:10]
        array([ 2.08    ,  1.44    ,  0.72    ,  0.36    ,  0.18    ,  0.09    ,
                0.045   ,  0.0225  ,  0.01125 ,  0.005625])
        >>> ArmaFft([1, -0.5], [1., 0.4], 40).acovf(10)
        array([ 2.08    ,  1.44    ,  0.72    ,  0.36    ,  0.18    ,  0.09    ,
                0.045   ,  0.0225  ,  0.01125 ,  0.005625])
           )tolN)r/   r   r^   r(   rc   r5   rH   s      r   invpowerspdzArmaFft.invpowerspdS  sH     \\!__BGGII 6 6C@@@!DDr   Fc                     |%t          j        dt           j        t                    }dt           j        z  |                     t          j        |dz                      z  S )z9ma only, need division for ar, use LagPolynomial
        Nr   r2   r[   )r   ro   r4   rs   r   r]   )r   r8   twosideds      r   	spdmapolyzArmaFft.spdmapolyd  sG     9Arue,,ARU{T[["6666r      c                    |                      dd          }|                     |          d|         }|                     |          }t          j        dt          j        |          }|                     |          \  }	}
|ddlm}  |j	                    }|
                    ddd          }|                    |           |                    d| j         d	| j                    |
                    ddd          }|                    |           |                    d
| j         d	| j        d           |
                    ddd          }|                    |
|	           |                    d| j         d	| j                    |
                    ddd          }|                    |           |                    d| j         d	| j                    |S )zPlot resultsrm   i  )nsampleburninNr   r1   r<   zRandom Sample 
ar=z, ma=zAutocorrelation 
ar=s   zPower Spectrum 
ar=   zPartial Autocorrelation 
ar=)generate_sampleacfpacfr   ro   r4   rN   matplotlib.pyplotpyplotfigureadd_subplotplot	set_titler   r   )r   figr   nacfrs   rvsr   r   r8   spdrwrpltaxs                r   plot4zArmaFft.plot4l  s   ""3s";;hhtnnUdU#yyK25%((==##b;++++++#*,,C__Qq##

B47BBBBCCC__Qq##

GTWGG47GGGHHH__Qq##
D
CDGCC$'CCDDD__Qq##

LTWLL47LLMMM
r   )Tr   )rY   )r   )rm   N)F)Nrm   r}   rm   )__name__
__module____qualname____doc__r
   r"   r&   r*   r-   r/   r:   rB   rE   rI   rN   rK   r`   rf   rl   ru   ry   r|   r   __classcell__)r   s   @r   r   r   *   s{        0    9 9 9 9>  (0 0 0 0"0 0 0"/ / / /(
4 
4 
4& & &. . .  = = =+ + +:
 
 
 
     .1 1 1 1*   E E E"7 7 7 7       r   r   c                     t          j        |           dk    r| }n	| d          }dt           j        z  d||z  z   d|z  t          j        |          z  z
  z  S )Nr   r<   r2   r1   )r   ndimr4   rS   )r   r8   rhos      r   spdar1r     sV    	wr{{a!uf;SWq3w'::;;r   __main__c                 T    t          j        t          j        | |z
                      S r   )r   maxrD   )rd   ys     r   maxabsr     s    vbfQqSkk"""r   rw   r<   g        gr1   rP   same)mode
   )sizerG   )rowvarr}      gٿg?)r<   g      r   r   r   r   gffffffg333333?g?alli   zspd fft complexzspd fft shiftzspd fft directzspd fft direct mirroredzspd from rootszspd ar1periodogrami  i'  z	sdm.shape
matplotlib)	LD_AR_esti   zspdnt.shapenitime)[r   numpyr   	numpy.fftr(   scipyr   statsmodels.tsa.arima_processr   r   r   r   r   r   r   r   r   ar2uniconvolvearcomblfiltermarepprintmafrrandomnormalr   datafrrc   r   corrcoefc_arreparfryfrr6   rd   arcombpr   map_ar0frma0fry2arma1rs   ro   r4   r8   w2r   r   r   closer   r:   spd1w1rb   r   _titlerB   spd2rE   spd3w3rI   spd3brN   r   r   spdar1_r   wperspdperstartupr   matplotlib.mlabmlabmlbpsdsdmwmravelnitime.algorithmsr   wntspdntr   r    r   r   <module>r      s   <                 5 5 5 5 5 5] ] ] ] ]k ] ] ]J< < < z# # #D
SB
SB
"(4..C$iCG "(4..CCF R[Sv...FFN2fc**E	E%*375>>D
)



%
%CSWS\\FfA	E+"+beAabbE1QrT7AcrcF231
=
=
=>>>FNA3uc**E	E%*375>>D
#'!**CcA	E!BQB%LLL	E#bqb'NNN	E+"+beAabbE1QrT7AcrcF231
=
=
=>>> bhtnnG"GLSS[[L28D>>DD##b''NCGGECGDMME	%+f$	%	%B	E"SbS'NNN	E!CRC&MMM	E&&B-- TB
SBG111As8TBBEEArue$$A	Q"%	'	'B######CIeCJLLLyyHD"	E$*ACI   CJLLL~~e$$HD"	E$*TACIoCJLLLu%%HD"	E$*TACICJLLLe$$E	E%+ACI'(((CJLLL~~a  HD"	E$*CHQCICJLLLfUXq!!G	E'-GACIi CJLLL$$U++LD&	E&,FACImG



.
.wxx
8C!!!!!!CJLLLcgajjGC	E+sy!!!
))++CCHRCIl++++++3C((JCCJLLL	E-%%%A	E%*CIh
#*,,C	KKC r   