
    M/Ph                     @    d Z ddlZddlZddlmZ  G d d          ZdS )zZ
State Space Representation - Initialization

Author: Chad Fulton
License: Simplified-BSD
    N   )toolsc                       e Zd ZdZ	 	 	 ddZe	 	 dd            Zed             Zd Zd Z		 	 dd	Z
d
 Zd Zed             Z	 	 	 ddZdS )Initializationa0  
    State space initialization

    Parameters
    ----------
    k_states : int
    exact_diffuse_initialization : bool, optional
        Whether or not to use exact diffuse initialization; only has an effect
        if some states are initialized as diffuse. Default is True.
    approximate_diffuse_variance : float, optional
        If using approximate diffuse initialization, the initial variance used.
        Default is 1e6.

    Notes
    -----
    As developed in Durbin and Koopman (2012), the state space recursions
    must be initialized for the first time period. The general form of this
    initialization is:

    .. math::

        \alpha_1 & = a + A \delta + R_0 \eta_0 \\
        \delta & \sim N(0, \kappa I), \kappa \to \infty \\
        \eta_0 & \sim N(0, Q_0)

    Thus the state vector can be initialized with a known constant part
    (elements of :math:`a`), with part modeled as a diffuse initial
    distribution (as a part of :math:`\delta`), and with a part modeled as a
    known (proper) initial distribution (as a part of :math:`\eta_0`).

    There are two important restrictions:

    1. An element of the state vector initialized as diffuse cannot be also
       modeled with a stationary component. In the `validate` method,
       violations of this cause an exception to be raised.
    2. If an element of the state vector is initialized with both a known
       constant part and with a diffuse initial distribution, the effect of
       the diffuse initialization will essentially ignore the given known
       constant value. In the `validate` method, violations of this cause a
       warning to be given, since it is not technically invalid but may
       indicate user error.

    The :math:`\eta_0` compoenent is also referred to as the stationary part
    because it is often set to the unconditional distribution of a stationary
    process.

    Initialization is specified for blocks (consecutive only, for now) of the
    state vector, with the entire state vector and individual elements as
    special cases. Denote the block in question as :math:`\alpha_1^{(i)}`. It
    can be initialized in the following ways:

    - 'known'
    - 'diffuse' or 'exact_diffuse' or 'approximate_diffuse'
    - 'stationary'
    - 'mixed'

    In the first three cases, the block's initialization is specified as an
    instance of the `Initialization` class, with the `initialization_type`
    attribute set to one of those three string values. In the 'mixed' cases,
    the initialization is also an instance of the `Initialization` class, but
    it will itself contain sub-blocks. Details of each type follow.

    Regardless of the type, for each block, the following must be defined:
    the `constant` array, an array `diffuse` with indices corresponding to
    diffuse elements, an array `stationary` with indices corresponding to
    stationary elements, and `stationary_cov`, a matrix with order equal to the
    number of stationary elements in the block.

    **Known**

    If a block is initialized as known, then a known (possibly degenerate)
    distribution is used; in particular, the block of states is understood to
    be distributed
    :math:`\alpha_1^{(i)} \sim N(a^{(i)}, Q_0^{(i)})`. Here, is is possible to
    set :math:`a^{(i)} = 0`, and it is also possible that
    :math:`Q_0^{(i)}` is only positive-semidefinite; i.e.
    :math:`\alpha_1^{(i)}` may be degenerate. One particular example is
    that if the entire block's initial values are known, then
    :math:`R_0^{(i)} = 0`, and so `Var(\alpha_1^{(i)}) = 0`.

    Here, `constant` must be provided (although it can be zeros), and
    `stationary_cov` is optional (by default it is a matrix of zeros).

    **Diffuse**

    If a block is initialized as diffuse, then set
    :math:`\alpha_1^{(i)} \sim N(a^{(i)}, \kappa^{(i)} I)`. If the block is
    initialized using the exact diffuse initialization procedure, then it is
    understood that :math:`\kappa^{(i)} \to \infty`.

    If the block is initialized using the approximate diffuse initialization
    procedure, then `\kappa^{(i)}` is set to some large value rather than
    driven to infinity.

    In the approximate diffuse initialization case, it is possible, although
    unlikely, that a known constant value may have some effect on
    initialization if :math:`\kappa^{(i)}` is not set large enough.

    Here, `constant` may be provided, and `approximate_diffuse_variance` may be
    provided.

    **Stationary**

    If a block is initialized as stationary, then the block of states is
    understood to have the distribution
    :math:`\alpha_1^{(i)} \sim N(a^{(i)}, Q_0^{(i)})`. :math:`a^{(i)}` is
    the unconditional mean of the block, computed as
    :math:`(I - T^{(i)})^{-1} c_t`. :math:`Q_0^{(i)}` is the unconditional
    variance of the block, computed as the solution to the discrete Lyapunov
    equation:

    .. math::

        T^{(i)} Q_0^{(i)} T^{(i)} + (R Q R')^{(i)} = Q_0^{(i)}

    :math:`T^{(i)}` and :math:`(R Q R')^{(i)}` are the submatrices of
    the corresponding state space system matrices corresponding to the given
    block of states.

    Here, no values can be provided.

    **Mixed**

    In this case, the block can be further broken down into sub-blocks.
    Usually, only the top-level `Initialization` instance will be of 'mixed'
    type, and in many cases, even the top-level instance will be purely
    'known', 'diffuse', or 'stationary'.

    For a block of type mixed, suppose that it has `J` sub-blocks,
    :math:`\alpha_1^{(i,j)}`. Then
    :math:`\alpha_1^{(i)} = a^{(i)} + A^{(i)} \delta + R_0^{(i)} \eta_0^{(i)}`.

    Examples
    --------

    Basic examples have one specification for all of the states:

    >>> Initialization(k_states=2, 'known', constant=[0, 1])
    >>> Initialization(k_states=2, 'known', stationary_cov=np.eye(2))
    >>> Initialization(k_states=2, 'known', constant=[0, 1],
                       stationary_cov=np.eye(2))
    >>> Initialization(k_states=2, 'diffuse')
    >>> Initialization(k_states=2, 'approximate_diffuse',
                       approximate_diffuse_variance=1e6)
    >>> Initialization(k_states=2, 'stationary')

    More complex examples initialize different blocks of states separately

    >>> init = Initialization(k_states=3)
    >>> init.set((0, 1), 'known', constant=[0, 1])
    >>> init.set((0, 1), 'known', stationary_cov=np.eye(2))
    >>> init.set((0, 1), 'known', constant=[0, 1],
                 stationary_cov=np.eye(2))
    >>> init.set((0, 1), 'diffuse')
    >>> init.set((0, 1), 'approximate_diffuse',
                 approximate_diffuse_variance=1e6)
    >>> init.set((0, 1), 'stationary')

    A still more complex example initializes a block using a previously
    created `Initialization` object:

    >>> init1 = Initialization(k_states=2, 'known', constant=[0, 1])
    >>> init2 = Initialization(k_states=3)
    >>> init2.set((1, 2), init1)
    N    .Ac                    || _         t          t          j        |                    | _        t          j        d g|z            | _        i | _        d | _        t          j	        | j                   | _
        t          j	        | j         | j         f          | _        || _        ||nt          j                                        | _        i | _        i | _        ||                     d |||           d S d S )Nconstantstationary_cov)k_statestuplenparange_statesarray_initializationblocksinitialization_typezerosr
   r   approximate_diffuse_variancer   prefix_initialization_mapcopy_representations_initializationsset)selfr   r   initialization_classesr   r
   r   s          i/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/tsa/statespace/initialization.py__init__zInitialization.__init__   s     ! RYx0011!x(9::
 $( // ht}'EFF,H) '=&H""05577 	& !# " *HHT.$2  4 4 4 4 4 +*    c           	      6   |}t          j        |          }t          j        |||||          \  }}}}}|||t          d          ||t          d          |t	          j        ||j                  }|t	          j        |          }t          |          |k    rt          d          ||@||t          d          |                    |                              |j                  }g |t	          j	        t	          j
        |                    d                                         |XD ]U}t	          j        ||         dk              r"t	          j        |dd|f         dk              st          d| d          Vt                    }	fd	t	          j        |          D             }
