From fd3a7524091d5cb7fc38d2b2501f19d106f6e75a Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Sat, 10 Apr 2021 03:13:46 -0300 Subject: [PATCH] Make use of rand more idiomatic This should improve performance and accuracy. --- src/base/construction.rs | 3 ++- src/geometry/quaternion_construction.rs | 10 +++++----- src/geometry/rotation_specialization.rs | 13 ++++++++----- src/geometry/unit_complex_construction.rs | 7 ++++--- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/base/construction.rs b/src/base/construction.rs index b606534c..f8e9e5f8 100644 --- a/src/base/construction.rs +++ b/src/base/construction.rs @@ -284,7 +284,8 @@ where where Standard: Distribution, { - Self::from_fn_generic(nrows, ncols, |_, _| rand::random()) + let mut rng = rand::thread_rng(); + Self::from_fn_generic(nrows, ncols, |_, _| rng.gen()) } /// Creates a matrix filled with random values from the given distribution. diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index 89911b91..625342a8 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -7,7 +7,7 @@ use quickcheck::{Arbitrary, Gen}; #[cfg(feature = "rand-no-std")] use rand::{ - distributions::{Distribution, OpenClosed01, Standard}, + distributions::{Distribution, OpenClosed01, Standard, Uniform, uniform::SampleUniform}, Rng, }; @@ -855,6 +855,7 @@ impl Distribution> for Standard where N::Element: SimdRealField, OpenClosed01: Distribution, + N: SampleUniform, { /// Generate a uniformly distributed random rotation quaternion. #[inline] @@ -863,10 +864,9 @@ where // Uniform random rotations. // In D. Kirk, editor, Graphics Gems III, pages 124-132. Academic, New York, 1992. let x0 = rng.sample(OpenClosed01); - let x1 = rng.sample(OpenClosed01); - let x2 = rng.sample(OpenClosed01); - let theta1 = N::simd_two_pi() * x1; - let theta2 = N::simd_two_pi() * x2; + let twopi = Uniform::new(N::zero(), N::simd_two_pi()); + let theta1 = rng.sample(&twopi); + let theta2 = rng.sample(&twopi); let s1 = theta1.simd_sin(); let c1 = theta1.simd_cos(); let s2 = theta2.simd_sin(); diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs index 95e19da1..fe431804 100644 --- a/src/geometry/rotation_specialization.rs +++ b/src/geometry/rotation_specialization.rs @@ -7,7 +7,7 @@ use num::Zero; #[cfg(feature = "rand-no-std")] use rand::{ - distributions::{Distribution, OpenClosed01, Standard}, + distributions::{Distribution, OpenClosed01, Standard, Uniform, uniform::SampleUniform}, Rng, }; @@ -265,12 +265,13 @@ impl Rotation2 { impl Distribution> for Standard where N::Element: SimdRealField, - OpenClosed01: Distribution, + N: SampleUniform, { /// Generate a uniformly distributed random rotation. #[inline] fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> Rotation2 { - Rotation2::new(rng.sample(OpenClosed01) * N::simd_two_pi()) + let twopi = Uniform::new(N::zero(), N::simd_two_pi()); + Rotation2::new(rng.sample(twopi)) } } @@ -923,6 +924,7 @@ impl Distribution> for Standard where N::Element: SimdRealField, OpenClosed01: Distribution, + N: SampleUniform, { /// Generate a uniformly distributed random rotation. #[inline] @@ -932,7 +934,8 @@ where // In D. Kirk, editor, Graphics Gems III, pages 117-120. Academic, New York, 1992. // Compute a random rotation around Z - let theta = N::simd_two_pi() * rng.sample(OpenClosed01); + let twopi = Uniform::new(N::zero(), N::simd_two_pi()); + let theta = rng.sample(&twopi); let (ts, tc) = theta.simd_sin_cos(); let a = MatrixN::::new( tc, @@ -947,7 +950,7 @@ where ); // Compute a random rotation *of* Z - let phi = N::simd_two_pi() * rng.sample(OpenClosed01); + let phi = rng.sample(&twopi); let z = rng.sample(OpenClosed01); let (ps, pc) = phi.simd_sin_cos(); let sqrt_z = z.simd_sqrt(); diff --git a/src/geometry/unit_complex_construction.rs b/src/geometry/unit_complex_construction.rs index 9a24a57d..fc1ff131 100644 --- a/src/geometry/unit_complex_construction.rs +++ b/src/geometry/unit_complex_construction.rs @@ -3,7 +3,7 @@ use quickcheck::{Arbitrary, Gen}; #[cfg(feature = "rand-no-std")] use rand::{ - distributions::{Distribution, OpenClosed01, Standard}, + distributions::{Distribution, Uniform, uniform::SampleUniform, Standard}, Rng, }; @@ -401,12 +401,13 @@ where impl Distribution> for Standard where N::Element: SimdRealField, - OpenClosed01: Distribution, + N: SampleUniform, { /// Generate a uniformly distributed random `UnitComplex`. #[inline] fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex { - UnitComplex::from_angle(rng.sample(OpenClosed01) * N::simd_two_pi()) + let twopi = Uniform::new(N::zero(), N::simd_two_pi()); + UnitComplex::from_angle(rng.sample(twopi)) } }