use ferric::make_model;
use nalgebra::DVector;
#[test]
fn multivariate_normal_conjugate() {
make_model! {
name mvn_conjugate;
use ferric::distributions::MultivariateNormal;
use nalgebra::DVector;
use nalgebra::DMatrix;
let mu : DVector<f64> ~ MultivariateNormal::new(
DVector::from_vec(vec![0.0, 0.0]),
DMatrix::identity(2, 2)
);
let x : DVector<f64> ~ MultivariateNormal::new(
mu,
DMatrix::from_diagonal_element(2, 2, 0.1)
);
observe x;
query mu;
};
let model = mvn_conjugate::Model {
x: DVector::from_vec(vec![1.0, 2.0]),
};
let num_samples = 200_000;
let mut mu0_vals = Vec::with_capacity(num_samples);
let mut mu1_vals = Vec::with_capacity(num_samples);
let mut log_weights = Vec::with_capacity(num_samples);
for ws in model.weighted_sample_iter().take(num_samples) {
mu0_vals.push(ws.sample.mu[0]);
mu1_vals.push(ws.sample.mu[1]);
log_weights.push(ws.log_weight);
}
let mean0 = ferric::weighted_mean(&mu0_vals, &log_weights);
let mean1 = ferric::weighted_mean(&mu1_vals, &log_weights);
println!("posterior mu = [{:.4}, {:.4}]", mean0, mean1);
let expected0 = 10.0 / 11.0;
let expected1 = 20.0 / 11.0;
let tol = 0.05;
assert!(
(mean0 - expected0).abs() < tol,
"mu[0] posterior mean {:.4} != expected {:.4}",
mean0,
expected0
);
assert!(
(mean1 - expected1).abs() < tol,
"mu[1] posterior mean {:.4} != expected {:.4}",
mean1,
expected1
);
}