Skip to content

Commit 36734f9

Browse files
committed
#249-test class Xoroshiro512
Fully validated.
1 parent a476b7d commit 36734f9

File tree

12 files changed

+2039
-66
lines changed

12 files changed

+2039
-66
lines changed

Python3.10/PyRandLib/xoroshiro512.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class Xoroshiro512( BaseXoroshiro ):
7777
"""
7878

7979
#-------------------------------------------------------------------------
80-
def __init__(self, _seedState: Numerical | StatesList = None, /) -> None:
80+
def __init__(self, _seedState: Numerical | StatesList = None, /) -> None: # type: ignore
8181
"""Constructor.
8282
8383
_seedState is either a valid state, an integer, a float or None.
@@ -103,18 +103,18 @@ def next(self) -> int:
103103
"""
104104
currentS1 = self._state[1]
105105
# advances the internal state of the PRNG
106-
self._state[2] ^= self._state[0]
107-
self._state[5] ^= self._state[1]
108-
self._state[1] ^= self._state[2]
109-
self._state[7] ^= self._state[3]
110-
self._state[3] ^= self._state[4]
111-
self._state[4] ^= self._state[5]
112-
self._state[0] ^= self._state[6]
113-
self._state[6] ^= self._state[7]
114-
self._state[6] ^= (currentS1 << 11) & BaseXoroshiro._MODULO
106+
self._state[2] ^= self._state[0] # type: ignore
107+
self._state[5] ^= self._state[1] # type: ignore
108+
self._state[1] ^= self._state[2] # type: ignore
109+
self._state[7] ^= self._state[3] # type: ignore
110+
self._state[3] ^= self._state[4] # type: ignore
111+
self._state[4] ^= self._state[5] # type: ignore
112+
self._state[0] ^= self._state[6] # type: ignore
113+
self._state[6] ^= self._state[7] # type: ignore
114+
self._state[6] ^= (currentS1 << 11) & BaseXoroshiro._MODULO # type: ignore
115115
self._state[7] = BaseRandom._rotleft( self._state[7], 21 )
116116
# returns the output value
117-
return (BaseRandom._rotleft( currentS1 * 5, 7) * 9) & BaseXoroshiro._MODULO
117+
return (BaseRandom._rotleft( currentS1 * 5, 7) * 9) & BaseXoroshiro._MODULO # type: ignore
118118

119119

120120
#===== end of module xoroshiro512.py ===================================
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
"""
2+
Copyright (c) 2025 Philippe Schmouker, ph (dot) schmouker (at) gmail.com
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
"""
22+
23+
#=============================================================================
24+
from typing import Any
25+
import pytest
26+
27+
from PyRandLib.xoroshiro512 import Xoroshiro512
28+
29+
30+
#=============================================================================
31+
class TestXoroshiro512:
32+
"""Tests class Xoroshiro512.
33+
"""
34+
35+
Xoroshiro512_STATE_SIZE = 8
36+
37+
#-------------------------------------------------------------------------
38+
def test_class(self):
39+
assert Xoroshiro512._NORMALIZE == 1.0 / (1 << 64)
40+
assert Xoroshiro512._OUT_BITS == 64
41+
42+
#-------------------------------------------------------------------------
43+
def test_init_empty(self):
44+
xrsr = Xoroshiro512()
45+
assert xrsr._STATE_SIZE == TestXoroshiro512.Xoroshiro512_STATE_SIZE
46+
assert xrsr._index == 0
47+
assert xrsr.gauss_next is None # type: ignore
48+
assert all(isinstance(s, int) for s in xrsr._state)
49+
assert all(0 <= s < (1 << 64) for s in xrsr._state) # type: ignore
50+
51+
#-------------------------------------------------------------------------
52+
def test_init_int(self):
53+
xrsr = Xoroshiro512(1)
54+
assert xrsr._index == 0
55+
assert xrsr.gauss_next is None # type: ignore
56+
assert xrsr._state[0] == 0x910a2dec89025cc1
57+
assert xrsr._state[1] == 0xbeeb8da1658eec67
58+
assert xrsr._state[2] == 0xf893a2eefb32555e
59+
assert xrsr._state[3] == 0x71c18690ee42c90b
60+
assert xrsr._state[4] == 0x71bb54d8d101b5b9
61+
assert xrsr._state[5] == 0xc34d0bff90150280
62+
assert xrsr._state[6] == 0xe099ec6cd7363ca5
63+
assert xrsr._state[7] == 0x85e7bb0f12278575
64+
65+
xrsr = Xoroshiro512(-2)
66+
assert xrsr._index == 0
67+
assert xrsr.gauss_next is None # type: ignore
68+
assert xrsr._state[0] == 0xf3203e9039f4a821
69+
assert xrsr._state[1] == 0xba56949915dcf9e9
70+
assert xrsr._state[2] == 0xd0d5127a96e8d90d
71+
assert xrsr._state[3] == 0x1ef156bb76650c37
72+
assert xrsr._state[4] == 0x7842841591543f1d
73+
assert xrsr._state[5] == 0xd85ab7a2b154095a
74+
assert xrsr._state[6] == 0xea909a92e113bf3c
75+
assert xrsr._state[7] == 0x1e2b53fb7bd63f05
76+
77+
xrsr = Xoroshiro512(0x0123_4567_89ab_cdef)
78+
assert xrsr._index == 0
79+
assert xrsr.gauss_next is None # type: ignore
80+
assert xrsr._state[0] == 0x157a3807a48faa9d
81+
assert xrsr._state[1] == 0xd573529b34a1d093
82+
assert xrsr._state[2] == 0x2f90b72e996dccbe
83+
assert xrsr._state[3] == 0xa2d419334c4667ec
84+
assert xrsr._state[4] == 0x01404ce914938008
85+
assert xrsr._state[5] == 0x14bc574c2a2b4c72
86+
assert xrsr._state[6] == 0xb8fc5b1060708c05
87+
assert xrsr._state[7] == 0x8931545f4f9ea651
88+
89+
xrsr = Xoroshiro512(-8_870_000_000_000_000_000)
90+
assert xrsr._index == 0
91+
assert xrsr.gauss_next is None # type: ignore
92+
assert xrsr._state[0] == 0x48bbc5b84275f3ca
93+
assert xrsr._state[1] == 0xe2fbc345a799b5aa
94+
assert xrsr._state[2] == 0x86ce19a135fba0de
95+
assert xrsr._state[3] == 0x637c87187035ea06
96+
assert xrsr._state[4] == 0x2a03b9aff2bfd421
97+
assert xrsr._state[5] == 0x534fe17cac5d7a22
98+
assert xrsr._state[6] == 0x95d0c8e531644d42
99+
assert xrsr._state[7] == 0xe6d2502493ff622e
100+
101+
xrsr = Xoroshiro512(8_870_000_000_000_000_000)
102+
assert xrsr._index == 0
103+
assert xrsr.gauss_next is None # type: ignore
104+
assert xrsr._state[0] == 0xeede014d9a5a6108
105+
assert xrsr._state[1] == 0xa6eb6466bac9f251
106+
assert xrsr._state[2] == 0x4246cbb1a64bf70c
107+
assert xrsr._state[3] == 0xaf6aa8f43ebb8659
108+
assert xrsr._state[4] == 0xe1b0fb2c7e764cdb
109+
assert xrsr._state[5] == 0x56d25f68391b2f83
110+
assert xrsr._state[6] == 0x1408795faf81b73d
111+
assert xrsr._state[7] == 0xe0c07d9420f2f41e
112+
113+
xrsr = Xoroshiro512(0xffff_ffff_ffff_fffe_ffff_ffff_ffff_fffd)
114+
assert xrsr._index == 0
115+
assert xrsr.gauss_next is None # type: ignore
116+
assert xrsr._state[0] == 0xf75f04cbb5a1a1dd
117+
assert xrsr._state[1] == 0xec779c3693f88501
118+
assert xrsr._state[2] == 0xfed9eeb4936de39d
119+
assert xrsr._state[3] == 0x6f9fb04b092bd30a
120+
assert xrsr._state[4] == 0x260ffb0260bbbe5f
121+
assert xrsr._state[5] == 0x082cfe8866fac366
122+
assert xrsr._state[6] == 0x7a5f67e38e997e3f
123+
assert xrsr._state[7] == 0xd7c07017388fa2af
124+
125+
#-------------------------------------------------------------------------
126+
def test_init_float(self):
127+
xrsr = Xoroshiro512(0.357)
128+
assert xrsr._index == 0
129+
assert xrsr.gauss_next is None # type: ignore
130+
assert xrsr._state[0] == 0x5fee464f36fc42c3
131+
assert xrsr._state[1] == 0x954faf5a9ad49cf8
132+
assert xrsr._state[2] == 0xa985465a4a5fc644
133+
assert xrsr._state[3] == 0x77714db9e870d702
134+
assert xrsr._state[4] == 0xa3aac457d81d552c
135+
assert xrsr._state[5] == 0xbcf1fb888caf4f02
136+
assert xrsr._state[6] == 0x1c4d126a40f3f8a9
137+
assert xrsr._state[7] == 0xe6b536617ee8b60c
138+
139+
xrsr = Xoroshiro512(1.0)
140+
assert xrsr._index == 0
141+
assert xrsr.gauss_next is None # type: ignore
142+
assert all(isinstance(s, int) for s in xrsr._state)
143+
assert all(0 <= s < (1 << 64) for s in xrsr._state) # type: ignore
144+
145+
with pytest.raises(ValueError):
146+
xrsr = Xoroshiro512(-0.0001)
147+
with pytest.raises(ValueError):
148+
xrsr = Xoroshiro512(1.001)
149+
150+
#-------------------------------------------------------------------------
151+
def test_init_state(self):
152+
xrsr = Xoroshiro512(tuple(i for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE))) # type: ignore
153+
assert xrsr._index == 0
154+
assert xrsr.gauss_next is None # type: ignore
155+
assert xrsr._state == [i for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
156+
157+
with pytest.raises(TypeError):
158+
# due to unhashable lists bug in Python 3.10
159+
xrsr = Xoroshiro512(list(i+10 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE))) # type: ignore
160+
assert xrsr._index == 0
161+
assert xrsr.gauss_next is None # type: ignore
162+
assert xrsr._state == list(i+10 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)) # type: ignore
163+
164+
with pytest.raises(TypeError):
165+
xrsr = Xoroshiro512((1, 2, 3)) # type: ignore
166+
with pytest.raises(TypeError):
167+
xrsr = Xoroshiro512((i for i in range(18))) # type: ignore
168+
with pytest.raises(TypeError):
169+
xrsr = Xoroshiro512([1, 2, 3]) # type: ignore
170+
with pytest.raises(TypeError):
171+
xrsr = Xoroshiro512([i for i in range(18)]) # type: ignore
172+
with pytest.raises(TypeError):
173+
xrsr = Xoroshiro512(set()) # type: ignore
174+
175+
#-------------------------------------------------------------------------
176+
def test_next(self):
177+
xrsr = Xoroshiro512(0x0123_4567_89ab_cdef)
178+
assert xrsr.gauss_next is None # type: ignore
179+
assert xrsr._index == 0
180+
assert xrsr._state[0] == 0x157a3807a48faa9d
181+
assert xrsr._state[1] == 0xd573529b34a1d093
182+
assert xrsr._state[2] == 0x2f90b72e996dccbe
183+
assert xrsr._state[3] == 0xa2d419334c4667ec
184+
assert xrsr._state[4] == 0x01404ce914938008
185+
assert xrsr._state[5] == 0x14bc574c2a2b4c72
186+
assert xrsr._state[6] == 0xb8fc5b1060708c05
187+
assert xrsr._state[7] == 0x8931545f4f9ea651
188+
189+
for v in [0xa2c2a42038d4ec3d, 0x5fc25d0738e7b0f, 0x8cdae320589ff91e, 0x5ef9741cae1d2a1c, 0xb5bfb1afdbeb04dd]:
190+
assert xrsr.next() == v
191+
192+
assert xrsr.gauss_next is None # type: ignore
193+
assert xrsr._index == 0
194+
assert xrsr.gauss_next is None # type: ignore
195+
assert xrsr._state[0] == 0x2dd1d8834a1d1abe
196+
assert xrsr._state[1] == 0xfd4348c7c59ed738
197+
assert xrsr._state[2] == 0xe8c9a4d483fa1ce6
198+
assert xrsr._state[3] == 0x90f3152a081b547f
199+
assert xrsr._state[4] == 0xadf094a1bc23213c
200+
assert xrsr._state[5] == 0x08bb748601635214
201+
assert xrsr._state[6] == 0xfad74f72516c3bfd
202+
assert xrsr._state[7] == 0x8f2b04287d66d6e6
203+
204+
#-------------------------------------------------------------------------
205+
def test_seed(self):
206+
xrsr = Xoroshiro512()
207+
208+
xrsr.seed(0xffff_ffff_ffff_fffe_ffff_ffff_ffff_fffd)
209+
assert xrsr._index == 0
210+
assert xrsr.gauss_next is None # type: ignore
211+
assert xrsr._state[0] == 0xf75f04cbb5a1a1dd
212+
assert xrsr._state[1] == 0xec779c3693f88501
213+
assert xrsr._state[2] == 0xfed9eeb4936de39d
214+
assert xrsr._state[3] == 0x6f9fb04b092bd30a
215+
assert xrsr._state[4] == 0x260ffb0260bbbe5f
216+
assert xrsr._state[5] == 0x082cfe8866fac366
217+
assert xrsr._state[6] == 0x7a5f67e38e997e3f
218+
assert xrsr._state[7] == 0xd7c07017388fa2af
219+
220+
xrsr.seed(0.357)
221+
assert xrsr._index == 0
222+
assert xrsr.gauss_next is None # type: ignore
223+
assert xrsr._state[0] == 0x5fee464f36fc42c3
224+
assert xrsr._state[1] == 0x954faf5a9ad49cf8
225+
assert xrsr._state[2] == 0xa985465a4a5fc644
226+
assert xrsr._state[3] == 0x77714db9e870d702
227+
assert xrsr._state[4] == 0xa3aac457d81d552c
228+
assert xrsr._state[5] == 0xbcf1fb888caf4f02
229+
assert xrsr._state[6] == 0x1c4d126a40f3f8a9
230+
assert xrsr._state[7] == 0xe6b536617ee8b60c
231+
232+
with pytest.raises(ValueError):
233+
xrsr.seed(-0.0001)
234+
with pytest.raises(ValueError):
235+
xrsr.seed(1.001)
236+
237+
xrsr.seed()
238+
assert xrsr._index == 0
239+
assert xrsr.gauss_next is None # type: ignore
240+
assert all(isinstance(s, int) for s in xrsr._state)
241+
assert all(0 < s < (1 << 64) for s in xrsr._state) # type: ignore
242+
243+
with pytest.raises(TypeError):
244+
xrsr.seed((1, 2, 3)) # type: ignore
245+
with pytest.raises(TypeError):
246+
xrsr.seed((1, 2, 3, 4, 5)) # type: ignore
247+
with pytest.raises(TypeError):
248+
xrsr.seed([1, 2, 3]) # type: ignore
249+
with pytest.raises(TypeError):
250+
xrsr.seed([1, 2, 3, 4, 5]) # type: ignore
251+
with pytest.raises(TypeError):
252+
xrsr.seed(set()) # type: ignore
253+
254+
#-------------------------------------------------------------------------
255+
def test_setstate(self):
256+
xrsr = Xoroshiro512()
257+
258+
xrsr.setstate()
259+
assert xrsr._index == 0
260+
assert xrsr.gauss_next is None # type: ignore
261+
assert all(isinstance(s, int) for s in xrsr._state)
262+
assert all(0 < s < (1 << 64) for s in xrsr._state) # type: ignore
263+
264+
with pytest.raises(TypeError):
265+
xrsr.setstate(1) # type: ignore
266+
267+
with pytest.raises(TypeError):
268+
xrsr.setstate(0.1) # type: ignore
269+
270+
with pytest.raises(TypeError):
271+
xrsr.setstate("123") # type: ignore
272+
273+
xrsr.setstate((tuple(i+31 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)), 3)) # type: ignore
274+
assert xrsr.gauss_next is None # type: ignore
275+
assert xrsr._index == 3
276+
assert xrsr.gauss_next is None # type: ignore
277+
assert xrsr._state == [i+31 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
278+
279+
xrsr.setstate([[i+41 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)], TestXoroshiro512.Xoroshiro512_STATE_SIZE + 8]) # type: ignore
280+
assert xrsr.gauss_next is None # type: ignore
281+
assert xrsr._index == 0
282+
assert xrsr.gauss_next is None # type: ignore
283+
assert xrsr._state == [i+41 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
284+
285+
xrsr.setstate([tuple(i+51 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)), 3]) # type: ignore
286+
assert xrsr.gauss_next is None # type: ignore
287+
assert xrsr._index == 3 % TestXoroshiro512.Xoroshiro512_STATE_SIZE
288+
assert xrsr.gauss_next is None # type: ignore
289+
assert xrsr._state == [i+51 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
290+
291+
xrsr.setstate(([i+61 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)], TestXoroshiro512.Xoroshiro512_STATE_SIZE + 8)) # type: ignore
292+
assert xrsr.gauss_next is None # type: ignore
293+
assert xrsr._index == 8 % TestXoroshiro512.Xoroshiro512_STATE_SIZE
294+
assert xrsr.gauss_next is None # type: ignore
295+
assert xrsr._state == [i+61 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
296+
297+
xrsr.setstate(tuple(i+11 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE))) # type: ignore
298+
assert xrsr.gauss_next is None # type: ignore
299+
assert xrsr._index == 0
300+
assert xrsr.gauss_next is None # type: ignore
301+
assert xrsr._state == [i+11 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
302+
303+
xrsr.setstate([i+21 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)]) # type: ignore
304+
assert xrsr.gauss_next is None # type: ignore
305+
assert xrsr._index == 0
306+
assert xrsr.gauss_next is None # type: ignore
307+
assert xrsr._state == [i+21 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
308+
309+
with pytest.raises(TypeError):
310+
xrsr.setstate([1, 2])
311+
with pytest.raises(TypeError):
312+
xrsr.setstate((1, 2, 3, 4, 5)) # type: ignore
313+
with pytest.raises(TypeError):
314+
xrsr.setstate([1, 2, '3', 4]) # type: ignore
315+
with pytest.raises(TypeError):
316+
xrsr.setstate([11, 12, 13.1, 14]) # type: ignore
317+
_state: list[Any]
318+
with pytest.raises(ValueError):
319+
_state = [i+1 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
320+
_state[TestXoroshiro512.Xoroshiro512_STATE_SIZE - 2] = -1
321+
xrsr.setstate(_state) # type: ignore
322+
with pytest.raises(ValueError):
323+
_state = [i+1 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
324+
_state[TestXoroshiro512.Xoroshiro512_STATE_SIZE - 3] = 0.321
325+
xrsr.setstate(_state) # type: ignore
326+
with pytest.raises(ValueError):
327+
_state = [i+1 for i in range(TestXoroshiro512.Xoroshiro512_STATE_SIZE)] # type: ignore
328+
_state[TestXoroshiro512.Xoroshiro512_STATE_SIZE - 5] = {1, 2}
329+
xrsr.setstate(_state) # type: ignore

0 commit comments

Comments
 (0)