||	z
  }||dk    rt          d
           | |          }|
rGt	          j        |
t	          j	        t	          j        |
          dk              d         dz             }ng }|D ]H}t!          |d         |d         dz             }|                    |d||         |||f                    ID ]}|                    |d           |S )a  
        Construct initialization object from component matrices

        Parameters
        ----------
        a : array_like, optional
            Vector of constant values describing the mean of the stationary
            component of the initial state.
        Pstar : array_like, optional
            Stationary component of the initial state covariance matrix. If
            given, should be a matrix shaped `k_states x k_states`. The
            submatrix associated with the diffuse states should contain zeros.
            Note that by definition, `Pstar = R0 @ Q0 @ R0.T`, so either
            `R0,Q0` or `Pstar` may be given, but not both.
        Pinf : array_like, optional
            Diffuse component of the initial state covariance matrix. If given,
            should be a matrix shaped `k_states x k_states` with ones in the
            diagonal positions corresponding to states with diffuse
            initialization and zeros otherwise. Note that by definition,
            `Pinf = A @ A.T`, so either `A` or `Pinf` may be given, but not
            both.
        A : array_like, optional
            Diffuse selection matrix, used in the definition of the diffuse
            initial state covariance matrix. If given, should be a
            `k_states x k_diffuse_states` matrix that contains the subset of
            the columns of the identity matrix that correspond to states with
            diffuse initialization. Note that by definition, `Pinf = A @ A.T`,
            so either `A` or `Pinf` may be given, but not both.
        R0 : array_like, optional
            Stationary selection matrix, used in the definition of the
            stationary initial state covariance matrix. If given, should be a
            `k_states x k_nondiffuse_states` matrix that contains the subset of
            the columns of the identity matrix that correspond to states with a
            non-diffuse initialization. Note that by definition,
            `Pstar = R0 @ Q0 @ R0.T`, so either `R0,Q0` or `Pstar` may be
            given, but not both.
        Q0 : array_like, optional
            Covariance matrix associated with stationary initial states. If
            given, should be a matrix shaped
            `k_nondiffuse_states x k_nondiffuse_states`.
            Note that by definition, `Pstar = R0 @ Q0 @ R0.T`, so either
            `R0,Q0` or `Pstar` may be given, but not both.

        Returns
        -------
        initialization
            Initialization object.

        Notes
        -----
        The matrices `a, Pstar, Pinf, A, R0, Q0` and the process for
        initializing the state space model is as given in Chapter 5 of [1]_.
        For the definitions of these matrices, see equation (5.2) and the
        subsequent discussion there.

        References
        ----------
        .. [*] Durbin, James, and Siem Jan Koopman. 2012.
           Time Series Analysis by State Space Methods: Second Edition.
           Oxford University Press.
        NzCannot specify the initial state covariance both as `Pstar` and as the components R0 and Q0  (because `Pstar` is defined such that `Pstar=R0 Q0 R0'`).zCannot specify both the diffuse covariance matrix `Pinf` and the selection matrix for diffuse elements, A, (because Pinf is defined such that `Pinf=A A'`).zHMust provide constant initialization vector for the entire state vector.zFIf specifying either of R0 or Q0 then you must specify both R0 and Q0.r   zThe state at position ze was specified as diffuse in Pinf, but also contains a non-diffuse diagonal or off-diagonal in Pstar.c                     g | ]}|v|	S  r#   ).0i
