Diffuse initialization (Durbin Koopman)

We describe below the diffuse initialization of Durbin-Koopman (DK) and a variant that we call “partial square root initialization”

When $y_t$ is observed, we compute the following recursions

\[F_{*t} = Z_t P_{*t} Z_T'\] \[C_{*t} = T_t P_{*t} Z_T'\] \[F_{\infty t} = Z_t P_{\infty t} Z_T'\] \[C_{\infty t} = T_t P_{\infty t} Z_T'\] \[v_t = y_t - Z_t a_t\]

if $F_{\infty t}=0$

\[a_{t+1} = T_t a_t + C_{* t} F_{* t}^{-1} v_t\] \[P_{\infty t+1} = T_t P_{\infty t} T_t'\] \[P_{* t+1} = T_t P_{*t} T_t' - C_{*t} F_{*t}^{-1} C_{* t}' + V_t\]

if $F_{\infty t}$ is invertible

\[a_{t+1} = T_t a_t + v_t F_{\infty t}^{-1} C_{\infty t}\] \[P_{\infty t+1} = T_t P_{\infty t} T_t' - C_{\infty t} F_{\infty t}^{-1} C_{\infty t}'\] \[P_{* t+1} = T_t P_{* t} T_t' - C_{\infty t} F_{\infty t}^{-1} F_{*t} F_{\infty t}^{-1} C_{\infty t}' - < C_{* t} F_{\infty t}^{-1} C_{\infty t}'> + V_t\]

where $\lt A \gt$ stands for $A+A’$

Partial square root form

The partial square root form is trivially derived from the Durbin-Koopman equations, taking into account that $P_{\infty t}=B_t B_t’$.

When $y_t$ is observed, we compute the following recursions

\[F_{*t} = Z_t P_{*t} Z_T'\] \[C_{*t} = T_t P_{*t} Z_T'\] \[F_{\infty t} = \left(Z_t B_t \right) \left(Z_t B_t \right)' = X_t X_t'\] \[C_{\infty t} = \left(T_t B_t \right) \left(Z_t B_t \right)' = Y_t X_t'\] \[v_t = y_t - Z_t a_t\]

if $Z_t B_t=0$

\[a_{t+1} = T_t a_t + C_{* t} F_{* t}^{-1} v_t\] \[B_{t+1} = T_t B_t\] \[P_{* t+1} = T_t P_{* t} T_t' - C_{*t} F_{*t}^{-1} C_{*t}' + V_t\]

if $Z_t B_t \neq 0$

\[a_{t+1} = T_t a_t + v_t F_{\infty t}^{-1} C_{\infty t}\] \[P_{\infty t+1} = \left(T_t B_t \right)\left(T_t B_t \right)' - C_{\infty t} F_{\infty t}^{-1} C_{\infty t}'\] \[P_{* t+1} = T_t P_{* t} T_t' - C_{\infty t} F_{\infty t}^{-1} F_{*t} F_{\infty t}^{-1} C_{\infty t}' - < C_{* t} F_{\infty t}^{-1} C_{\infty t}'> + V_t\]

$B_{t+1}$ is computed as follows:

  • Choose an orthogonal transformation that transforms $Z_t B_t$ in $\begin{pmatrix}L_t &0&\cdots&0 \end{pmatrix}$; by default, JD+ takes Householder reflection(s)
  • Apply that transformation on $T_t B_t$
  • The first column(s) of the transformed $T_t B_t$ corresponds to $C_{\infty t} F_{\infty t}^{-1/2}$ and the remaining to $B_{t+1}$

That can be shown using the same arguments as in an array algorithm, applied on the transformations:

\[\begin{pmatrix} 0 \\ B_t \end{pmatrix} \rightarrow \begin{pmatrix} Z_t B_t \\ T_t B_t \end{pmatrix} \rightarrow \begin{pmatrix} F_{\infty t}^{1/2} & 0 \\ C_{\infty t} F_{\infty t}^{-1/2} & B_{t+1} \end{pmatrix}\]

Contrary to the usual array algorithm, we don’t compute a complete triangularization: processing the first rows, which correspond to the measurement equations, is indeed sufficient. So, in the case of a univariate series, we just have to use a single householder reflection to compute the next $B_{t+1}$. To be noted that that formulation shows in an obvious way that the rank of $B_t$ will decrease by $rank(F_{\infty t})$ at each step. That implies that, after every iteration, the matrix $B_t$ becomes smaller and the computations less expensive.


Implementation

The Diffuse initialization is implemented in several classes

  • The “Durbin-Koopman” initialization of the filter is provided by the class demetra.ssf.dk.DurbinKoopmanInitializer
  • The corresponding “Durbin Koopman” smoother is provided by the class demetra.ssf.dk.DiffuseSmoother
  • The “Partial square root” initialization of the filter is provided by the class demetra.ssf.dk.sqrt.DiffuseSquareRootInitializer
  • The corresponding diffuse square root smoother is provided by the class demetra.ssf.dk.sqrt.DiffuseSquareRootSmoother.

The different algorithms based on the DK initialization are put together in the class demetra.ssf.dk.DkToolkit. This is illustrated by the piece of code hereafter.

        // Creation of the ssf of an airline model
        SarimaSpecification spec = new SarimaSpecification(12);
        spec.airline();
        arima = SarimaModel
                .builder(spec)
                .theta(1, -.6)
                .btheta(1, -.8)
                .build();
        data = Data.PROD.clone();
        SsfArima ssf = SsfArima.of(arima);
        // data
        SsfData ssfData = new SsfData(data);
        // computation of the diffuse likelihood
        DkLikelihood ll1 = DkToolkit.likelihoodComputer().compute(ssf, ssfData);
        // filtering
        DefaultDiffuseFilteringResults frslts = DkToolkit.filter(ssf, ssfData, true);
       // square root form
        DefaultDiffuseSquareRootFilteringResults frslts2 = DkToolkit.sqrtFilter(ssf, ssfData, true);