2019-03-03 02:33:49 +08:00
|
|
|
// This module implement several methods to fill some
|
|
|
|
// missing features of num-complex when it comes to randomness.
|
|
|
|
|
|
|
|
use quickcheck::{Arbitrary, Gen};
|
|
|
|
use rand::distributions::{Standard, Distribution};
|
|
|
|
use rand::Rng;
|
|
|
|
use num_complex::Complex;
|
2019-03-25 18:21:41 +08:00
|
|
|
use na::RealField;
|
2019-03-03 02:33:49 +08:00
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub struct RandComplex<N>(pub Complex<N>);
|
|
|
|
|
2019-03-25 18:21:41 +08:00
|
|
|
impl<N: Arbitrary + RealField> Arbitrary for RandComplex<N> {
|
2019-03-03 02:33:49 +08:00
|
|
|
#[inline]
|
|
|
|
fn arbitrary<G: Gen>(rng: &mut G) -> Self {
|
|
|
|
let im = Arbitrary::arbitrary(rng);
|
|
|
|
let re = Arbitrary::arbitrary(rng);
|
|
|
|
RandComplex(Complex::new(re, im))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-25 18:21:41 +08:00
|
|
|
impl<N: RealField> Distribution<RandComplex<N>> for Standard
|
2019-03-03 02:33:49 +08:00
|
|
|
where
|
|
|
|
Standard: Distribution<N>,
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> RandComplex<N> {
|
|
|
|
let re = rng.gen();
|
|
|
|
let im = rng.gen();
|
|
|
|
RandComplex(Complex::new(re, im))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is a wrapper similar to RandComplex, but for non-complex.
|
|
|
|
// This exists only to make generic tests easier to write.
|
2019-07-26 22:29:16 +08:00
|
|
|
// Generates variates in the range [0, 1). Do we want this? E.g. we could use standard normal samples instead.
|
2019-03-03 02:33:49 +08:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub struct RandScalar<N>(pub N);
|
|
|
|
|
|
|
|
impl<N: Arbitrary> Arbitrary for RandScalar<N> {
|
|
|
|
#[inline]
|
|
|
|
fn arbitrary<G: Gen>(rng: &mut G) -> Self {
|
|
|
|
RandScalar(Arbitrary::arbitrary(rng))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-25 18:21:41 +08:00
|
|
|
impl<N: RealField> Distribution<RandScalar<N>> for Standard
|
2019-03-03 02:33:49 +08:00
|
|
|
where
|
|
|
|
Standard: Distribution<N>,
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> RandScalar<N> {
|
|
|
|
RandScalar(self.sample(rng))
|
|
|
|
}
|
|
|
|
}
|