diffuse_ixs     r   
<listcomp>z2Initialization.from_components.<locals>.<listcomp>C  s#    OOOq1J;N;N;N;N;Nr    z>Must provide initial covariance matrix for non-diffuse states.r   knownr	   diffuse)r   _atleast_1d_atleast_2d
ValueErrorr   dotTr   lenwherediagonaltolistallr   splitdiffslicer   )clsr   aPstarPinfAR0Q0r%   k_diffuse_statesnondiffuse_ixk_nondiffuse_statesinitnondiffuse_groupsgroupsr&   s                   @r   from_componentszInitialization.from_components   s0   @  a  !&!25$2r!J!JtQB ".BN 4 5 5 5  8 9 9 9 ]6!QS>>D 9""Aq66X 9 : : :>R^zRZ  "A B B BFF2JJNN24((E 
"+d"3"344Q7>>@@J # P PAF58q=11 PF5A;!#344P( *O! *O *O *O P P PP z??OOOOBIh$7$7OOO&)99 =0144 4 5 5 5 s8}} 	# "rx(>(>!(CDDQG!K!M !M !#& 	L 	LEeAhb	A..AHHQ!A$uQT{HKKKK 	# 	#AHHQ	""""r    c                 r    |j         }|j        }|j        }|                     |j        j        |||          S )N)r9   r:   r;   )initial_stateinitial_state_covinitial_diffuse_state_covrF   modelr   )r8   filter_resultsr9   r:   r;   s        r   from_resultszInitialization.from_resultsZ  sI    (07"">#7#@%&e$ # @ @ 	@r    c                 2    |                      ||           d S N)r   )r   indexr   s      r   __setitem__zInitialization.__setitem__c  s    +,,,,,r    c                    t           j        |         }|| j        vrP| j                            |          t          j        | j                            |                    d| j        |<   np| j                            |          d d          | j        |         d         d d <   | j                            |          d d          | j        |         d         d d <   || j        vrP| j	        |         } || j
        | j        |         d         | j        |         d         | j                  | j        |<   n| j        | j        |         _        ||fS )Nr	   r
   r   )r   prefix_dtype_mapr   r
   astyper   asfortranarrayr   r   r   r   r   )r   prefixdtyper8   s       r   _initialize_initializationz)Initialization._initialize_initializationf  sk   &v. ... !M0077"$"3'..u55#7 #7- -D!&)) $$U++AAA. !&)*5aaa8 #**511!!!4 !&)*:;AAA> ...08C,/Ct4V<ZH%f-.>?1-3 -3D!&)) 1 !&)F u}r    c           	         t          |t                    st          |t          t          j        f          r7t          |          }|dk     s|| j        k    rt          d          ||dz   f}n*||f}n$t          |t                    st          d          t          |          dk    rt          d          t          | }| j	        |         }t          |          dk    rdS | j
        *|| j	        k    st          dt          |          z            t          j        | j        |f         d          }|| j        vrLt          j        |          s8t          dt          t          j        |          |                    z            t          |          }|| j        k    r|| _
        ||d	k    st          d
          ||dk    st          d          |dk    r||t          d          |t          j        ||f          }nt          j        |          }|j        ||fk    s7t          dt          |j                  dt          ||f          d          || _        nT|dk    r|t)          j        d           n7|d	k    r
