distributions 0.0.2

Some statistic distributions written in rust
use std::rand::{mod, Rng, task_rng, TaskRng};
use std::rand::distributions::{Sample, Normal,IndependentSample};
use super::{Distribution,ContinuousDistribution,HasCdf};
use std::num::Float;
use std::f64::consts::PI;

pub struct Uniform {
    a: f64,
    b: f64,
    pub entropy: f64,
}

impl Uniform {
    pub fn new(a: f64, b: f64) -> Uniform {
        Uniform {
            a: a,
            b: b,
            entropy: (b - a).ln(),
        }
    }
}

impl Sample<f64> for Uniform {
    fn sample<R>(&mut self, rng: &mut R) -> f64 where R: Rng {
        self.ind_sample(rng)
    }
}

impl IndependentSample<f64> for Uniform {
    fn ind_sample<R>(&self, rng: &mut R) -> f64 where R: Rng {
        rng.gen_range(self.a, self.b)
    }
}

impl Distribution<f64> for Uniform {
    fn mean(&self) -> f64 {
        (self.a + self.b) / 2.0
    }
    fn variance(&self) -> f64 {
        (self.b - self.a).powi(2) / 12.0
    }
}

impl ContinuousDistribution<f64> for Uniform {
    fn unnormalized_log_pdf(&self, x: f64) -> f64 {
        if x <= self.b && x >= self.a {
            let f = 1. / (self.b - self.a);
            f.ln()
        } else {
            0f64
        }
    }
    fn log_normalizer(&self) -> f64 {
        self.entropy
    }
}

impl HasCdf<f64> for Uniform {
    fn probability(&self, a: f64, b: f64) -> f64 {
        (b - a) / (self.b - self.a)
    }
    fn cdf(&self, x: f64) -> f64 {
        match x {
            x if x <= self.a => 0f64,
            x if x >= self.b => 1f64,
            _ => (x - self.a) / (self.b - self.a)
        }
    }
}

#[test]
fn test_uniform_distr() {
    let mut d = Uniform::new(1.0, 3.);
    for _ in range(0u, 99u) {
        let rand = d.sample(&mut task_rng());
        assert!(rand <= 3.0 && rand >= 1.0);
    }
}