Skip to content

Commit

Permalink
Cauchy distribution: optimise sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed May 30, 2018
1 parent c4d1446 commit b847ea3
Showing 1 changed file with 8 additions and 11 deletions.
19 changes: 8 additions & 11 deletions src/distributions/cauchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! The Cauchy distribution.
use Rng;
use distributions::Distribution;
use distributions::{Distribution, Open01};
use std::f64::consts::PI;

/// The Cauchy distribution `Cauchy(median, scale)`.
Expand Down Expand Up @@ -49,14 +49,11 @@ impl Cauchy {

impl Distribution<f64> for Cauchy {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
// sample from [0, 1)
let mut x = rng.gen::<f64>();
// guard against the extremely unlikely case we get the invalid 0.5
while x == 0.5 {
x = rng.gen::<f64>();
}
// Sample from (-π/2, π/2). Note that end-points are not
// representable since π is not rational, therefore result is finite.
let x = PI * (rng.sample::<f64, _>(Open01) - 0.5);
// get standard cauchy random number
let comp_dev = (PI * x).tan();
let comp_dev = x.tan();
// shift and scale according to parameters
let result = self.median + self.scale * comp_dev;
result
Expand All @@ -81,7 +78,7 @@ mod test {
#[test]
fn test_cauchy_median() {
let cauchy = Cauchy::new(10.0, 5.0);
let mut rng = ::test::rng(123);
let mut rng = ::test::rng(321);
let mut numbers: [f64; 1000] = [0.0; 1000];
for i in 0..1000 {
numbers[i] = cauchy.sample(&mut rng);
Expand All @@ -94,15 +91,15 @@ mod test {
#[test]
fn test_cauchy_mean() {
let cauchy = Cauchy::new(10.0, 5.0);
let mut rng = ::test::rng(123);
let mut rng = ::test::rng(322);
let mut sum = 0.0;
for _ in 0..1000 {
sum += cauchy.sample(&mut rng);
}
let mean = sum / 1000.0;
println!("Cauchy mean: {}", mean);
// for a Cauchy distribution the mean should not converge
assert!((mean - 10.0).abs() > 0.5); // not 100% certain, but probable enough
assert!((mean - 10.0).abs() > 0.1); // not 100% certain, but probable enough
}

#[test]
Expand Down

0 comments on commit b847ea3

Please sign in to comment.