use nalgebra::*;
use bayes::gsl::randist::*;
use bayes::gsl::vector_double::*;
use bayes::gsl::matrix_double::*;
use bayes::gsl::utils::*;
use bayes::distr::*;
const EPS : f64 = 10E-8;
fn unit_interval_seq(n : usize) -> DMatrix<f64> {
DMatrix::from_fn(n, 1, |i,j| (i+1) as f64 * (1. / n as f64) )
}
fn count_seq(n : usize) -> DMatrix<f64> {
DMatrix::from_fn(n, 1, |i,j| (i+1) as f64)
}
#[test]
fn bernoulli() {
for y in [0.0, 1.0].iter() {
for p in (1..100).map(|p| 0.01 * p as f64) {
let gsl_p = unsafe{ gsl_ran_bernoulli_pdf(*y as u32, p) };
let mut b = Bernoulli::new(1, Some(0.5));
let pv = DVector::from_element(1,p);
b.set_parameter(pv.rows(0,1), false);
let ym = DMatrix::from_element(1,1,*y);
assert!( (gsl_p - b.prob(ym.rows(0,1))).abs() < EPS);
}
}
}
#[test]
fn poisson() {
let lambda = unit_interval_seq(100);
let count = count_seq(100);
unsafe {
for i in 0..100 {
for l in lambda.iter() {
let gsl_prob = gsl_ran_poisson_pdf(count[(i,0)] as u32, *l);
let poiss = Poisson::new(1, Some(*l));
let bayes_prob = poiss.prob(count.slice((i,0), (1,1)));
assert!( (gsl_prob - bayes_prob).abs() < EPS);
}
}
}
}
#[test]
fn beta() {
let theta = unit_interval_seq(100);
let count = count_seq(10);
unsafe {
for i in 0..100 {
for (a, b) in count.iter().zip(count.iter()) {
let gsl_prob = gsl_ran_beta_pdf(theta[(i,0)], *a, *b);
let beta = Beta::new(*a as usize, *b as usize);
let bayes_prob = beta.prob(theta.slice((i,0), (1,1)));
assert!( (gsl_prob - bayes_prob).abs() < EPS);
}
}
}
}
#[test]
fn gamma() {
let theta = unit_interval_seq(100);
let count = count_seq(10);
unsafe {
for i in 0..100 {
for (a, b) in count.iter().zip(count.iter()) {
let gsl_prob = gsl_ran_gamma_pdf(theta[(i,0)], *a, 1. / *b);
let gamma = Gamma::new(*a, *b);
let bayes_prob = gamma.prob(theta.slice((i,0), (1,1)));
assert!( (gsl_prob - bayes_prob).abs() < EPS);
}
}
}
}
#[test]
fn multinormal() {
let mu = DVector::from_element(5, 0.0);
let mut sigma = DMatrix::from_element(5, 5, 0.0);
sigma.set_diagonal(&DVector::from_element(5, 1.));
let mn : MultiNormal = MultiNormal::new(mu.clone(), sigma.clone());
let lu = Cholesky::new(sigma).unwrap();
let lower = lu.l();
println!("{}", lower);
unsafe {
let lower_gsl : gsl_matrix = lower.into();
let ws_orig = DVector::<f64>::zeros(5);
let mut ws : gsl_vector = ws_orig.into();
let mut gsl_prob : f64 = 0.0;
let mu_vec : gsl_vector = mu.clone().into();
let x_vec : gsl_vector = mu.clone().into();
let ans = gsl_ran_multivariate_gaussian_pdf(
&x_vec as *const _,
&mu_vec as *const _,
&lower_gsl as *const _,
&mut gsl_prob as *mut _,
&mut ws as *mut _
);
if ans != 0 {
panic!("Error calculating multivariate density");
}
let x = DMatrix::<f64>::from_iterator(1, 5, mu.iter().map(|x| *x));
assert!((gsl_prob - mn.prob(x.slice((0,0), (x.nrows(), x.ncols())))).abs() < EPS);
}
}
#[test]
fn normal() {
let mu = unit_interval_seq(100);
let values = mu.clone();
unsafe {
for (i, y) in values.iter().enumerate() {
let gsl_prob = gsl_ran_gaussian_pdf(*y, (1.).sqrt());
let norm = Normal::new(1, Some(0.), Some(1.));
let bayes_prob = norm.prob(values.slice((i,0), (1,1)));
assert!( (gsl_prob - bayes_prob).abs() < EPS);
}
}
}
#[test]
fn categorical() {
let c : Categorical = Categorical::new(4, Some(&[0.2, 0.2, 0.2, 0.2]));
let probs : [f64; 5] = [0.2,0.2,0.2,0.2,0.2];
let outcome : [u32; 5] = [1, 0, 0, 0, 0];
unsafe {
let gsl_cat_p = gsl_ran_multinomial_pdf(5, &probs[0] as *const _, &outcome[0] as *const _);
let vprobs = DMatrix::from_iterator(1, 4, outcome[0..4].iter().map(|o| *o as f64));
let cat_p = c.prob(vprobs.slice((0, 0), (1, 4)));
assert!((gsl_cat_p - cat_p).abs() < EPS);
}
}