Update to rand 0.5.

This commit is contained in:
sebcrozet 2018-05-22 23:58:14 +02:00 committed by Sébastien Crozet
parent 57fa307d4d
commit a51744f86b
12 changed files with 150 additions and 111 deletions

View File

@ -26,11 +26,11 @@ debug = [ ]
[dependencies] [dependencies]
typenum = "1.10" typenum = "1.10"
generic-array = "0.11" generic-array = "0.11"
rand = { version = "0.4", default-features = false } rand = { version = "0.5", default-features = false }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.2.0-git", git = "https://github.com/rust-num/num-complex", default-features = false } num-complex = { version = "0.2.0-git", git = "https://github.com/rust-num/num-complex", default-features = false }
approx = { version = "0.1", default-features = false } approx = { version = "0.2", default-features = false }
alga = { version = "0.5", default-features = false } alga = { version = "0.5", path = "../alga/alga", default-features = false }
matrixmultiply = { version = "0.1", optional = true } matrixmultiply = { version = "0.1", optional = true }
serde = { version = "1.0", optional = true } serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true }

View File

@ -4,7 +4,8 @@ use base::storage::Owned;
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use num::{Bounded, One, Zero}; use num::{Bounded, One, Zero};
use rand::{self, distributions::Sample, Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::{self, Rng};
use std::iter; use std::iter;
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
@ -231,14 +232,14 @@ where
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn new_random_generic(nrows: R, ncols: C) -> Self pub fn new_random_generic(nrows: R, ncols: C) -> Self
where where
N: Rand, Standard: Distribution<N>,
{ {
Self::from_fn_generic(nrows, ncols, |_, _| rand::random()) Self::from_fn_generic(nrows, ncols, |_, _| rand::random())
} }
/// Creates a matrix filled with random values from the given distribution. /// Creates a matrix filled with random values from the given distribution.
#[inline] #[inline]
pub fn from_distribution_generic<Distr: Sample<N> + ?Sized, G: Rng>( pub fn from_distribution_generic<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
nrows: R, nrows: R,
ncols: C, ncols: C,
distribution: &mut Distr, distribution: &mut Distr,
@ -371,7 +372,7 @@ macro_rules! impl_constructors(
/// Creates a matrix filled with random values from the given distribution. /// Creates a matrix filled with random values from the given distribution.
#[inline] #[inline]
pub fn from_distribution<Distr: Sample<N> + ?Sized, G: Rng>( pub fn from_distribution<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
$($args: usize,)* $($args: usize,)*
distribution: &mut Distr, distribution: &mut Distr,
rng: &mut G, rng: &mut G,
@ -380,8 +381,10 @@ macro_rules! impl_constructors(
} }
} }
impl<N: Scalar + Rand, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*> impl<N: Scalar, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*>
where DefaultAllocator: Allocator<N $(, $Dims)*> { where
DefaultAllocator: Allocator<N $(, $Dims)*>,
Standard: Distribution<N> {
/// Creates a matrix filled with random values. /// Creates a matrix filled with random values.
#[inline] #[inline]
@ -462,18 +465,17 @@ where
} }
} }
impl<N: Scalar + Rand, R: Dim, C: Dim> Rand for MatrixMN<N, R, C> impl<N: Scalar, R: Dim, C: Dim> Distribution<MatrixMN<N, R, C>> for Standard
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<N, R, C>,
Standard: Distribution<N>,
{ {
#[inline] #[inline]
fn rand<G: Rng>(rng: &mut G) -> Self { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> MatrixMN<N, R, C> {
let nrows = R::try_to_usize().unwrap_or(rng.gen_range(0, 10)); let nrows = R::try_to_usize().unwrap_or(rng.gen_range(0, 10));
let ncols = C::try_to_usize().unwrap_or(rng.gen_range(0, 10)); let ncols = C::try_to_usize().unwrap_or(rng.gen_range(0, 10));
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| { MatrixMN::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
rng.gen()
})
} }
} }