||| _        n'|dk    r|t          d          nt          d          |t          j        |          }nt          j        |          }|j        |fk    s6t          dt          |j                  dt          |f          d          || _        dS t          |t0                    r|}n|| j        }t1          |||||          }|| j        |<   |D ]}	|| j        |	<   dS )a  
        Set initialization for states, either globally or for a block

        Parameters
        ----------
        index : tuple or int or None
            Arguments used to create a `slice` of states. Can be a tuple with
            `(start, stop)` (note that for `slice`, stop is not inclusive), or
            an integer (to select a specific state), or None (to select all the
            states).
        initialization_type : str
            The type of initialization used for the states selected by `index`.
            Must be one of 'known', 'diffuse', 'approximate_diffuse', or
            'stationary'.
        constant : array_like, optional
            A vector of constant values, denoted :math:`a`. Most often used
            with 'known' initialization, but may also be used with
            'approximate_diffuse' (although it will then likely have little
            effect).
        stationary_cov : array_like, optional
            The covariance matrix of the stationary part, denoted :math:`Q_0`.
            Only used with 'known' initialization.
        approximate_diffuse_variance : float, optional
            The approximate diffuse variance, denoted :math:`\kappa`. Only
            applicable with 'approximate_diffuse' initialization. Default is
            1e6.
        r   Invalid index.r   N   'Cannot include a slice step in `index`.zCannot set initialization for the block of  states %s because initialization was previously performed globally. You must either re-initialize globally or else unset the global initialization before initializing specific blocks of states.zCannot set initialization for the state(s) %s because they are a subset of a previously initialized block. You must either re-initialize the entire block as a whole or else unset the entire block before re-initializing the subset.approximate_diffusezb`approximate_diffuse_variance` can only be provided when using approximate diffuse initialization.r)   zF`stationary_cov` can only be provided when using known initialization.ztMust specify either the constant vector or the stationary covariance matrix (or both) if using known initialization.z2Invalid stationary covariance matrix; given shape z but require shape .r*   zOConstant values provided, but they are ignored in exact diffuse initialization.
