use std::fmt; use std::ops; #[derive(Clone, Copy)] pub struct Gaussian { pi: f64, tau: f64, } impl fmt::Debug for Gaussian { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "N(mu={:.03}, sigma={:.03}, pi={:.03}, tau={:.03})", self.mu(), self.sigma(), self.pi(), self.tau()) } } impl Gaussian { pub fn from_pi_tau(pi: f64, tau: f64) -> Gaussian { Gaussian { pi, tau } } pub fn from_mu_sigma(mu: f64, sigma: f64) -> Gaussian { let pi = 1.0 / (sigma * sigma); Self::from_pi_tau(pi, pi * mu) } pub fn pi(&self) -> f64 { self.pi } pub fn tau(&self) -> f64 { self.tau } pub fn mu(&self) -> f64 { if self.pi == 0.0 { return 0.0; } else { self.tau / self.pi } } pub fn sigma(&self) -> f64 { (1.0 / self.pi).sqrt() } } impl ops::Mul for Gaussian { type Output = Gaussian; fn mul(self, rhs: Gaussian) -> Gaussian { Gaussian::from_pi_tau(self.pi + rhs.pi, self.tau + rhs.tau) } } impl ops::Div for Gaussian { type Output = Gaussian; fn div(self, rhs: Gaussian) -> Gaussian { Gaussian::from_pi_tau(self.pi - rhs.pi, self.tau - rhs.tau) } }