diff --git a/src/base/construction.rs b/src/base/construction.rs index b606534c..2fd0bb7f 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. @@ -852,6 +853,7 @@ where } } +// TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere}) #[cfg(feature = "rand")] impl Distribution>> for Standard where diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs index 7b137641..43bf45c6 100644 --- a/src/geometry/orthographic.rs +++ b/src/geometry/orthographic.rs @@ -691,6 +691,7 @@ impl Distribution> for Standard where Standard: Distribution, { + /// Generate an arbitrary random variate for testing purposes. fn sample(&self, r: &mut R) -> Orthographic3 { use crate::base::helper; let left = r.gen(); diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs index 69233952..64861fbd 100644 --- a/src/geometry/perspective.rs +++ b/src/geometry/perspective.rs @@ -275,6 +275,7 @@ impl Distribution> for Standard where Standard: Distribution, { + /// Generate an arbitrary random variate for testing purposes. fn sample<'a, R: Rng + ?Sized>(&self, r: &'a mut R) -> Perspective3 { use crate::base::helper; let znear = r.gen(); diff --git a/src/geometry/point_construction.rs b/src/geometry/point_construction.rs index bf88ece0..47b336f4 100644 --- a/src/geometry/point_construction.rs +++ b/src/geometry/point_construction.rs @@ -164,6 +164,7 @@ where DefaultAllocator: Allocator, Standard: Distribution, { + /// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`. #[inline] fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point { Point::from(rng.gen::>()) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index 50807907..1b87dba0 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/similarity_construction.rs b/src/geometry/similarity_construction.rs index 4501bdb7..0c814534 100644 --- a/src/geometry/similarity_construction.rs +++ b/src/geometry/similarity_construction.rs @@ -69,6 +69,7 @@ where DefaultAllocator: Allocator, Standard: Distribution + Distribution, { + /// Generate an arbitrary random variate for testing purposes. #[inline] fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity { let mut s = rng.gen(); diff --git a/src/geometry/translation_construction.rs b/src/geometry/translation_construction.rs index 964cd105..c1c02862 100644 --- a/src/geometry/translation_construction.rs +++ b/src/geometry/translation_construction.rs @@ -78,6 +78,7 @@ where DefaultAllocator: Allocator, Standard: Distribution, { + /// Generate an arbitrary random variate for testing purposes. #[inline] fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation { Translation::from(rng.gen::>()) diff --git a/src/geometry/unit_complex_construction.rs b/src/geometry/unit_complex_construction.rs index 9a24a57d..9f300f3d 100644 --- a/src/geometry/unit_complex_construction.rs +++ b/src/geometry/unit_complex_construction.rs @@ -2,10 +2,7 @@ use quickcheck::{Arbitrary, Gen}; #[cfg(feature = "rand-no-std")] -use rand::{ - distributions::{Distribution, OpenClosed01, Standard}, - Rng, -}; +use rand::{distributions::{Distribution, Standard}, Rng}; use num::One; use num_complex::Complex; @@ -401,12 +398,13 @@ where impl Distribution> for Standard where N::Element: SimdRealField, - OpenClosed01: Distribution, + rand_distr::UnitCircle: Distribution<[N; 2]>, { /// 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 x = rng.sample(rand_distr::UnitCircle); + UnitComplex::new_unchecked(Complex::new(x[0], x[1])) } } diff --git a/tests/core/helper.rs b/tests/core/helper.rs index ef749da6..ec214fc0 100644 --- a/tests/core/helper.rs +++ b/tests/core/helper.rs @@ -33,6 +33,8 @@ where // This is a wrapper similar to RandComplex, but for non-complex. // This exists only to make generic tests easier to write. +// +// Generates variates in the range [0, 1). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct RandScalar(pub N);