mod box_muller;
use super::{Distribution};
use rand::Rng;
use std::f64::consts::PI;
pub fn pdf(x: f64, mu: f64, sigma: f64) -> f64
{
let sigma_sqr = sigma * sigma;
let sigma_sqr_2 = 2.0 * sigma_sqr;
let diff = x - mu;
let e_num = diff * diff;
let e = e_num / sigma_sqr_2;
let exp = (- e).exp();
let denom = (PI * sigma_sqr_2).sqrt();
let value = exp / denom;
value
}
#[derive(Debug)]
pub enum SampleMethod
{
BoxMuller,
}
#[derive(Debug)]
pub struct Gaussian
{
mu: f64, sigma: f64 }
impl Gaussian
{
pub fn new(mu: f64, sigma: f64) -> Self
{
Self{mu, sigma}
}
pub fn sample(&self, n: usize, method: SampleMethod) -> Vec<f64>
{
match method
{
SampleMethod::BoxMuller => self.sample_box_muller(n)
}
}
pub fn sample_box_muller(&self, n: usize) -> Vec<f64>
{
box_muller::box_muller(self.mu, self.sigma, n)
}
pub fn sample_box_muller_with<R: Rng>(&self, n: usize, rng: R) -> Vec<f64>
{
box_muller::box_muller_with(self.mu, self.sigma, n, rng)
}
}
impl Distribution for Gaussian
{
type Dist = Self;
fn n_dim() -> usize
{
2
}
fn from(theta: &[f64]) -> Self
{
Self::new(theta[0], theta[1])
}
fn params(&self, theta: &mut [f64]) -> ()
{
theta[0] = self.mu;
theta[1] = self.sigma;
}
fn pdf(&self, x: f64) -> f64
{
pdf(x, self.mu, self.sigma)
}
}