View File

@ -1,6 +1,7 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
/// Simple helper function for rejection sampling /// Simple helper function for rejection sampling
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
@ -16,7 +17,10 @@ pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
pub fn reject_rand<G: Rng, F: FnMut(&T) -> bool, T: Rand>(g: &mut G, f: F) -> T { pub fn reject_rand<G: Rng + ?Sized, F: FnMut(&T) -> bool, T>(g: &mut G, f: F) -> T
where
Standard: Distribution<T>,
{
use std::iter; use std::iter;
iter::repeat(()).map(|_| Rand::rand(g)).find(f).unwrap() iter::repeat(()).map(|_| g.gen()).find(f).unwrap()
} }

View File

@ -1,20 +1,23 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
use base::storage::Owned; use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use num::One; use num::One;
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real; use alga::general::Real;
use alga::linear::Rotation as AlgaRotation; use alga::linear::Rotation as AlgaRotation;
use base::{DefaultAllocator, Vector2, Vector3};
use base::dimension::{DimName, U2, U3};
use base::allocator::Allocator; use base::allocator::Allocator;
use base::dimension::{DimName, U2, U3};
use base::{DefaultAllocator, Vector2, Vector3};
use geometry::{Isometry, Point, Point3, Rotation, Rotation2, Rotation3, Translation, UnitComplex, use geometry::{
UnitQuaternion}; Isometry, Point, Point3, Rotation, Rotation2, Rotation3, Translation, UnitComplex,
UnitQuaternion,
};
impl<N: Real, D: DimName, R: AlgaRotation<Point<N, D>>> Isometry<N, D, R> impl<N: Real, D: DimName, R: AlgaRotation<Point<N, D>>> Isometry<N, D, R>
where where
@ -46,14 +49,15 @@ where
} }
} }
impl<N: Real + Rand, D: DimName, R> Rand for Isometry<N, D, R> impl<N: Real, D: DimName, R> Distribution<Isometry<N, D, R>> for Standard
where where
R: AlgaRotation<Point<N, D>> + Rand, R: AlgaRotation<Point<N, D>>,
Standard: Distribution<N> + Distribution<R>,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn rand<G: Rng>(rng: &mut G) -> Self { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Isometry<N, D, R> {
Self::from_parts(rng.gen(), rng.gen()) Isometry::from_parts(rng.gen(), rng.gen())
} }
} }

View File

@ -1,16 +1,17 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
use serde; use serde;
use std::fmt; use std::fmt;
use alga::general::Real; use alga::general::Real;
use base::{Matrix4, Vector, Vector3};
use base::dimension::U3; use base::dimension::U3;
use base::storage::Storage;
use base::helper; use base::helper;
use base::storage::Storage;
use base::{Matrix4, Vector, Vector3};
use geometry::Point3; use geometry::Point3;
@ -310,16 +311,19 @@ impl<N: Real> Orthographic3<N> {
} }
} }
impl<N: Real + Rand> Rand for Orthographic3<N> { impl<N: Real> Distribution<Orthographic3<N>> for Standard
fn rand<R: Rng>(r: &mut R) -> Self { where
let left = Rand::rand(r); Standard: Distribution<N>,
{
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Orthographic3<N> {
let left = r.gen();
let right = helper::reject_rand(r, |x: &N| *x > left); let right = helper::reject_rand(r, |x: &N| *x > left);
let bottom = Rand::rand(r); let bottom = r.gen();
let top = helper::reject_rand(r, |x: &N| *x > bottom); let top = helper::reject_rand(r, |x: &N| *x > bottom);
let znear = Rand::rand(r); let znear = r.gen();
let zfar = helper::reject_rand(r, |x: &N| *x > znear); let zfar = helper::reject_rand(r, |x: &N| *x > znear);
Self::new(left, right, bottom, top, znear, zfar) Orthographic3::new(left, right, bottom, top, znear, zfar)
} }
} }

