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]
typenum = "1.10"
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-complex = { version = "0.2.0-git", git = "https://github.com/rust-num/num-complex", default-features = false }
approx = { version = "0.1", default-features = false }
alga = { version = "0.5", default-features = false }
approx = { version = "0.2", default-features = false }
alga = { version = "0.5", path = "../alga/alga", default-features = false }
matrixmultiply = { version = "0.1", optional = true }
serde = { 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 num::{Bounded, One, Zero};
use rand::{self, distributions::Sample, Rand, Rng};
use rand::distributions::{Distribution, Standard};
use rand::{self, Rng};
use std::iter;
use typenum::{self, Cmp, Greater};
@ -231,14 +232,14 @@ where
#[cfg(feature = "std")]
pub fn new_random_generic(nrows: R, ncols: C) -> Self
where
N: Rand,
Standard: Distribution<N>,
{
Self::from_fn_generic(nrows, ncols, |_, _| rand::random())
}
/// Creates a matrix filled with random values from the given distribution.
#[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,
ncols: C,
distribution: &mut Distr,
@ -371,7 +372,7 @@ macro_rules! impl_constructors(
/// Creates a matrix filled with random values from the given distribution.
#[inline]
pub fn from_distribution<Distr: Sample<N> + ?Sized, G: Rng>(
pub fn from_distribution<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
$($args: usize,)*
distribution: &mut Distr,
rng: &mut G,
@ -380,8 +381,10 @@ macro_rules! impl_constructors(
}
}
impl<N: Scalar + Rand, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*>
where DefaultAllocator: Allocator<N $(, $Dims)*> {
impl<N: Scalar, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*>
where
DefaultAllocator: Allocator<N $(, $Dims)*>,
Standard: Distribution<N> {
/// Creates a matrix filled with random values.
#[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
DefaultAllocator: Allocator<N, R, C>,
Standard: Distribution<N>,
{
#[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 ncols = C::try_to_usize().unwrap_or(rng.gen_range(0, 10));
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
rng.gen()
})
MatrixMN::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
}
}

View File

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

View File

@ -1,16 +1,17 @@
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
#[cfg(feature = "serde-serialize")]
use serde;
use std::fmt;
use alga::general::Real;
use base::{Matrix4, Vector, Vector3};
use base::dimension::U3;
use base::storage::Storage;
use base::helper;
use base::storage::Storage;
use base::{Matrix4, Vector, Vector3};
use geometry::Point3;
@ -310,16 +311,19 @@ impl<N: Real> Orthographic3<N> {
}
}
impl<N: Real + Rand> Rand for Orthographic3<N> {
fn rand<R: Rng>(r: &mut R) -> Self {
let left = Rand::rand(r);
impl<N: Real> Distribution<Orthographic3<N>> for Standard
where
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 bottom = Rand::rand(r);
let bottom = r.gen();
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);
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")]
use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
#[cfg(feature = "serde-serialize")]
use serde;
@ -8,10 +9,10 @@ use std::fmt;
use alga::general::Real;
use base::{Matrix4, Scalar, Vector, Vector3};
use base::dimension::U3;
use base::storage::Storage;
use base::helper;
use base::storage::Storage;
use base::{Matrix4, Scalar, Vector, Vector3};
use geometry::Point3;
@ -245,13 +246,16 @@ impl<N: Real> Perspective3<N> {
}
}
impl<N: Real + Rand> Rand for Perspective3<N> {
fn rand<R: Rng>(r: &mut R) -> Self {
let znear = Rand::rand(r);
impl<N: Real> Distribution<Perspective3<N>> for Standard
where
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 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")]
use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use num::{Bounded, One, Zero};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::ClosedDiv;
use base::{DefaultAllocator, Scalar, VectorN};
use base::allocator::Allocator;
use base::dimension::{DimName, DimNameAdd, DimNameSum, U1, U2, U3, U4, U5, U6};
use base::{DefaultAllocator, Scalar, VectorN};
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
DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N>,
{
#[inline]
fn rand<G: Rng>(rng: &mut G) -> Self {
Point::from_coordinates(rng.gen())
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point<N, D> {
Point::from_coordinates(rng.gen::<VectorN<N, D>>())
}
}

View File

@ -1,18 +1,19 @@
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use base::dimension::U4;
#[cfg(feature = "arbitrary")]
use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use base::dimension::U4;
use quickcheck::{Arbitrary, Gen};
use rand::{Rand, Rng};
use num::{One, Zero};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real;
use base::{Unit, Vector, Vector3, Vector4};
use base::storage::Storage;
use base::dimension::U3;
use base::storage::Storage;
use base::{Unit, Vector, Vector3, Vector4};
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]
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())
}
}
@ -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]
fn rand<R: Rng>(rng: &mut R) -> Self {
let axisangle = Vector3::rand(rng);
UnitQuaternion::from_scaled_axis(axisangle)
fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> UnitQuaternion<N> {
UnitQuaternion::from_scaled_axis(rng.gen::<Vector3<N>>() * N::two_pi())
}
}