stationaryzAConstant values cannot be provided for stationary initialization.zInvalid initialization type.z%Invalid constant vector; given shape )r
   r   r   )
isinstancer7   intr   integerr   r-   r   r0   r   r   strequalr   r   r4   r   r   shaper   warningswarnr   r
   r   )
r   rP   r   r
   r   r   uninitializedr   rB   r%   s
             r   r   zInitialization.set  sy   > %'' 	"%#rz!233 3E

199 6 6$%5666	*u-- 3 !12225zzA~~ !JKKK5MEU# u::??F #/8M8M H  #5zz* + + + !5ef!>EE##BF=,A,A# <  #28E??M>#BCCD E E E u::t}$$':D$ -8+/DDD  "4 5 5 5 *+w66  "@ A A A #g--#(>$ &8 9 9 9
 ")%'Xx.B%C%CNN%'Xn%=%=N &+(/CCC$*(+N,@(A(A(A(A(+Xx,@(A(A(A(A&C D D D '5##$	11'M #N O O O$(===/;4 5$44'$ &C D D D ( !!?@@@ 8H--8H-->h[00 j$'$7$7$7$7h[9I9I9I9I"K L L L %DMMM -~>> 	O*/79 1%1H#11MO O O
 "&DK 0 0*/$Q''0 0r    c                    t          |t          t          j        f          r7t          |          }|dk     s|| j        k    rt          d          ||dz   f}n*||f}n$t          |t                    st          d          t          |          dk    rt          d          | j        t          |          }t          |          dk    rdS t          |          }|| j        k    r(| j
        !d| _
        d| j        dd<   d| j        dd<   dS || j        v r|D ]}d| j        |<   | j        |= dS t          d          )a#  
        Unset initialization for states, either globally or for a block

        Parameters
        ----------
        index : tuple or int or None
            Arguments used to create a `slice` of states. Can be a tuple with
            `(start, stop)` (note that for `slice`, stop is not inclusive), or
            an integer (to select a specific state), or None (to select all the
            states).

        Notes
        -----
        Note that this specifically unsets initializations previously created
        using `set` with this same index. Thus you cannot use `index=None` to
        unset all initializations, but only to unset a previously set global
        initialization. To unset all initializations (including both global and
        block level), use the `clear` method.
        r   rZ   r   Nr[   r\   zFThe given index does not correspond to a previously initialized block.)r`   ra   r   rb   r   r-   r   r0   r   r7   r   r
   r   r   r   )r   rP   r   r%   s       r   unsetzInitialization.unset$  ss   ( ec2:.// 	/JJEqyyEDM11 !1222EAI&EE]HEEE5)) 	/-...u::>>FGGGUE]+ u::??F u::t}$$)A)M'+D$ DM!!!%&D"""dk!! / /*.$Q''E""" > ? ? ?r    c                     | j         D ]}d| j        |<   t          | j                                                  }|D ]
}| j        |= d| _        d| j        dd<   d| j        dd<   dS )zX
        Clear all previously set initializations, either global or block level
        Nr   )r   r   listr   keysr   r
   r   )r   r%   rm   keys       r   clearzInitialization.clearX  s    
  	+ 	+A&*D ## DK$$&&'' 	! 	!CC   $( aaa!"AAAr    c                 n    | j         d u o+t          j        t          j        | j        d                      S rO   )r   r   anyrd   r   )r   s    r   initializedzInitialization.initializedj  s;    ,4 AF28D$8$??@@B 	Br    Fc                    | j         ;t          j        t          j        | j        d                    rt          d          |4| j        }t          j        dd         }t          j        ddddf         }n8t          j        |d         |d         dz            }t          j        ||          }|d|d|df         }	|d|z   dz            }
|d	|dddf         }|d
dddddf         }t          j	        ||          	                    |j
                  }|t          j        | j                  }| j        | j        f}|t          j        |          }|t          j        |          }| j         t          j        | j                  }t          j        | j        | j        f          }| j         dk    r|t          d          | j         dk    rZt          j                            |
          }d}t          j        t          j        |                    |k     st          d          | j         dk    r't          j                            ||
z
  |	          ||<   n
| j        ||<   | j         dk    rt          j        | j                  ||<   n|||<   | j         dk    r| j        ||<   n| j         dk    r|||<   n| j         dk    r|| j        z  ||<   n{| j         dk    rt-          j        |
||          ||<   nU| j                                        D ];\  }} |t5          t          j        |          |f                   ||||           <|||fS )ac  
        Construct initialization representation

        Parameters
        ----------
        model : Representation, optional
            A state space model representation object, optional if 'stationary'
            initialization is used and ignored otherwise. See notes for
            details in the stationary initialization case.
        model_index : ndarray, optional
            The base index of the block in the model.
        initial_state_mean : ndarray, optional
            An array (or more usually view) in which to place the initial state
            mean.
        initial_diffuse_state_cov : ndarray, optional
            An array (or more usually view) in which to place the diffuse
            component of initial state covariance matrix.
        initial_stationary_state_cov : ndarray, optional
            An array (or more usually view) in which to place the stationary
            component of initial state covariance matrix.


        Returns
        -------
        initial_state_mean : ndarray
            Initial state mean, :math:`a_1^{(0)} = a`
        initial_diffuse_state_cov : ndarray
            Diffuse component of initial state covariance matrix,
            :math:`P_\infty = A A'`
        initial_stationary_state_cov : ndarray
            Stationary component of initial state covariance matrix,
            :math:`P_* = R_0 Q_0 R_0'`

        Notes
        -----
        If stationary initialization is used either globally or for any block
        of states, then either `model` or all of `state_intercept`,
        `transition`, `selection`, and `state_cov` must be provided.
        Nz\Cannot construct initialization representation because not all states have been initialized.r   r(   r   state_intercept)