View File

@ -1,6 +1,7 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
use serde; use serde;
@ -8,10 +9,10 @@ use std::fmt;
use alga::general::Real; use alga::general::Real;
use base::{Matrix4, Scalar, Vector, Vector3};
use base::dimension::U3; use base::dimension::U3;
use base::storage::Storage;
use base::helper; use base::helper;
use base::storage::Storage;
use base::{Matrix4, Scalar, Vector, Vector3};
use geometry::Point3; use geometry::Point3;
@ -245,13 +246,16 @@ impl<N: Real> Perspective3<N> {
} }
} }
impl<N: Real + Rand> Rand for Perspective3<N> { impl<N: Real> Distribution<Perspective3<N>> for Standard
fn rand<R: Rng>(r: &mut R) -> Self { where
let znear = Rand::rand(r); Standard: Distribution<N>,
{
fn sample<'a, R: Rng + ?Sized>(&self, r: &'a mut R) -> Perspective3<N> {
let znear = r.gen();
let zfar = helper::reject_rand(r, |&x: &N| !(x - znear).is_zero()); let zfar = helper::reject_rand(r, |&x: &N| !(x - znear).is_zero());
let aspect = helper::reject_rand(r, |&x: &N| !x.is_zero()); let aspect = helper::reject_rand(r, |&x: &N| !x.is_zero());
Self::new(aspect, Rand::rand(r), znear, zfar) Perspective3::new(aspect, r.gen(), znear, zfar)
} }
} }

View File

@ -1,13 +1,14 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use num::{Bounded, One, Zero}; use num::{Bounded, One, Zero};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::ClosedDiv; use alga::general::ClosedDiv;
use base::{DefaultAllocator, Scalar, VectorN};
use base::allocator::Allocator; use base::allocator::Allocator;
use base::dimension::{DimName, DimNameAdd, DimNameSum, U1, U2, U3, U4, U5, U6}; use base::dimension::{DimName, DimNameAdd, DimNameSum, U1, U2, U3, U4, U5, U6};
use base::{DefaultAllocator, Scalar, VectorN};
use geometry::Point; use geometry::Point;
@ -70,13 +71,14 @@ where
} }
} }
impl<N: Scalar + Rand, D: DimName> Rand for Point<N, D> impl<N: Scalar, D: DimName> Distribution<Point<N, D>> for Standard
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N>,
{ {
#[inline] #[inline]
fn rand<G: Rng>(rng: &mut G) -> Self { fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point<N, D> {
Point::from_coordinates(rng.gen()) Point::from_coordinates(rng.gen::<VectorN<N, D>>())
} }
} }

View File

@ -1,18 +1,19 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use base::dimension::U4;
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use base::storage::Owned; use base::storage::Owned;
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use base::dimension::U4; use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use num::{One, Zero}; use num::{One, Zero};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real; use alga::general::Real;
use base::{Unit, Vector, Vector3, Vector4};
use base::storage::Storage;
use base::dimension::U3; use base::dimension::U3;
use base::storage::Storage;
use base::{Unit, Vector, Vector3, Vector4};
use geometry::{Quaternion, Rotation, UnitQuaternion}; use geometry::{Quaternion, Rotation, UnitQuaternion};
@ -86,9 +87,12 @@ impl<N: Real> Zero for Quaternion<N> {
} }
} }
impl<N: Real + Rand> Rand for Quaternion<N> { impl<N: Real> Distribution<Quaternion<N>> for Standard
where
Standard: Distribution<N>,
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Self { fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> Quaternion<N> {
Quaternion::new(rng.gen(), rng.gen(), rng.gen(), rng.gen()) Quaternion::new(rng.gen(), rng.gen(), rng.gen(), rng.gen())
} }
} }
@ -407,11 +411,13 @@ impl<N: Real> One for UnitQuaternion<N> {
} }
} }
impl<N: Real + Rand> Rand for UnitQuaternion<N> { impl<N: Real> Distribution<UnitQuaternion<N>> for Standard
where
Standard: Distribution<N>,
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Self { fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> UnitQuaternion<N> {
let axisangle = Vector3::rand(rng); UnitQuaternion::from_scaled_axis(rng.gen::<Vector3<N>>() * N::two_pi())
UnitQuaternion::from_scaled_axis(axisangle)
} }
} }

