From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rand-0.7.3/src/distributions/unit_circle.rs | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 vendor/rand-0.7.3/src/distributions/unit_circle.rs (limited to 'vendor/rand-0.7.3/src/distributions/unit_circle.rs') diff --git a/vendor/rand-0.7.3/src/distributions/unit_circle.rs b/vendor/rand-0.7.3/src/distributions/unit_circle.rs new file mode 100644 index 000000000..37885d8eb --- /dev/null +++ b/vendor/rand-0.7.3/src/distributions/unit_circle.rs @@ -0,0 +1,102 @@ +// Copyright 2018 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(deprecated)] +#![allow(clippy::all)] + +use crate::distributions::{Distribution, Uniform}; +use crate::Rng; + +/// Samples uniformly from the edge of the unit circle in two dimensions. +/// +/// Implemented via a method by von Neumann[^1]. +/// +/// [^1]: von Neumann, J. (1951) [*Various Techniques Used in Connection with +/// Random Digits.*](https://mcnp.lanl.gov/pdf_files/nbs_vonneumann.pdf) +/// NBS Appl. Math. Ser., No. 12. Washington, DC: U.S. Government Printing +/// Office, pp. 36-38. +#[deprecated(since = "0.7.0", note = "moved to rand_distr crate")] +#[derive(Clone, Copy, Debug)] +pub struct UnitCircle; + +impl UnitCircle { + /// Construct a new `UnitCircle` distribution. + #[inline] + pub fn new() -> UnitCircle { + UnitCircle + } +} + +impl Distribution<[f64; 2]> for UnitCircle { + #[inline] + fn sample(&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; + + /// Assert that two numbers are almost equal to each other. + /// + /// On panic, this macro will print the values of the expressions with their + /// debug representations. + 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); + } +} -- cgit v1.2.3