//--------------------------------------------------------------------------- SpdMatrix Marginal::forecast_precision() const { const Selector &observed(model_->observed_status(time_index())); DiagonalMatrix observation_precision = model_->observation_variance(time_index()).inv(); const SparseKalmanMatrix *observation_coefficients( model_->observation_coefficients(time_index(), observed)); SpdMatrix variance; if (previous()) { variance = previous()->state_variance(); } else { variance = model_->initial_state_variance(); } // 'inner' is I + P * Z' Hinv Z Matrix inner = variance * observation_coefficients->inner( observation_precision.diag()); inner.diag() += 1.0; SpdMatrix outer = inner.solve(variance); SpdMatrix ans = observation_precision.sandwich( observation_coefficients->sandwich(outer)); ans *= -1; ans.diag() += observation_precision.diag(); return ans; }
//--------------------------------------------------------------------------- SpdMatrix Marginal::direct_forecast_precision() const { SpdMatrix variance; if (previous()) { variance = previous()->state_variance(); } else { variance = model_->initial_state_variance(); } const Selector &observed(model_->observed_status(time_index())); SpdMatrix ans = model_->observation_coefficients( time_index(), observed)->sandwich(variance); ans.diag() += model_->observation_variance(time_index()).diag(); return ans.inv(); }