[][src]Module easy_ml::distributions

Models of distributions that samples can be drawn from.

These structs and methods require numerical types that can be treated as real numbers, ie unsigned and signed numbers cannot be used here.

Example of plotting a Gaussian

extern crate rand;
extern crate rand_chacha;
extern crate textplots;
extern crate easy_ml;

use rand::{Rng, SeedableRng};
use textplots::{Chart, Plot, Shape};
use easy_ml::distributions::Gaussian;

const SAMPLES: usize = 10000;

// create a normal distribution, note that the mean and variance are
// given in floating point notation as this will be a f64 Gaussian
let normal_distribution = Gaussian::new(0.0, 1.0);

// first create random numbers between 0 and 1
// using a fixed seed non cryptographically secure random
// generator from the rand crate
let mut random_generator = rand_chacha::ChaCha8Rng::seed_from_u64(10);

let mut random_numbers = Vec::with_capacity(SAMPLES);
for _ in 0..SAMPLES {
    random_numbers.push(random_generator.gen::<f64>());
}

// draw samples from the normal distribution
let samples: Vec<f64> = normal_distribution.draw(&mut random_numbers.drain(..), SAMPLES)
    // unwrap is perfectly save if and only if we know we have supplied enough random numbers
    .unwrap();

// create a [(f32, f32)] list to plot a histogram of
let histogram_points = {
    let x = 0..SAMPLES;
    let mut y = samples;
    let mut points = Vec::with_capacity(SAMPLES);
    for (x, y) in y.drain(..).zip(x).map(|(y, x)| (x as f32, y as f32)) {
        points.push((x, y));
    }
    points
};

// Plot a histogram from -3 to 3 with 30 bins to check that this distribution
// looks like a Gaussian. This will show a bell curve for large enough SAMPLES.
let histogram = textplots::utils::histogram(&histogram_points, -3.0, 3.0, 30);
Chart::new(180, 60, -3.0, 3.0)
    .lineplot( Shape::Bars(&histogram) )
    .nice();

Example of creating an infinite iterator using the rand crate

It may be convenient to create an infinite iterator for random numbers so you don't need to populate lists of random numbers when using these types.

use rand::{Rng, SeedableRng};

// use a fixed seed non cryptographically secure random generator from the rand crate
let mut random_generator = rand_chacha::ChaCha8Rng::seed_from_u64(16);

struct EndlessRandomGenerator {
    rng: rand_chacha::ChaCha8Rng
}

impl Iterator for EndlessRandomGenerator {
    type Item = f64;

    fn next(&mut self) -> Option<Self::Item> {
        // always return Some, hence this iterator is infinite
        Some(self.rng.gen::<f64>())
    }
}

// now pass this instance to Gaussian functions that accept a &mut Iterator
let mut random_numbers = EndlessRandomGenerator { rng: random_generator };

Structs

Gaussian

A Gaussian probability density function of a normally distributed random variable with expected value / mean μ, and variance σ2.

MultivariateGaussian

A multivariate Gaussian distribution with mean vector μ, and covariance matrix Σ.