about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-12-07 23:39:34 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2013-12-08 22:12:58 +1100
commit705b705ba5182745e12652dc7eeeb10828f520d0 (patch)
treeb42fca1852b504120e4ce0966b0274f432eab90f /src/libstd
parent6155a1c98012f9565744dad3832660accd135b83 (diff)
downloadrust-705b705ba5182745e12652dc7eeeb10828f520d0.tar.gz
rust-705b705ba5182745e12652dc7eeeb10828f520d0.zip
std::rand: implement the student t distribution.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/rand/distributions/gamma.rs51
-rw-r--r--src/libstd/rand/distributions/mod.rs2
2 files changed, 52 insertions, 1 deletions
diff --git a/src/libstd/rand/distributions/gamma.rs b/src/libstd/rand/distributions/gamma.rs
index dec0d3922d3..ae7ff99af92 100644
--- a/src/libstd/rand/distributions/gamma.rs
+++ b/src/libstd/rand/distributions/gamma.rs
@@ -274,6 +274,47 @@ impl IndependentSample<f64> for FisherF {
     }
 }
 
+/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
+/// freedom.
+///
+/// # Example
+///
+/// ```rust
+/// use std::rand;
+/// use std::rand::distributions::{StudentT, IndependentSample};
+///
+/// fn main() {
+///     let t = StudentT::new(11.0);
+///     let v = t.ind_sample(&mut rand::task_rng());
+///     println!("{} is from a t(11) distribution", v)
+/// }
+/// ```
+pub struct StudentT {
+    priv chi: ChiSquared,
+    priv dof: f64
+}
+
+impl StudentT {
+    /// Create a new Student t distribution with `n` degrees of
+    /// freedom. Fails if `n <= 0`.
+    pub fn new(n: f64) -> StudentT {
+        assert!(n > 0.0, "StudentT::new called with `n <= 0`");
+        StudentT {
+            chi: ChiSquared::new(n),
+            dof: n
+        }
+    }
+}
+impl Sample<f64> for StudentT {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for StudentT {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        let norm = *rng.gen::<StandardNormal>();
+        norm * (self.dof / self.chi.ind_sample(rng)).sqrt()
+    }
+}
+
 #[cfg(test)]
 mod test {
     use rand::*;
@@ -323,6 +364,16 @@ mod test {
             f.ind_sample(&mut rng);
         }
     }
+
+    #[test]
+    fn test_t() {
+        let mut t = StudentT::new(11.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            t.sample(&mut rng);
+            t.ind_sample(&mut rng);
+        }
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libstd/rand/distributions/mod.rs b/src/libstd/rand/distributions/mod.rs
index 261b77fb245..a381ac35d30 100644
--- a/src/libstd/rand/distributions/mod.rs
+++ b/src/libstd/rand/distributions/mod.rs
@@ -27,7 +27,7 @@ use rand::{Rng, Rand};
 use clone::Clone;
 
 pub use self::range::Range;
-pub use self::gamma::{Gamma, ChiSquared, FisherF};
+pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
 pub use self::normal::{Normal, LogNormal};
 pub use self::exponential::Exp;