View File

@ -1,16 +1,17 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
use base::storage::Owned; use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use std::ops::Neg;
use num::Zero;
use rand::{Rand, Rng};
use alga::general::Real; use alga::general::Real;
use num::Zero;
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use std::ops::Neg;
use base::{MatrixN, Unit, Vector, Vector1, Vector3, VectorN};
use base::dimension::{U1, U2, U3}; use base::dimension::{U1, U2, U3};
use base::storage::Storage; use base::storage::Storage;
use base::{MatrixN, Unit, Vector, Vector1, Vector3, VectorN};
use geometry::{Rotation2, Rotation3, UnitComplex}; use geometry::{Rotation2, Rotation3, UnitComplex};
@ -97,10 +98,13 @@ impl<N: Real> Rotation2<N> {
} }
} }
impl<N: Real + Rand> Rand for Rotation2<N> { impl<N: Real> Distribution<Rotation2<N>> for Standard
where
Standard: Distribution<N>,
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Self { fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> Rotation2<N> {
Self::new(rng.gen()) Rotation2::new(rng.gen())
} }
} }
@ -195,15 +199,19 @@ impl<N: Real> Rotation3<N> {
pub fn to_euler_angles(&self) -> (N, N, N) { pub fn to_euler_angles(&self) -> (N, N, N) {
// Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh // Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh
// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578
if self[(2,0)].abs() != N::one() { if self[(2, 0)].abs() != N::one() {
let yaw = -self[(2,0)].asin(); let yaw = -self[(2, 0)].asin();
let roll = (self[(2,1)] / yaw.cos()).atan2(self[(2,2)] / yaw.cos()); let roll = (self[(2, 1)] / yaw.cos()).atan2(self[(2, 2)] / yaw.cos());
let pitch = (self[(1,0)] / yaw.cos()).atan2(self[(0,0)] / yaw.cos()); let pitch = (self[(1, 0)] / yaw.cos()).atan2(self[(0, 0)] / yaw.cos());
(roll, yaw, pitch) (roll, yaw, pitch)
} else if self[(2,0)] == -N::one() { } else if self[(2, 0)] == -N::one() {
(self[(0,1)].atan2(self[(0,2)]), N::frac_pi_2(), N::zero()) (self[(0, 1)].atan2(self[(0, 2)]), N::frac_pi_2(), N::zero())
} else { } else {
(-self[(0,1)].atan2(-self[(0,2)]), -N::frac_pi_2(), N::zero()) (
-self[(0, 1)].atan2(-self[(0, 2)]),
-N::frac_pi_2(),
N::zero(),
)
} }
} }
@ -228,15 +236,7 @@ impl<N: Real> Rotation3<N> {
let yaxis = zaxis.cross(&xaxis).normalize(); let yaxis = zaxis.cross(&xaxis).normalize();
Self::from_matrix_unchecked(MatrixN::<N, U3>::new( Self::from_matrix_unchecked(MatrixN::<N, U3>::new(
xaxis.x, xaxis.x, yaxis.x, zaxis.x, xaxis.y, yaxis.y, zaxis.y, xaxis.z, yaxis.z, zaxis.z,
yaxis.x,
zaxis.x,
xaxis.y,
yaxis.y,
zaxis.y,
xaxis.z,
yaxis.z,
zaxis.z,
)) ))
} }
@ -382,10 +382,13 @@ impl<N: Real> Rotation3<N> {
} }
} }
impl<N: Real + Rand> Rand for Rotation3<N> { impl<N: Real> Distribution<Rotation3<N>> for Standard
where
Standard: Distribution<N>,
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Self { fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> Rotation3<N> {
Self::new(VectorN::rand(rng)) Rotation3::new(rng.gen::<Vector3<N>>() * N::two_pi())
} }
} }

