pcg_mwc/
gen32.rs

1use rand_core::{RngCore, Error, SeedableRng, le};
2
3#[cfg(feature = "serde1")]
4use serde::{Deserialize, Serialize};
5
6// Deliberately poor constants for testing:
7// 2562598503 - Lag-2 or 3 Truly awful spectra
8// 2487410280 - Lag-2 or 3 Very bad spectra
9
10const MULTIPLIER: u32 = 3487286589; //Suitable for lag-2,3,4 acceptably good spectra
11
12/// A PCG random number generator (MWC X A 128/32 variant).
13///
14/// Permuted Congruential Generator with 128-bit state, internal multiply
15/// with carry Generator, and 32-bit output via a xor and an add.
16#[derive(Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
18pub struct Mwc128XXA32 {
19    pub(crate) x1: u32,
20    pub(crate) x2: u32,
21    pub(crate) x3: u32,
22    pub(crate) c: u32,
23}
24
25impl Mwc128XXA32 {
26    /// Construct an instance given two keys.
27    pub fn new(k1: u32, k2: u32) -> Self {
28        // X3 is 0xcafef00d 0xd15ea5e5 (default state from PCG paper because it cannot be 0.
29        // C must be initialized to a value > 1 and < MULTIPLIER
30        Mwc128XXA32::from_state_incr(k1, k2, 0xcafef00d, 0xd15ea5e5)
31    }
32
33    #[inline]
34    fn from_state_incr(x1: u32, x2: u32, x3: u32, c: u32) -> Self {
35        let mut pcg = Mwc128XXA32 { x1, x2, x3, c };
36        //Advance 6 steps to fully mix the keys.
37        pcg.gen6();
38        pcg
39    }
40
41    pub fn next(&mut self) -> u32 {
42        self.step()
43    }
44
45    #[inline]
46    fn step(&mut self) -> u32 {
47        // prepare the MCG for the next round
48        let (low, hi) = multiply(self.x3);
49        let result = permute(self.x1, self.x2, self.x3, self.c, low, hi);
50        let (x1, b) = low.overflowing_add(self.c);
51        self.x3 = self.x2;
52        self.x2 = self.x1;
53        self.x1 = x1;
54        self.c = hi.wrapping_add(b as u32);
55        result
56    }
57
58    #[inline]
59    fn gen6(&mut self) -> [u32; 6] {
60        //This is faster than calling `next_u32` 6 times because it avoids the intermediate assignments to the member variables.
61        //For some reason the compiler doesn't figure this out automatically.
62        let mut result = [0; 6];
63        let (low, hi) = multiply(self.x3);
64        result[0] = permute(self.x1, self.x2, self.x3, self.c, low, hi);
65        let (r1, b) = low.overflowing_add(self.c);
66        let c = hi.wrapping_add(b as u32);
67        let (low, hi) = multiply(self.x2);
68        result[1] = permute(r1, self.x1, self.x2, c, low, hi);
69        let (r2, b) = low.overflowing_add(c);
70        let c = hi.wrapping_add(b as u32);
71        let (low, hi) = multiply(self.x1);
72        result[2] = permute(r2, r1, self.x1, c, low, hi);
73        let (r3, b) = low.overflowing_add(c);
74        let c = hi.wrapping_add(b as u32);
75
76        let (low, hi) = multiply(r1);
77        result[3] = permute(r3, r2, r1, c, low, hi);
78        let (r1, b) = low.overflowing_add(c);
79        let c = hi.wrapping_add(b as u32);
80        let (low, hi) = multiply(r2);
81        result[4] = permute(r1, r3, r2, c, low, hi);
82        let (r2, b) = low.overflowing_add(c);
83        let c = hi.wrapping_add(b as u32);
84        let (low, hi) = multiply(r3);
85        result[5] = permute(r2, r1, r3, c, low, hi);
86        let (r3, b) = low.overflowing_add(c);
87        let c = hi.wrapping_add(b as u32);
88
89        self.c = c;
90        self.x1 = r3;
91        self.x2 = r2;
92        self.x3 = r1;
93        return result;
94    }
95}
96
97
98/// We use a single 121-bit seed to initialise the state and select a stream.
99/// Of the 128 `seed` bits 7 are ignored.
100impl SeedableRng for Mwc128XXA32 {
101    type Seed = [u8; 16];
102
103    fn from_seed(seed: Self::Seed) -> Self {
104        let mut seed_u32 = [0u32; 4];
105        le::read_u32_into(&seed, &mut seed_u32);
106        // c must be < MULTIPLE and not all 1s or 0s
107        let c = (seed_u32[0] & 0x3fff_fff8) | 5;
108        // X3 must be non-zero and not all 1s, hence we discard 2 bits
109        let x3 = (seed_u32[3] << 2) | 1;
110        Mwc128XXA32::from_state_incr(seed_u32[1], seed_u32[2], x3, c)
111    }
112}
113
114impl RngCore for Mwc128XXA32 {
115    #[inline]
116    fn next_u32(&mut self) -> u32 {
117        self.step() as u32
118    }
119
120    #[inline]
121    fn next_u64(&mut self) -> u64 {
122        let result = self.step() as u64;
123        return (result << 32) | (self.step() as u64);
124    }
125
126    #[inline]
127    fn fill_bytes(&mut self, dest: &mut [u8]) {
128        let mut dest_chunks = dest.chunks_exact_mut(6 * 4);
129        for mut dest_chunk in &mut dest_chunks {
130            for &num in self.gen6().iter() {
131                let (l, r) = dest_chunk.split_at_mut(4);
132                l.copy_from_slice(&num.to_le_bytes());
133                dest_chunk = r;
134            }
135        }
136        for dest_chunk in dest_chunks.into_remainder().chunks_mut(4) {
137            dest_chunk.copy_from_slice(&self.step().to_le_bytes()[..dest_chunk.len()]);
138        }
139    }
140
141    #[inline(always)]
142    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
143        self.fill_bytes(dest);
144        Ok(())
145    }
146}
147
148#[inline(always)]
149fn multiply(val: u32) -> (u32, u32) {
150    let t = (val as u64).wrapping_mul(MULTIPLIER as u64);
151    return (t as u32, (t >> 32) as u32);
152}
153
154#[inline(always)]
155fn permute(x1: u32, x2: u32, x3: u32, _c: u32, _low: u32, hi: u32) -> u32 {
156    (x3 ^ x2).wrapping_add(x1 ^ hi)
157}