1use crate::error::Result;
7use crate::fast::splitmix64::SplitMix64;
8use crate::seed::Seed;
9use crate::traits::{DeterministicRng, Rng, SeedableRng};
10
11#[derive(Debug, Clone)]
17pub struct Pcg64 {
18 state: u64,
19 inc: u64,
20}
21
22impl Pcg64 {
23 pub fn new(seed: u64) -> Self {
25 let mut splitmix = SplitMix64::new(seed);
27 let state = splitmix.next_u64();
28 let inc = (splitmix.next_u64() << 1) | 1; Self { state, inc }
30 }
31
32 pub fn from_seed_obj(seed: &Seed) -> Result<Self> {
34 let seed_bytes = seed.as_ref();
35 if seed_bytes.len() < 8 {
36 let mut expanded = seed_bytes.to_vec();
38 while expanded.len() < 8 {
39 expanded.extend_from_slice(seed_bytes);
40 }
41 let seed_value = u64::from_le_bytes([
42 expanded[0],
43 expanded[1],
44 expanded[2],
45 expanded[3],
46 expanded[4],
47 expanded[5],
48 expanded[6],
49 expanded[7],
50 ]);
51 Ok(Self::new(seed_value))
52 } else {
53 let seed_value = u64::from_le_bytes([
54 seed_bytes[0],
55 seed_bytes[1],
56 seed_bytes[2],
57 seed_bytes[3],
58 seed_bytes[4],
59 seed_bytes[5],
60 seed_bytes[6],
61 seed_bytes[7],
62 ]);
63 Ok(Self::new(seed_value))
64 }
65 }
66
67 pub fn from_state(state: u64, inc: u64) -> Self {
69 let inc = inc | 1;
71 Self { state, inc }
72 }
73
74 #[inline(always)]
76 pub fn next_u32(&mut self) -> u32 {
77 (self.next_u64() >> 32) as u32
78 }
79
80 #[inline(always)]
82 pub fn next_u64(&mut self) -> u64 {
83 let oldstate = self.state;
84
85 self.state = oldstate
87 .wrapping_mul(6364136223846793005u64)
88 .wrapping_add(self.inc);
89
90 let xorshifted = ((oldstate >> 18) ^ oldstate) >> 27;
92 let rot = (oldstate >> 59) as u32;
93 xorshifted.rotate_right(rot)
94 }
95
96 #[inline]
98 pub fn fill_bytes(&mut self, dest: &mut [u8]) {
99 let mut chunks = dest.chunks_exact_mut(8);
100 for chunk in chunks.by_ref() {
101 let value = self.next_u64();
102 chunk.copy_from_slice(&value.to_le_bytes());
103 }
104 let remainder = chunks.into_remainder();
105 if !remainder.is_empty() {
106 let value = self.next_u64();
107 let bytes = value.to_le_bytes();
108 remainder.copy_from_slice(&bytes[..remainder.len()]);
109 }
110 }
111
112 pub fn save_state(&self) -> [u64; 2] {
114 [self.state, self.inc]
115 }
116
117 pub fn restore_state(&mut self, state: [u64; 2]) {
119 self.state = state[0];
120 self.inc = state[1] | 1; }
122}
123
124impl Rng for Pcg64 {
125 #[inline]
126 fn next_u32(&mut self) -> u32 {
127 self.next_u32()
128 }
129
130 #[inline]
131 fn next_u64(&mut self) -> u64 {
132 self.next_u64()
133 }
134
135 #[inline]
136 fn fill_bytes(&mut self, dest: &mut [u8]) {
137 self.fill_bytes(dest)
138 }
139}
140
141impl DeterministicRng for Pcg64 {
142 #[inline]
143 fn is_deterministic(&self) -> bool {
144 true
145 }
146}
147
148impl SeedableRng for Pcg64 {
149 type Seed = Seed;
150
151 fn from_seed(seed: Self::Seed) -> Self {
152 Self::from_seed_obj(&seed).expect("Seed should be valid")
153 }
154
155 fn reseed(&mut self, seed: Self::Seed) -> Result<()> {
156 *self = Self::from_seed_obj(&seed)?;
157 Ok(())
158 }
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164
165 #[test]
166 fn test_pcg64_deterministic() {
167 let mut rng1 = Pcg64::new(12345);
168 let mut rng2 = Pcg64::new(12345);
169
170 for _ in 0..100 {
171 assert_eq!(rng1.next_u64(), rng2.next_u64());
172 }
173 }
174
175 #[test]
176 fn test_pcg64_save_restore() {
177 let mut rng = Pcg64::new(42);
178 let _ = rng.next_u64();
179 let state = rng.save_state();
180
181 let mut rng2 = Pcg64::new(0);
182 rng2.restore_state(state);
183
184 assert_eq!(rng.next_u64(), rng2.next_u64());
185 }
186
187 #[test]
188 fn test_pcg64_increment_odd() {
189 let rng = Pcg64::from_state(123, 456);
190 assert_eq!(rng.inc & 1, 1);
192 }
193}