blob: 21d5987af3b9183bb4d222cddad7f46a49d0c47c [file] [log] [blame]
// Copyright ©2019 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package prng
import (
"testing"
"time"
"golang.org/x/exp/rand"
)
// Random values in tests are produced by 40 iterations of the C code.
var _ rand.Source = (*SplitMix64)(nil)
func TestSplitMix64(t *testing.T) {
t.Parallel()
want := []uint64{
10451216379200822465, 13757245211066428519, 17911839290282890590, 8196980753821780235, 8195237237126968761,
14072917602864530048, 16184226688143867045, 9648886400068060533, 5266705631892356520, 14646652180046636950,
7455107161863376737, 11168034603498703870, 8392123148533390784, 9778231605760336522, 8042142155559163816,
3081251696030599739, 11904322950028659555, 15040563541741120241, 12575237177726700014, 16312908901713405192,
1216750802008901446, 1501835286251455644, 9147370558249537485, 2270958130545493676, 5292580334274787743,
883620860755687159, 9509663594007654709, 13166747327335888811, 807013244984872231, 18405200023706498954,
11028426030083068036, 10820770463232788922, 7326479631639850093, 8097875853865443356, 4672064935750269975,
9772298966463872780, 10028955912863736053, 13802505617680978881, 15090054588401425688, 12333003614474408764,
}
sm := NewSplitMix64(1)
for i := range want {
got := sm.Uint64()
if got != want[i] {
t.Errorf("unexpected random value at iteration %d: got:%d want:%d", i, got, want[i])
}
}
}
func TestSplitMix64RoundTrip(t *testing.T) {
t.Parallel()
var src SplitMix64
src.Seed(uint64(time.Now().Unix()))
buf, err := src.MarshalBinary()
if err != nil {
t.Errorf("unexpected error marshaling state: %v", err)
}
var dst SplitMix64
// Get dst into a non-zero state.
dst.Seed(1)
for i := 0; i < 10; i++ {
dst.Uint64()
}
err = dst.UnmarshalBinary(buf)
if err != nil {
t.Errorf("unexpected error unmarshaling state: %v", err)
}
if dst != src {
t.Errorf("mismatch between generator states: got:%+v want:%+v", dst, src)
}
}
var _ rand.Source = (*Xoshiro256plus)(nil)
func TestXoshiro256plus(t *testing.T) {
t.Parallel()
want := []uint64{
201453059313051084, 16342930563397888806, 2922809869868169223, 13315230553875954649, 6410977891529050008,
2721661332018190285, 3769995280709464022, 17208995829377771030, 16938999919058283733, 8307416726322109393,
13997290115667311691, 5498422487743993519, 13193129985428835789, 17178224140053183722, 3371202013665523682,
6673444001875245482, 11649545741795472859, 4657392542380076879, 8631341306563158492, 16151880809814987639,
15271080878658922261, 6998002807989632655, 11431762507643441726, 136605885039865329, 16072241235209520170,
17064623797431990278, 6319393334343723778, 3599071131527455911, 14678971584471326753, 11566847267978507055,
37242444495476935, 9767625399998905638, 14799351402198708144, 15147234459691564338, 10081976988475685812,
12402022881820243150, 17939631254687971868, 15680836376982110901, 179319489669050051, 16194215847106809765,
}
xsr := NewXoshiro256plus(1)
for i := range want {
got := xsr.Uint64()
if got != want[i] {
t.Errorf("unexpected random value at iteration %d: got:%d want:%d", i, got, want[i])
}
}
}
func TestXoshiro256plusRoundTrip(t *testing.T) {
t.Parallel()
var src Xoshiro256plus
src.Seed(uint64(time.Now().Unix()))
src.Uint64() // Step PRNG once to makes sure states are mixed.
buf, err := src.MarshalBinary()
if err != nil {
t.Errorf("unexpected error marshaling state: %v", err)
}
var dst Xoshiro256plus
// Get dst into a non-zero state.
dst.Seed(1)
for i := 0; i < 10; i++ {
dst.Uint64()
}
err = dst.UnmarshalBinary(buf)
if err != nil {
t.Errorf("unexpected error unmarshaling state: %v", err)
}
if dst != src {
t.Errorf("mismatch between generator states: got:%+v want:%+v", dst, src)
}
}
var _ rand.Source = (*Xoshiro256plusplus)(nil)
func TestXoshiro256plusplus(t *testing.T) {
t.Parallel()
want := []uint64{
14971601782005023387, 13781649495232077965, 1847458086238483744, 13765271635752736470, 3406718355780431780,
10892412867582108485, 18204613561675945223, 9655336933892813345, 1781989159761824720, 2477283028068920342,
16978024111547606601, 6336475467619303347, 1336129645694042326, 7278725533440954441, 1650926874576718010,
2884092293074692283, 10277292511068429730, 8723528388573605619, 17670016435951889822, 11847526622624223050,
4869519043768407819, 14645621260580619786, 2927941368235978475, 7627105703721172900, 4384663367605854827,
11119034730948704880, 3397900810577180010, 18115970067406137490, 11274606161466886392, 13467911786374401590,
10949103424463861935, 11981483663808188895, 9358210361682609782, 11442939244776437245, 17602980262171424054,
5959474180322755185, 1996769245947054333, 13544632058761996522, 16649296193330087156, 12760326241867116135,
}
xsr := NewXoshiro256plusplus(1)
for i := range want {
got := xsr.Uint64()
if got != want[i] {
t.Errorf("unexpected random value at iteration %d: got:%d want:%d", i, got, want[i])
}
}
}
func TestXoshiro256plusplusRoundTrip(t *testing.T) {
t.Parallel()
var src Xoshiro256plusplus
src.Seed(uint64(time.Now().Unix()))
src.Uint64() // Step PRNG once to makes sure states are mixed.
buf, err := src.MarshalBinary()
if err != nil {
t.Errorf("unexpected error marshaling state: %v", err)
}
var dst Xoshiro256plusplus
// Get dst into a non-zero state.
dst.Seed(1)
for i := 0; i < 10; i++ {
dst.Uint64()
}
err = dst.UnmarshalBinary(buf)
if err != nil {
t.Errorf("unexpected error unmarshaling state: %v", err)
}
if dst != src {
t.Errorf("mismatch between generator states: got:%+v want:%+v", dst, src)
}
}
var _ rand.Source = (*Xoshiro256starstar)(nil)
func TestXoshiro256starstar(t *testing.T) {
t.Parallel()
want := []uint64{
12966619160104079557, 9600361134598540522, 10590380919521690900, 7218738570589545383, 12860671823995680371,
2648436617965840162, 1310552918490157286, 7031611932980406429, 15996139959407692321, 10177250653276320208,
17202925169076741841, 17657558547222227110, 17206619296382044401, 12342657103067243573, 11066818095355039191,
16427605434558419749, 1484150211974036615, 9063990983673329711, 845232928428614080, 1176429380546917807,
8545088851120551825, 9158324580728115577, 11267126437916202177, 6452051665337041730, 7460617819096774474,
3909615622106851260, 7148019177890935463, 15761474764570999248, 13856144421012645925, 18119237044791779759,
202581184499657049, 16256128138147959276, 7894450248801719761, 7285265299121834259, 11974578372788407364,
4350246478179107086, 4560570958642824732, 15448532239578831742, 7084622563335324071, 8654072644765974953,
}
xsr := NewXoshiro256starstar(1)
for i := range want {
got := xsr.Uint64()
if got != want[i] {
t.Errorf("unexpected random value at iteration %d: got:%d want:%d", i, got, want[i])
}
}
}
func TestXoshiro256starstarRoundTrip(t *testing.T) {
t.Parallel()
var src Xoshiro256starstar
src.Seed(uint64(time.Now().Unix()))
src.Uint64() // Step PRNG once to makes sure states are mixed.
buf, err := src.MarshalBinary()
if err != nil {
t.Errorf("unexpected error marshaling state: %v", err)
}
var dst Xoshiro256starstar
// Get dst into a non-zero state.
dst.Seed(1)
for i := 0; i < 10; i++ {
dst.Uint64()
}
err = dst.UnmarshalBinary(buf)
if err != nil {
t.Errorf("unexpected error unmarshaling state: %v", err)
}
if dst != src {
t.Errorf("mismatch between generator states: got:%+v want:%+v", dst, src)
}
}