View File

@ -1,16 +1,17 @@
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
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 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::storage::Storage;
use base::{MatrixN, Unit, Vector, Vector1, Vector3, VectorN};
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]
fn rand<R: Rng>(rng: &mut R) -> Self {
Self::new(rng.gen())
fn sample<'a, R: Rng + ?Sized>(&self, rng: &'a mut R) -> Rotation2<N> {
Rotation2::new(rng.gen())
}
}
@ -195,15 +199,19 @@ impl<N: Real> Rotation3<N> {
pub fn to_euler_angles(&self) -> (N, N, N) {
// 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
if self[(2,0)].abs() != N::one() {
let yaw = -self[(2,0)].asin();
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());
if self[(2, 0)].abs() != N::one() {
let yaw = -self[(2, 0)].asin();
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());
(roll, yaw, pitch)
} else if self[(2,0)] == -N::one() {
(self[(0,1)].atan2(self[(0,2)]), N::frac_pi_2(), N::zero())
} else if self[(2, 0)] == -N::one() {
(self[(0, 1)].atan2(self[(0, 2)]), N::frac_pi_2(), N::zero())
} 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();
Self::from_matrix_unchecked(MatrixN::<N, U3>::new(
xaxis.x,
yaxis.x,
zaxis.x,
xaxis.y,
yaxis.y,
zaxis.y,
xaxis.z,
yaxis.z,
zaxis.z,
xaxis.x, 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]
fn rand<R: Rng>(rng: &mut R) -> Self {
Self::new(VectorN::rand(rng))
fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> Rotation3<N> {
Rotation3::new(rng.gen::<Vector3<N>>() * N::two_pi())
}
}

View File

@ -1,20 +1,23 @@
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "arbitrary")]
use base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use num::One;
use rand::{Rand, Rng};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real;
use alga::linear::Rotation as AlgaRotation;
use base::{DefaultAllocator, Vector2, Vector3};
use base::dimension::{DimName, U2, U3};
use base::allocator::Allocator;
use base::dimension::{DimName, U2, U3};
use base::{DefaultAllocator, Vector2, Vector3};
use geometry::{Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation,
UnitComplex, UnitQuaternion};
use geometry::{
Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation, UnitComplex,
UnitQuaternion,
};
impl<N: Real, D: DimName, R> Similarity<N, D, R>
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
R: AlgaRotation<Point<N, D>> + Rand,
R: AlgaRotation<Point<N, D>>,
DefaultAllocator: Allocator<N, D>,
Standard: Distribution<N> + Distribution<R>,
{
#[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();
while relative_eq!(s, N::zero()) {
s = rng.gen()
}
Self::from_isometry(rng.gen(), s)
Similarity::from_isometry(rng.gen(), s)
}
}

View File

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

View File

@ -3,7 +3,8 @@ use quickcheck::{Arbitrary, Gen};
use num::One;
use num_complex::Complex;
use rand::{Rand, Rng};
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use alga::general::Real;
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]
fn rand<R: Rng>(rng: &mut R) -> Self {
UnitComplex::from_angle(N::rand(rng))
fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<N> {
UnitComplex::from_angle(rng.gen() * N::two_pi())
}
}