View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.core.source32;
18  
19  import org.apache.commons.rng.core.RandomAssert;
20  import org.junit.jupiter.api.Test;
21  
22  class XoShiRo128PlusTest {
23      /** The size of the array seed. */
24      private static final int SEED_SIZE = 4;
25  
26      /*
27       * Data from running the executable compiled from the author's C code:
28       *   http://xoshiro.di.unimi.it/xoshiro128plus.c
29       */
30  
31      private static final int[] SEED = {
32          0x012de1ba, 0xa5a818b8, 0xb124ea2b, 0x18e03749,
33      };
34  
35      private static final int[] EXPECTED_SEQUENCE = {
36          0x1a0e1903, 0xfde55c35, 0xddb16b2e, 0xab949ac5,
37          0xb5519fea, 0xc6a97473, 0x1f0403d9, 0x1bb46995,
38          0x79c99a12, 0xe447ebce, 0xa8c31d78, 0x54d8bbe3,
39          0x4984a039, 0xb411e932, 0x9c1f2c5e, 0x5f53c469,
40          0x7f333552, 0xb368c7a1, 0xa57b8e66, 0xb29a9444,
41          0x5c389bfa, 0x8e7d3758, 0xfe17a1bb, 0xcd0aad57,
42          0xde83c4bb, 0x1402339d, 0xb557a080, 0x4f828bc9,
43          0xde14892d, 0xbba8eaed, 0xab62ebbb, 0x4ad959a4,
44          0x3c6ee9c7, 0x4f6a6fd3, 0xd5785eed, 0x1a0227d1,
45          0x81314acb, 0xfabdfb97, 0x7e1b7e90, 0x57544e23,
46      };
47  
48      private static final int[] EXPECTED_SEQUENCE_AFTER_JUMP = {
49          0x65ddc942, 0x7e7c4d6b, 0x6745a785, 0x40897788,
50          0xfb60ce92, 0x121f2ee0, 0xd000bae8, 0x52b3ebfc,
51          0x62fc3720, 0xf880f092, 0x7753c1ab, 0x1e76a627,
52          0xe5de31e8, 0xc7b1503f, 0xa5557a66, 0x37b2b2cd,
53          0x656dde58, 0xdd5f1b93, 0xba61298b, 0xbd5d1ce2,
54          0xea4a5a73, 0x0f10981d, 0xc207a68c, 0x1897adca,
55          0x4d729b07, 0xf0115ee0, 0x953d9e4b, 0x3608e61c,
56          0x0c14c065, 0xf2ed7579, 0xcd96ef9b, 0xdb62d117,
57          0x844e4713, 0x763a8a76, 0x9ad37470, 0x211e4883,
58          0xc8682b75, 0xb1831941, 0xf0c50a84, 0x7321dc33,
59      };
60  
61      private static final int[] EXPECTED_SEQUENCE_AFTER_LONG_JUMP = {
62          0x93572bc7, 0xc46a6c83, 0x5803ee73, 0x525cc155,
63          0x45d27ce5, 0xfffbdf72, 0x764d4d47, 0xe94e5ee4,
64          0xf91b0e1f, 0x63138833, 0xb63f1a97, 0x5cf78346,
65          0xad979a8f, 0xcf4c0d3f, 0xccfb1798, 0xff978ea1,
66          0xc7744b7c, 0xfcae345e, 0x40618bc9, 0x55f2ffd7,
67          0x869ad599, 0x0101eba4, 0x5091a478, 0xc82b9461,
68          0x940e4e36, 0x49f41fbe, 0x6005f4af, 0x6cf46dab,
69          0x2de3bc75, 0x06530e45, 0x839ef4b3, 0xd2510032,
70          0x6053afee, 0xe67eb5e8, 0x2f25e700, 0x2de3212b,
71          0x41cf6954, 0xa66d8fd8, 0x6c348704, 0xb16b8da5,
72      };
73  
74      @Test
75      void testReferenceCode() {
76          RandomAssert.assertEquals(EXPECTED_SEQUENCE, new XoShiRo128Plus(SEED));
77      }
78  
79      @Test
80      void testConstructorWithZeroSeedIsNonFunctional() {
81          RandomAssert.assertNextIntZeroOutput(new XoShiRo128Plus(new int[SEED_SIZE]), 2 * SEED_SIZE);
82      }
83  
84      @Test
85      void testConstructorWithSingleBitSeedIsFunctional() {
86          RandomAssert.assertIntArrayConstructorWithSingleBitSeedIsFunctional(XoShiRo128Plus.class, SEED_SIZE);
87      }
88  
89      @Test
90      void testConstructorWithoutFullLengthSeed() {
91          // Hit the case when the input seed is self-seeded when not full length
92          RandomAssert.assertNextLongNonZeroOutput(new XoShiRo128Plus(new int[] {SEED[0]}),
93                  SEED_SIZE, SEED_SIZE);
94      }
95  
96      @Test
97      void testElementConstructor() {
98          final XoShiRo128Plus rng1 = new XoShiRo128Plus(SEED);
99          final XoShiRo128Plus rng2 = new XoShiRo128Plus(SEED[0], SEED[1], SEED[2], SEED[3]);
100         RandomAssert.assertNextIntEquals(SEED.length * 2, rng1, rng2);
101     }
102 
103     @Test
104     void testJump() {
105         RandomAssert.assertJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_JUMP, new XoShiRo128Plus(SEED));
106     }
107 
108     @Test
109     void testLongJump() {
110         RandomAssert.assertLongJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_LONG_JUMP, new XoShiRo128Plus(SEED));
111     }
112 }