transition)r   	selection	state_covr_   z~Stationary initialization requires passing either the `model` argument or all of the individual transition equation arguments.gA?zWTransition equation is not stationary, and so stationary initialization cannot be used.r*   r)   r]   )complex_step)rP   rK   initial_state_meanrJ   initial_stationary_state_cov)r   r   rq   rd   r   r-   r   s_ix_r.   r/   r   r   eyelinalgeigvalsmaxabssolver
   r   r   r   solve_discrete_lyapunovr   itemsr   r   )r   rP   rK   ry   rJ   rz   rx   ix1ix2rt   ru   rv   rw   selected_state_cov	cov_shaper}   r   r   	thresholdblock_indexrB   s                        r   __call__zInitialization.__call__o  s   V $,rx 4d;;<< - N O O O =LE%(C%111+CC%arQ./C&&&C #$5sA$=>O4t;<Jk3145Ik111aaa23I!#	9!=!=!A!A)+!N!N %!#$-!8!8]DM2	$,(*(;(;%'/+-8I+>+>( #/&''CHdmT];<<E '<77EM  "N O O O '<77)++J77&	vbfWoo..::$ &1 2 2 2
 '<77*,)//#
:J:I+K +K"3'' +/-"3' '944131F1F)#..16)#. '722484G,S11)Y6649,S11)-BBB$;; -S11)\99 1*2D?KM M M -S1 &*[%6%6%8%8 P P!T5%!?@@ 5G/H2NP P P P P
 #$=,. 	.r    )NNr   NN)NNNNNN)NNN)NNNNNF)__name__
__module____qualname____doc__r   classmethodrF   rM   rQ   rX   r   rj   ro   propertyrr   r   r#   r    r   r   r      s-       d dL 6:KN/34 4 4 4> HL$(C C C [CJ @ @ [@- - -     D 8<>BZ0 Z0 Z0 Z0x2? 2? 2?h# # #$ B B XB CG+/AFD. D. D. D. D. D.r    r   )r   rf   numpyr    r   r   r#   r    r   <module>r      st               e. e. e. e. e. e. e. e. e. e.r    