Exemple #1
0
 //======================================================================
 Vector &impute_mvn(Vector &observation,
                    const Vector &mean, const SpdMatrix &variance,
                    const Selector &observed, RNG &rng) {
   if (observed.nvars() == observed.nvars_possible()) {
     return observation;
   } else if (observed.nvars() == 0) {
     observation = rmvn_mt(rng, mean, variance);
     return observation;
   }
   if (observation.size() != observed.nvars_possible()) {
     report_error("observation and observed must be the same size.");
   }
   
   // The distribution we want is N(mu, V), with 
   //  V = Sig11 - Sig12 Sig22.inv Sig.21
   // and
   // mu = mu1 - Sig12 Sig22.inv (y2 - mu2)
   // The 1's are missing, and the 2's are observed.
   Selector missing = observed.complement();
   Matrix cross_covariance = missing.select_rows(
       observed.select_cols(variance));
   SpdMatrix observed_precision = observed.select_square(variance).inv();
   Vector mu = missing.select(mean) + cross_covariance * observed_precision
       * (observed.select(observation) - observed.select(mean));
   SpdMatrix V = missing.select_square(variance)
       - sandwich(cross_covariance, observed_precision);
   Vector imputed = rmvn_mt(rng, mu, V);
   observed.fill_missing_elements(observation, imputed);
   return observation;
 }
 // When dimensions are small the updates are trivial, and careful
 // optimization is not necessary.
 void Marginal::low_dimensional_update(
     const Vector &observation,
     const Selector &observed,
     const SparseKalmanMatrix &transition,
     const SparseKalmanMatrix &observation_coefficient_subset) {
   set_prediction_error(
       observed.select(observation)
       - observation_coefficient_subset * state_mean());
   SpdMatrix forecast_variance =
       observed.select_square(model_->observation_variance(time_index())) +
       observation_coefficient_subset.sandwich(state_variance());
   SpdMatrix forecast_precision = forecast_variance.inv();
   set_forecast_precision_log_determinant(forecast_precision.logdet());
   set_scaled_prediction_error(forecast_precision * prediction_error());
   set_kalman_gain(transition * state_variance() *
                   observation_coefficient_subset.Tmult(forecast_precision));
 }