rustfmt src/librand

This commit is contained in:
Marcello Seri 2015-10-16 22:38:49 +01:00
parent 747d951e88
commit 76b69e365b
10 changed files with 1409 additions and 416 deletions

View File

@ -27,15 +27,15 @@ const CHACHA_ROUNDS: usize = 20; // Cryptographically secure from 8 upwards as o
/// Salsa20*](http://cr.yp.to/chacha.html)
#[derive(Copy, Clone)]
pub struct ChaChaRng {
buffer: [u32; STATE_WORDS], // Internal buffer of output
state: [u32; STATE_WORDS], // Initial state
index: usize, // Index into state
buffer: [u32; STATE_WORDS], // Internal buffer of output
state: [u32; STATE_WORDS], // Initial state
index: usize, // Index into state
}
static EMPTY: ChaChaRng = ChaChaRng {
buffer: [0; STATE_WORDS],
state: [0; STATE_WORDS],
index: STATE_WORDS
buffer: [0; STATE_WORDS],
state: [0; STATE_WORDS],
index: STATE_WORDS,
};
@ -95,9 +95,9 @@ impl ChaChaRng {
/// associated with a particular nonce can call this function with
/// arguments `0, desired_nonce`.
pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
self.state[12] = (counter_low >> 0) as u32;
self.state[12] = (counter_low >> 0) as u32;
self.state[13] = (counter_low >> 32) as u32;
self.state[14] = (counter_high >> 0) as u32;
self.state[14] = (counter_high >> 0) as u32;
self.state[15] = (counter_high >> 32) as u32;
self.index = STATE_WORDS; // force recomputation
}
@ -127,7 +127,7 @@ impl ChaChaRng {
self.state[3] = 0x6B206574;
for i in 0..KEY_WORDS {
self.state[4+i] = key[i];
self.state[4 + i] = key[i];
}
self.state[12] = 0;
@ -144,11 +144,17 @@ impl ChaChaRng {
self.index = 0;
// update 128-bit counter
self.state[12] += 1;
if self.state[12] != 0 { return };
if self.state[12] != 0 {
return;
}
self.state[13] += 1;
if self.state[13] != 0 { return };
if self.state[13] != 0 {
return;
}
self.state[14] += 1;
if self.state[14] != 0 { return };
if self.state[14] != 0 {
return;
}
self.state[15] += 1;
}
}
@ -172,7 +178,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {
// reset state
self.init(&[0; KEY_WORDS]);
// set key in place
let key = &mut self.state[4 .. 4+KEY_WORDS];
let key = &mut self.state[4..4 + KEY_WORDS];
for (k, s) in key.iter_mut().zip(seed) {
*k = *s;
}
@ -191,7 +197,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {
impl Rand for ChaChaRng {
fn rand<R: Rng>(other: &mut R) -> ChaChaRng {
let mut key : [u32; KEY_WORDS] = [0; KEY_WORDS];
let mut key: [u32; KEY_WORDS] = [0; KEY_WORDS];
for word in &mut key {
*word = other.gen();
}
@ -219,7 +225,7 @@ mod tests {
#[test]
fn test_rng_seeded() {
let seed : &[_] = &[0,1,2,3,4,5,6,7];
let seed: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
assert!(order::equals(ra.gen_ascii_chars().take(100),
@ -242,30 +248,54 @@ mod tests {
fn test_rng_true_values() {
// Test vectors 1 and 2 from
// http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
let seed : &[_] = &[0; 8];
let seed: &[_] = &[0; 8];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653,
0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b,
0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8,
0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2));
vec!(0xade0b876,
0x903df1a0,
0xe56a5d40,
0x28bd8653,
0xb819d2bd,
0x1aed8da0,
0xccef36a8,
0xc70d778b,
0x7c5941da,
0x8d485751,
0x3fe02477,
0x374ad8b8,
0xf4b8436a,
0x1ca11815,
0x69b687c3,
0x8665eeb2));
let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73,
0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32,
0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874,
0x281fed31, 0x45fb0a51, 0x1f0ae1ac, 0x6f4d794b));
vec!(0xbee7079f,
0x7a385155,
0x7c97ba98,
0x0d082d73,
0xa0290fcb,
0x6965e348,
0x3e53c612,
0xed7aee32,
0x7621b729,
0x434ee69c,
0xb03371d5,
0xd539d874,
0x281fed31,
0x45fb0a51,
0x1f0ae1ac,
0x6f4d794b));
let seed : &[_] = &[0,1,2,3,4,5,6,7];
let seed: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
// Store the 17*i-th 32-bit word,
// i.e., the i-th word of the i-th 16-word block
let mut v : Vec<u32> = Vec::new();
let mut v: Vec<u32> = Vec::new();
for _ in 0..16 {
v.push(ra.next_u32());
for _ in 0..16 {
@ -274,15 +304,27 @@ mod tests {
}
assert_eq!(v,
vec!(0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036,
0x49884684, 0x64efec72, 0x4be2d186, 0x3615b384,
0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
vec!(0xf225c81a,
0x6ab1be57,
0x04d42951,
0x70858036,
0x49884684,
0x64efec72,
0x4be2d186,
0x3615b384,
0x11cfa18e,
0xd3c50049,
0x75c775f6,
0x434c6530,
0x2c5bad8f,
0x898881dc,
0x5f1c86d9,
0xc1f8e7f4));
}
#[test]
fn test_rng_clone() {
let seed : &[_] = &[0; 8];
let seed: &[_] = &[0; 8];
let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
let mut clone = rng.clone();
for _ in 0..16 {

View File

@ -35,20 +35,22 @@ pub struct Exp1(pub f64);
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
impl Rand for Exp1 {
#[inline]
fn rand<R:Rng>(rng: &mut R) -> Exp1 {
fn rand<R: Rng>(rng: &mut R) -> Exp1 {
#[inline]
fn pdf(x: f64) -> f64 {
(-x).exp()
}
#[inline]
fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
fn zero_case<R: Rng>(rng: &mut R, _u: f64) -> f64 {
ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
}
Exp1(ziggurat(rng, false,
Exp1(ziggurat(rng,
false,
&ziggurat_tables::ZIG_EXP_X,
&ziggurat_tables::ZIG_EXP_F,
pdf, zero_case))
pdf,
zero_case))
}
}
@ -59,7 +61,7 @@ impl Rand for Exp1 {
#[derive(Copy, Clone)]
pub struct Exp {
/// `lambda` stored as `1/lambda`, since this is what we scale by.
lambda_inverse: f64
lambda_inverse: f64,
}
impl Exp {
@ -72,7 +74,9 @@ impl Exp {
}
impl Sample<f64> for Exp {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl IndependentSample<f64> for Exp {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {

View File

@ -46,7 +46,7 @@ pub struct Gamma {
enum GammaRepr {
Large(GammaLargeShape),
One(Exp),
Small(GammaSmallShape)
Small(GammaSmallShape),
}
// These two helpers could be made public, but saving the
@ -65,7 +65,7 @@ enum GammaRepr {
/// shape parameters.
struct GammaSmallShape {
inv_shape: f64,
large_shape: GammaLargeShape
large_shape: GammaLargeShape,
}
/// Gamma distribution where the shape parameter is larger than 1.
@ -75,7 +75,7 @@ struct GammaSmallShape {
struct GammaLargeShape {
scale: f64,
c: f64,
d: f64
d: f64,
}
impl Gamma {
@ -88,9 +88,9 @@ impl Gamma {
assert!(scale > 0.0, "Gamma::new called with scale <= 0");
let repr = match shape {
1.0 => One(Exp::new(1.0 / scale)),
1.0 => One(Exp::new(1.0 / scale)),
0.0 ... 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
_ => Large(GammaLargeShape::new_raw(shape, scale))
_ => Large(GammaLargeShape::new_raw(shape, scale)),
};
Gamma { repr: repr }
}
@ -100,7 +100,7 @@ impl GammaSmallShape {
fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
GammaSmallShape {
inv_shape: 1. / shape,
large_shape: GammaLargeShape::new_raw(shape + 1.0, scale)
large_shape: GammaLargeShape::new_raw(shape + 1.0, scale),
}
}
}
@ -111,19 +111,25 @@ impl GammaLargeShape {
GammaLargeShape {
scale: scale,
c: 1. / (9. * d).sqrt(),
d: d
d: d,
}
}
}
impl Sample<f64> for Gamma {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl Sample<f64> for GammaSmallShape {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl Sample<f64> for GammaLargeShape {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl IndependentSample<f64> for Gamma {
@ -148,7 +154,7 @@ impl IndependentSample<f64> for GammaLargeShape {
let StandardNormal(x) = rng.gen::<StandardNormal>();
let v_cbrt = 1.0 + self.c * x;
if v_cbrt <= 0.0 { // a^3 <= 0 iff a <= 0
continue
continue;
}
let v = v_cbrt * v_cbrt * v_cbrt;
@ -156,8 +162,8 @@ impl IndependentSample<f64> for GammaLargeShape {
let x_sqr = x * x;
if u < 1.0 - 0.0331 * x_sqr * x_sqr ||
u.ln() < 0.5 * x_sqr + self.d * (1.0 - v + v.ln()) {
return self.d * v * self.scale
u.ln() < 0.5 * x_sqr + self.d * (1.0 - v + v.ln()) {
return self.d * v * self.scale;
}
}
}
@ -196,7 +202,9 @@ impl ChiSquared {
}
}
impl Sample<f64> for ChiSquared {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl IndependentSample<f64> for ChiSquared {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
@ -206,7 +214,7 @@ impl IndependentSample<f64> for ChiSquared {
let StandardNormal(norm) = rng.gen::<StandardNormal>();
norm * norm
}
DoFAnythingElse(ref g) => g.ind_sample(rng)
DoFAnythingElse(ref g) => g.ind_sample(rng),
}
}
}
@ -234,12 +242,14 @@ impl FisherF {
FisherF {
numer: ChiSquared::new(m),
denom: ChiSquared::new(n),
dof_ratio: n / m
dof_ratio: n / m,
}
}
}
impl Sample<f64> for FisherF {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl IndependentSample<f64> for FisherF {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
@ -251,7 +261,7 @@ impl IndependentSample<f64> for FisherF {
/// freedom.
pub struct StudentT {
chi: ChiSquared,
dof: f64
dof: f64,
}
impl StudentT {
@ -261,12 +271,14 @@ impl StudentT {
assert!(n > 0.0, "StudentT::new called with `n <= 0`");
StudentT {
chi: ChiSquared::new(n),
dof: n
dof: n,
}
}
}
impl Sample<f64> for StudentT {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
impl IndependentSample<f64> for StudentT {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {

View File

@ -54,7 +54,9 @@ pub trait IndependentSample<Support>: Sample<Support> {
/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
pub struct RandSample<Sup> { _marker: PhantomData<Sup> }
pub struct RandSample<Sup> {
_marker: PhantomData<Sup>,
}
impl<Sup> RandSample<Sup> {
pub fn new() -> RandSample<Sup> {
@ -63,7 +65,9 @@ impl<Sup> RandSample<Sup> {
}
impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup {
self.ind_sample(rng)
}
}
impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
@ -89,9 +93,9 @@ pub struct Weighted<T> {
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
/// all `T`, as is `usize`, so one can store references or indices into
/// another vector.
pub struct WeightedChoice<'a, T:'a> {
pub struct WeightedChoice<'a, T: 'a> {
items: &'a mut [Weighted<T>],
weight_range: Range<usize>
weight_range: Range<usize>,
}
impl<'a, T: Clone> WeightedChoice<'a, T> {
@ -103,7 +107,8 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
/// - the total weight is larger than a `usize` can contain.
pub fn new(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
// strictly speaking, this is subsumed by the total weight == 0 case
assert!(!items.is_empty(), "WeightedChoice::new called with no items");
assert!(!items.is_empty(),
"WeightedChoice::new called with no items");
let mut running_total = 0_usize;
@ -113,25 +118,28 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
for item in &mut *items {
running_total = match running_total.checked_add(item.weight) {
Some(n) => n,
None => panic!("WeightedChoice::new called with a total weight \
larger than a usize can contain")
None => panic!("WeightedChoice::new called with a total weight larger than a \
usize can contain"),
};
item.weight = running_total;
}
assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
assert!(running_total != 0,
"WeightedChoice::new called with a total weight of 0");
WeightedChoice {
items: items,
// we're likely to be generating numbers in this range
// relatively often, so might as well cache it
weight_range: Range::new(0, running_total)
weight_range: Range::new(0, running_total),
}
}
}
impl<'a, T: Clone> Sample<T> for WeightedChoice<'a, T> {
fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> T {
self.ind_sample(rng)
}
}
impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> {
@ -191,18 +199,19 @@ mod ziggurat_tables;
/// * `pdf`: the probability density function
/// * `zero_case`: manual sampling from the tail when we chose the
/// bottom box (i.e. i == 0)
// the perf improvement (25-50%) is definitely worth the extra code
// size from force-inlining.
#[inline(always)]
fn ziggurat<R: Rng, P, Z>(
rng: &mut R,
symmetric: bool,
x_tab: ziggurat_tables::ZigTable,
f_tab: ziggurat_tables::ZigTable,
mut pdf: P,
mut zero_case: Z)
-> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
fn ziggurat<R: Rng, P, Z>(rng: &mut R,
symmetric: bool,
x_tab: ziggurat_tables::ZigTable,
f_tab: ziggurat_tables::ZigTable,
mut pdf: P,
mut zero_case: Z)
-> f64
where P: FnMut(f64) -> f64,
Z: FnMut(&mut R, f64) -> f64
{
const SCALE: f64 = (1u64 << 53) as f64;
loop {
// reimplement the f64 generation as an optimisation suggested
@ -224,10 +233,18 @@ fn ziggurat<R: Rng, P, Z>(
// u is either U(-1, 1) or U(0, 1) depending on if this is a
// symmetric distribution or not.
let u = if symmetric {2.0 * f - 1.0} else {f};
let u = if symmetric {
2.0 * f - 1.0
} else {
f
};
let x = u * x_tab[i];
let test_x = if symmetric { x.abs() } else {x};
let test_x = if symmetric {
x.abs()
} else {
x
};
// algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
if test_x < x_tab[i + 1] {
@ -259,7 +276,9 @@ mod tests {
}
// 0, 1, 2, 3, ...
struct CountingRng { i: u32 }
struct CountingRng {
i: u32,
}
impl Rng for CountingRng {
fn next_u32(&mut self) -> u32 {
self.i += 1;
@ -298,54 +317,133 @@ mod tests {
}}
}
t!(vec!(Weighted { weight: 1, item: 10}), [10]);
t!(vec!(Weighted {
weight: 1,
item: 10,
}),
[10]);
// skip some
t!(vec!(Weighted { weight: 0, item: 20},
Weighted { weight: 2, item: 21},
Weighted { weight: 0, item: 22},
Weighted { weight: 1, item: 23}),
[21,21, 23]);
t!(vec!(Weighted {
weight: 0,
item: 20,
},
Weighted {
weight: 2,
item: 21,
},
Weighted {
weight: 0,
item: 22,
},
Weighted {
weight: 1,
item: 23,
}),
[21, 21, 23]);
// different weights
t!(vec!(Weighted { weight: 4, item: 30},
Weighted { weight: 3, item: 31}),
[30,30,30,30, 31,31,31]);
t!(vec!(Weighted {
weight: 4,
item: 30,
},
Weighted {
weight: 3,
item: 31,
}),
[30, 30, 30, 30, 31, 31, 31]);
// check that we're binary searching
// correctly with some vectors of odd
// length.
t!(vec!(Weighted { weight: 1, item: 40},
Weighted { weight: 1, item: 41},
Weighted { weight: 1, item: 42},
Weighted { weight: 1, item: 43},
Weighted { weight: 1, item: 44}),
t!(vec!(Weighted {
weight: 1,
item: 40,
},
Weighted {
weight: 1,
item: 41,
},
Weighted {
weight: 1,
item: 42,
},
Weighted {
weight: 1,
item: 43,
},
Weighted {
weight: 1,
item: 44,
}),
[40, 41, 42, 43, 44]);
t!(vec!(Weighted { weight: 1, item: 50},
Weighted { weight: 1, item: 51},
Weighted { weight: 1, item: 52},
Weighted { weight: 1, item: 53},
Weighted { weight: 1, item: 54},
Weighted { weight: 1, item: 55},
Weighted { weight: 1, item: 56}),
t!(vec!(Weighted {
weight: 1,
item: 50,
},
Weighted {
weight: 1,
item: 51,
},
Weighted {
weight: 1,
item: 52,
},
Weighted {
weight: 1,
item: 53,
},
Weighted {
weight: 1,
item: 54,
},
Weighted {
weight: 1,
item: 55,
},
Weighted {
weight: 1,
item: 56,
}),
[50, 51, 52, 53, 54, 55, 56]);
}
#[test] #[should_panic]
#[test]
#[should_panic]
fn test_weighted_choice_no_items() {
WeightedChoice::<isize>::new(&mut []);
}
#[test] #[should_panic]
#[test]
#[should_panic]
fn test_weighted_choice_zero_weight() {
WeightedChoice::new(&mut [Weighted { weight: 0, item: 0},
Weighted { weight: 0, item: 1}]);
WeightedChoice::new(&mut [Weighted {
weight: 0,
item: 0,
},
Weighted {
weight: 0,
item: 1,
}]);
}
#[test] #[should_panic]
#[test]
#[should_panic]
fn test_weighted_choice_weight_overflows() {
let x = (!0) as usize / 2; // x + x + 2 is the overflow
WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
Weighted { weight: 1, item: 1 },
Weighted { weight: x, item: 2 },
Weighted { weight: 1, item: 3 }]);
WeightedChoice::new(&mut [Weighted {
weight: x,
item: 0,
},
Weighted {
weight: 1,
item: 1,
},
Weighted {
weight: x,
item: 2,
},
Weighted {
weight: 1,
item: 3,
}]);
}
}

View File

@ -32,7 +32,7 @@ use distributions::{Sample, IndependentSample};
pub struct Range<X> {
low: X,
range: X,
accept_zone: X
accept_zone: X,
}
impl<X: SampleRange + PartialOrd> Range<X> {
@ -46,7 +46,9 @@ impl<X: SampleRange + PartialOrd> Range<X> {
impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
#[inline]
fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup {
self.ind_sample(rng)
}
}
impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
@ -148,7 +150,7 @@ float_impl! { f64 }
mod tests {
use std::prelude::v1::*;
use distributions::{Sample, IndependentSample};
use super::Range as Range;
use super::Range;
#[should_panic]
#[test]
@ -182,8 +184,7 @@ mod tests {
)*
}}
}
t!(i8, i16, i32, i64, isize,
u8, u16, u32, u64, usize)
t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize)
}
#[test]

File diff suppressed because it is too large Load Diff

View File

@ -48,7 +48,9 @@ static EMPTY: IsaacRng = IsaacRng {
cnt: 0,
rsl: [w(0); RAND_SIZE_USIZE],
mem: [w(0); RAND_SIZE_USIZE],
a: w(0), b: w(0), c: w(0),
a: w(0),
b: w(0),
c: w(0),
};
impl IsaacRng {
@ -113,10 +115,14 @@ impl IsaacRng {
} else {
for i in (0..RAND_SIZE_USIZE).step_by(8) {
mix!();
self.mem[i ]=a; self.mem[i+1]=b;
self.mem[i+2]=c; self.mem[i+3]=d;
self.mem[i+4]=e; self.mem[i+5]=f;
self.mem[i+6]=g; self.mem[i+7]=h;
self.mem[i] = a;
self.mem[i + 1] = b;
self.mem[i + 2] = c;
self.mem[i + 3] = d;
self.mem[i + 4] = e;
self.mem[i + 5] = f;
self.mem[i + 6] = g;
self.mem[i + 7] = h;
}
}
@ -290,7 +296,9 @@ static EMPTY_64: Isaac64Rng = Isaac64Rng {
cnt: 0,
rsl: [w(0); RAND_SIZE_64],
mem: [w(0); RAND_SIZE_64],
a: w(0), b: w(0), c: w(0),
a: w(0),
b: w(0),
c: w(0),
};
impl Isaac64Rng {
@ -311,8 +319,14 @@ impl Isaac64Rng {
let mut $var = w(0x9e3779b97f4a7c13);
)
}
init!(a); init!(b); init!(c); init!(d);
init!(e); init!(f); init!(g); init!(h);
init!(a);
init!(b);
init!(c);
init!(d);
init!(e);
init!(f);
init!(g);
init!(h);
macro_rules! mix {
() => {{
@ -353,10 +367,14 @@ impl Isaac64Rng {
} else {
for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
mix!();
self.mem[i ]=a; self.mem[i+1]=b;
self.mem[i+2]=c; self.mem[i+3]=d;
self.mem[i+4]=e; self.mem[i+5]=f;
self.mem[i+6]=g; self.mem[i+7]=h;
self.mem[i] = a;
self.mem[i + 1] = b;
self.mem[i + 2] = c;
self.mem[i + 3] = d;
self.mem[i + 4] = e;
self.mem[i + 5] = f;
self.mem[i + 6] = g;
self.mem[i + 7] = h;
}
}
@ -370,7 +388,7 @@ impl Isaac64Rng {
let mut a = self.a;
let mut b = self.b + self.c;
const MIDPOINT: usize = RAND_SIZE_64 / 2;
const MP_VEC: [(usize, usize); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
const MP_VEC: [(usize, usize); 2] = [(0, MIDPOINT), (MIDPOINT, 0)];
macro_rules! ind {
($x:expr) => {
*self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
@ -579,18 +597,36 @@ mod tests {
// Regression test that isaac is actually using the above vector
let v = (0..10).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(2558573138, 873787463, 263499565, 2103644246, 3595684709,
4203127393, 264982119, 2765226902, 2737944514, 3900253796));
vec!(2558573138,
873787463,
263499565,
2103644246,
3595684709,
4203127393,
264982119,
2765226902,
2737944514,
3900253796));
let seed: &[_] = &[12345, 67890, 54321, 9876];
let mut rb: IsaacRng = SeedableRng::from_seed(seed);
// skip forward to the 10000th number
for _ in 0..10000 { rb.next_u32(); }
for _ in 0..10000 {
rb.next_u32();
}
let v = (0..10).map(|_| rb.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
1576568959, 3507990155, 179069555, 141456972, 2478885421));
vec!(3676831399,
3183332890,
2834741178,
3854698763,
2717568474,
1576568959,
3507990155,
179069555,
141456972,
2478885421));
}
#[test]
fn test_rng_64_true_values() {
@ -599,21 +635,35 @@ mod tests {
// Regression test that isaac is actually using the above vector
let v = (0..10).map(|_| ra.next_u64()).collect::<Vec<_>>();
assert_eq!(v,
vec!(547121783600835980, 14377643087320773276, 17351601304698403469,
1238879483818134882, 11952566807690396487, 13970131091560099343,
4469761996653280935, 15552757044682284409, 6860251611068737823,
vec!(547121783600835980,
14377643087320773276,
17351601304698403469,
1238879483818134882,
11952566807690396487,
13970131091560099343,
4469761996653280935,
15552757044682284409,
6860251611068737823,
13722198873481261842));
let seed: &[_] = &[12345, 67890, 54321, 9876];
let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
// skip forward to the 10000th number
for _ in 0..10000 { rb.next_u64(); }
for _ in 0..10000 {
rb.next_u64();
}
let v = (0..10).map(|_| rb.next_u64()).collect::<Vec<_>>();
assert_eq!(v,
vec!(18143823860592706164, 8491801882678285927, 2699425367717515619,
17196852593171130876, 2606123525235546165, 15790932315217671084,
596345674630742204, 9947027391921273664, 11788097613744130851,
vec!(18143823860592706164,
8491801882678285927,
2699425367717515619,
17196852593171130876,
2606123525235546165,
15790932315217671084,
596345674630742204,
9947027391921273664,
11788097613744130851,
10391409374914919106));
}

View File

@ -41,8 +41,12 @@
#![allow(deprecated)]
#[cfg(test)] #[macro_use] extern crate std;
#[cfg(test)] #[macro_use] extern crate log;
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
#[macro_use]
extern crate log;
use core::f64;
use core::intrinsics;
@ -217,7 +221,10 @@ pub trait Rng : Sized {
/// Return an iterator that will yield an infinite number of randomly
/// generated items.
fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
Generator { rng: self, _marker: PhantomData }
Generator {
rng: self,
_marker: PhantomData,
}
}
/// Generate a random value in the range [`low`, `high`).
@ -272,9 +279,9 @@ pub trait Rng : Sized {
/// Iterator which will generate a stream of random items.
///
/// This iterator is created via the `gen_iter` method on `Rng`.
pub struct Generator<'a, T, R:'a> {
pub struct Generator<'a, T, R: 'a> {
rng: &'a mut R,
_marker: PhantomData<T>
_marker: PhantomData<T>,
}
impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
@ -288,7 +295,7 @@ impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
/// Iterator which will continuously generate random ascii characters.
///
/// This iterator is created via the `gen_ascii_chars` method on `Rng`.
pub struct AsciiGenerator<'a, R:'a> {
pub struct AsciiGenerator<'a, R: 'a> {
rng: &'a mut R,
}
@ -384,7 +391,7 @@ impl SeedableRng<[u32; 4]> for XorShiftRng {
x: seed[0],
y: seed[1],
z: seed[2],
w: seed[3]
w: seed[3],
}
}
}
@ -396,7 +403,12 @@ impl Rand for XorShiftRng {
tuple = rng.gen();
}
let (x, y, z, w) = tuple;
XorShiftRng { x: x, y: y, z: z, w: w }
XorShiftRng {
x: x,
y: y,
z: z,
w: w,
}
}
}
@ -420,7 +432,9 @@ pub struct Closed01<F>(pub F);
mod test {
use std::__rand as rand;
pub struct MyRng<R> { inner: R }
pub struct MyRng<R> {
inner: R,
}
impl<R: rand::Rng> ::Rng for MyRng<R> {
fn next_u32(&mut self) -> u32 {

View File

@ -14,7 +14,7 @@ use core::char;
use core::isize;
use core::usize;
use {Rand,Rng};
use {Rand, Rng};
impl Rand for isize {
#[inline]
@ -185,7 +185,9 @@ macro_rules! tuple_impl {
impl Rand for () {
#[inline]
fn rand<R: Rng>(_: &mut R) -> () { () }
fn rand<R: Rng>(_: &mut R) -> () {
()
}
}
tuple_impl!{A}
tuple_impl!{A, B}

View File

@ -35,12 +35,12 @@ impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
/// * `rng`: the random number generator to use.
/// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
/// * `reseeder`: the reseeding object to use.
pub fn new(rng: R, generation_threshold: usize, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
pub fn new(rng: R, generation_threshold: usize, reseeder: Rsdr) -> ReseedingRng<R, Rsdr> {
ReseedingRng {
rng: rng,
generation_threshold: generation_threshold,
bytes_generated: 0,
reseeder: reseeder
reseeder: reseeder,
}
}
@ -90,7 +90,7 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
rng: SeedableRng::from_seed(seed),
generation_threshold: DEFAULT_GENERATION_THRESHOLD,
bytes_generated: 0,
reseeder: rsdr
reseeder: rsdr,
}
}
}
@ -114,7 +114,9 @@ impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
#[stable(feature = "rust1", since = "1.0.0")]
impl Default for ReseedWithDefault {
#[stable(feature = "rust1", since = "1.0.0")]
fn default() -> ReseedWithDefault { ReseedWithDefault }
fn default() -> ReseedWithDefault {
ReseedWithDefault
}
}
#[cfg(test)]
@ -126,7 +128,7 @@ mod tests {
use {SeedableRng, Rng};
struct Counter {
i: u32
i: u32,
}
impl Rng for Counter {
@ -153,7 +155,7 @@ mod tests {
#[test]
fn test_reseeding() {
let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
let mut rs = ReseedingRng::new(Counter { i: 0 }, 400, ReseedWithDefault);
let mut i = 0;
for _ in 0..1000 {