steel_utils/random/
gaussian.rs1use super::Random;
2
3pub trait MarsagliaPolarGaussian: Random {
5 fn stored_next_gaussian(&self) -> Option<f64>;
7
8 fn set_stored_next_gaussian(&mut self, value: Option<f64>);
10
11 fn calculate_gaussian(&mut self) -> f64 {
13 if let Some(gaussian) = self.stored_next_gaussian() {
14 self.set_stored_next_gaussian(None);
15 gaussian
16 } else {
17 loop {
18 let d = 2.0 * self.next_f64() - 1.0;
19 let e = 2.0 * self.next_f64() - 1.0;
20 let f = d * d + e * e;
21
22 if f < 1.0 && f != 0.0 {
23 let g = (-2.0 * f.ln() / f).sqrt();
24 self.set_stored_next_gaussian(Some(e * g));
25 return d * g;
26 }
27 }
28 }
29 }
30}