1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#![allow(deprecated)]
#![allow(clippy::all)]
use crate::distributions::{Distribution, Uniform};
use crate::Rng;
#[deprecated(since = "0.7.0", note = "moved to rand_distr crate")]
#[derive(Clone, Copy, Debug)]
pub struct UnitCircle;
impl UnitCircle {
    
    #[inline]
    pub fn new() -> UnitCircle {
        UnitCircle
    }
}
impl Distribution<[f64; 2]> for UnitCircle {
    #[inline]
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> [f64; 2] {
        let uniform = Uniform::new(-1., 1.);
        let mut x1;
        let mut x2;
        let mut sum;
        loop {
            x1 = uniform.sample(rng);
            x2 = uniform.sample(rng);
            sum = x1 * x1 + x2 * x2;
            if sum < 1. {
                break;
            }
        }
        let diff = x1 * x1 - x2 * x2;
        [diff / sum, 2. * x1 * x2 / sum]
    }
}
#[cfg(test)]
mod tests {
    use super::UnitCircle;
    use crate::distributions::Distribution;
    
    
    
    
    macro_rules! assert_almost_eq {
        ($a:expr, $b:expr, $prec:expr) => {
            let diff = ($a - $b).abs();
            if diff > $prec {
                panic!(format!(
                    "assertion failed: `abs(left - right) = {:.1e} < {:e}`, \
                     (left: `{}`, right: `{}`)",
                    diff, $prec, $a, $b
                ));
            }
        };
    }
    #[test]
    fn norm() {
        let mut rng = crate::test::rng(1);
        let dist = UnitCircle::new();
        for _ in 0..1000 {
            let x = dist.sample(&mut rng);
            assert_almost_eq!(x[0] * x[0] + x[1] * x[1], 1., 1e-15);
        }
    }
    #[test]
    fn value_stability() {
        let mut rng = crate::test::rng(2);
        let expected = [
            [-0.9965658683520504, -0.08280380447614634],
            [-0.9790853270389644, -0.20345004884984505],
            [-0.8449189758898707, 0.5348943112253227],
        ];
        let samples = [
            UnitCircle.sample(&mut rng),
            UnitCircle.sample(&mut rng),
            UnitCircle.sample(&mut rng),
        ];
        assert_eq!(samples, expected);
    }
}