1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use super::{RngState};

use rand::{Rng, SeedableRng};
use std::mem::{transmute};
use std::num::{Wrapping};

#[derive(Clone)]
pub struct Xorshiftplus128Rng {
  state: [u64; 2],
}

impl Xorshiftplus128Rng {
  pub fn new<R>(seed_rng: &mut R) -> Xorshiftplus128Rng where R: Rng {
    let seed = [seed_rng.next_u64(), seed_rng.next_u64()];
    Self::from_seed(seed)
  }

  pub fn _state(&self) -> &[u64] {
    &self.state
  }
}

impl RngState for Xorshiftplus128Rng {
  fn state_size(&self) -> usize {
    2
  }

  fn extract_state(&self, state_buf: &mut [u64]) {
    state_buf[ .. 2].copy_from_slice(&self.state);
  }

  fn set_state(&mut self, state_buf: &[u64]) {
    self.state.copy_from_slice(&state_buf[ .. 2]);
  }
}

impl Rng for Xorshiftplus128Rng {
  fn next_u64(&mut self) -> u64 {
    let mut s1 = unsafe { *self.state.get_unchecked(0) };
    let s0 = unsafe { *self.state.get_unchecked(1) };
    s1 ^= s1 << 23;
    s1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26);
    unsafe { *self.state.get_unchecked_mut(0) = s0 };
    unsafe { *self.state.get_unchecked_mut(1) = s1 };
    (Wrapping(s1) + Wrapping(s0)).0
  }

  fn next_u32(&mut self) -> u32 {
    (self.next_u64() >> 32) as u32
  }
}

impl<'a> SeedableRng<&'a [u64]> for Xorshiftplus128Rng {
  fn reseed(&mut self, seed: &'a [u64]) {
    assert!(seed.len() >= 2);
    self.state[0] = seed[0];
    self.state[1] = seed[1];
    /*// XXX: This increases the initial state entropy (many zeros to half zeros).
    // See Figure 4 in <http://arxiv.org/abs/1404.0390> for details.
    for _ in 0 .. 20 {
      let _ = self.next_u64();
    }*/
  }

  fn from_seed(seed: &'a [u64]) -> Xorshiftplus128Rng {
    let mut rng = Xorshiftplus128Rng{
      state: [0; 2],
    };
    rng.reseed(seed);
    rng
  }
}

impl SeedableRng<[u64; 2]> for Xorshiftplus128Rng {
  fn reseed(&mut self, seed: [u64; 2]) {
    self.reseed(&seed as &[u64]);
  }

  fn from_seed(seed: [u64; 2]) -> Xorshiftplus128Rng {
    Self::from_seed(&seed as &[u64])
  }
}

pub struct Xorshiftstar1024Rng {
  state: [u64; 16],
  p: usize,
}

impl Rng for Xorshiftstar1024Rng {
  fn next_u64(&mut self) -> u64 {
    // See: <http://xorshift.di.unimi.it/xorshift1024star.c>
    // and <http://arxiv.org/abs/1402.6246>.
    let mut s0 = unsafe { *self.state.get_unchecked(self.p) };
    let p = (self.p + 1) & 0x0f;
    let mut s1 = unsafe { *self.state.get_unchecked(p) };
    s1 ^= s1 << 31;
    s1 ^= s1 >> 11;
    s0 ^= s0 >> 30;
    let s = s0 ^ s1;
    unsafe { *self.state.get_unchecked_mut(p) = s; }
    self.p = p;
    let r = s * 1181783497276652981_u64;
    r
  }

  fn next_u32(&mut self) -> u32 {
    self.next_u64() as u32
  }
}

impl<'a> SeedableRng<&'a [u64]> for Xorshiftstar1024Rng {
  fn reseed(&mut self, seed: &'a [u64]) {
    assert!(seed.len() >= 16);
    for p in 0 .. 16 {
      self.state[p] = seed[p];
    }
  }

  fn from_seed(seed: &'a [u64]) -> Xorshiftstar1024Rng {
    let mut rng = Xorshiftstar1024Rng{
      state: [0; 16],
      p: 0,
    };
    rng.reseed(seed);
    rng
  }
}