View File

@ -1,20 +1,23 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
use base::storage::Owned; use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use num::One; use num::One;
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real; use alga::general::Real;
use alga::linear::Rotation as AlgaRotation; use alga::linear::Rotation as AlgaRotation;
use base::{DefaultAllocator, Vector2, Vector3};
use base::dimension::{DimName, U2, U3};
use base::allocator::Allocator; use base::allocator::Allocator;
use base::dimension::{DimName, U2, U3};
use base::{DefaultAllocator, Vector2, Vector3};
use geometry::{Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation, use geometry::{
UnitComplex, UnitQuaternion}; Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation, UnitComplex,
UnitQuaternion,
};
impl<N: Real, D: DimName, R> Similarity<N, D, R> impl<N: Real, D: DimName, R> Similarity<N, D, R>
where where
@ -40,19 +43,20 @@ where
} }
} }
impl<N: Real + Rand, D: DimName, R> Rand for Similarity<N, D, R> impl<N: Real, D: DimName, R> Distribution<Similarity<N, D, R>> for Standard
where where
R: AlgaRotation<Point<N, D>> + Rand, R: AlgaRotation<Point<N, D>>,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N> + Distribution<R>,
{ {
#[inline] #[inline]
fn rand<G: Rng>(rng: &mut G) -> Self { fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Similarity<N, D, R> {
let mut s = rng.gen(); let mut s = rng.gen();
while relative_eq!(s, N::zero()) { while relative_eq!(s, N::zero()) {
s = rng.gen() s = rng.gen()
} }
Self::from_isometry(rng.gen(), s) Similarity::from_isometry(rng.gen(), s)
} }
} }

View File

@ -1,16 +1,17 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
use base::storage::Owned; use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use num::{One, Zero}; use num::{One, Zero};
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::ClosedAdd; use alga::general::ClosedAdd;
use base::{DefaultAllocator, Scalar, VectorN};
use base::dimension::{DimName, U1, U2, U3, U4, U5, U6};
use base::allocator::Allocator; use base::allocator::Allocator;
use base::dimension::{DimName, U1, U2, U3, U4, U5, U6};
use base::{DefaultAllocator, Scalar, VectorN};
use geometry::Translation; use geometry::Translation;
@ -35,13 +36,14 @@ where
} }
} }
impl<N: Scalar + Rand, D: DimName> Rand for Translation<N, D> impl<N: Scalar, D: DimName> Distribution<Translation<N, D>> for Standard
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N>,
{ {
#[inline] #[inline]
fn rand<G: Rng>(rng: &mut G) -> Self { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> {
Self::from_vector(rng.gen()) Translation::from_vector(rng.gen::<VectorN<N, D>>())
} }
} }

View File

@ -3,7 +3,8 @@ use quickcheck::{Arbitrary, Gen};
use num::One; use num::One;
use num_complex::Complex; use num_complex::Complex;
use rand::{Rand, Rng}; use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real; use alga::general::Real;
use base::allocator::Allocator; use base::allocator::Allocator;
@ -150,10 +151,13 @@ impl<N: Real> One for UnitComplex<N> {
} }
} }
impl<N: Real + Rand> Rand for UnitComplex<N> { impl<N: Real> Distribution<UnitComplex<N>> for Standard
where
Standard: Distribution<N>,
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Self { fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<N> {
UnitComplex::from_angle(N::rand(rng)) UnitComplex::from_angle(rng.gen() * N::two_pi())
} }
} }