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 XoShiRo128PlusPlusTest {
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/xoshiro128plusplus.c
29       */
30  
31      private static final int[] SEED = {
32          0x012de1ba, 0xa5a818b8, 0xb124ea2b, 0x18e03749,
33      };
34  
35      private static final int[] EXPECTED_SEQUENCE = {
36          0x083a6347, 0xaf13e949, 0xc170e7f6, 0x1fff4fb2,
37          0x683f45ee, 0x0447edcf, 0x42e85ced, 0xaf636b74,
38          0xb0087a5e, 0x75bf2669, 0xd1bce8bd, 0x421fc05e,
39          0x1c6c405f, 0x14ddbffd, 0xaeacb705, 0x977ae584,
40          0x2ac01aac, 0xc474ec71, 0xe0888022, 0xf94bc227,
41          0x32775b57, 0x44142b05, 0x525f6d9b, 0xa2721e61,
42          0x1bfe5c72, 0x17be23c2, 0x3231cc54, 0x8776866e,
43          0x9ede2587, 0x0f7f144e, 0xb6f2ff9d, 0x1556365b,
44          0x9e68aef3, 0x254010c3, 0x0b885bdd, 0x7c3f26bb,
45          0xc8266de6, 0xcd2e6587, 0x0cbec249, 0xa69b37ba,
46      };
47  
48      private static final int[] EXPECTED_SEQUENCE_AFTER_JUMP  = {
49          0x4485d85f, 0x43f4d8a7, 0xe21ea064, 0x3eddd57d,
50          0x44f6149a, 0xde7e1c16, 0xa7410410, 0x6360a4a9,
51          0x34dab153, 0xfdf089b0, 0xa9b78551, 0xa2136cee,
52          0x0ad2126f, 0x67a62b78, 0xa3e8c1fa, 0x19eed39b,
53          0x83357624, 0xde015e70, 0xdc670b3b, 0x833dc245,
54          0x4d644c84, 0x30e7ea9f, 0x9dd22362, 0x70978ced,
55          0xf3d07dbb, 0xfdad08e5, 0x9118ebe0, 0x5dc55edf,
56          0xcf9abe08, 0x7a822c3b, 0xa1115ecf, 0x9f8cc327,
57          0x452c8954, 0xf920ef83, 0xcff75ece, 0x9622a70d,
58          0x6202e501, 0x10ae0703, 0x8b7ee1be, 0xc72c1cf6,
59      };
60  
61      private static final int[] EXPECTED_SEQUENCE_AFTER_LONG_JUMP  = {
62          0x27906b5a, 0xe2ce9fb2, 0xd97f8c4f, 0x7609af7d,
63          0x5b91ddd8, 0x4134b769, 0x47f505f2, 0xacc18832,
64          0xeea7faf6, 0x50178ca9, 0xc15f4b36, 0xcbd206e6,
65          0x4f2273cb, 0xebaabeef, 0x51e6d76f, 0xaf1fdde8,
66          0x3cb5ced1, 0x04b42264, 0x2396256f, 0x9c0618ff,
67          0x95ecbb0c, 0xc88c952c, 0x820664ab, 0x5d2e6153,
68          0xb2003213, 0x71531ff6, 0x99d4bd53, 0xbd15fcc1,
69          0x90ad002b, 0x3d37b45d, 0x500b49db, 0x6f81b35f,
70          0x533f3bab, 0xe22a25fe, 0x114ca833, 0x4ab45586,
71          0x077ca93d, 0xd5cf0025, 0xbe019f55, 0x8ecbe4a8,
72      };
73  
74      @Test
75      void testReferenceCode() {
76          RandomAssert.assertEquals(EXPECTED_SEQUENCE, new XoShiRo128PlusPlus(SEED));
77      }
78  
79      @Test
80      void testConstructorWithZeroSeedIsNonFunctional() {
81          RandomAssert.assertNextIntZeroOutput(new XoShiRo128PlusPlus(new int[SEED_SIZE]), 2 * SEED_SIZE);
82      }
83  
84      @Test
85      void testConstructorWithSingleBitSeedIsFunctional() {
86          RandomAssert.assertIntArrayConstructorWithSingleBitSeedIsFunctional(XoShiRo128PlusPlus.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 XoShiRo128PlusPlus(new int[] {SEED[0]}),
93                  SEED_SIZE, SEED_SIZE);
94      }
95  
96      @Test
97      void testElementConstructor() {
98          final XoShiRo128PlusPlus rng1 = new XoShiRo128PlusPlus(SEED);
99          final XoShiRo128PlusPlus rng2 = new XoShiRo128PlusPlus(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 XoShiRo128PlusPlus(SEED));
106     }
107 
108     @Test
109     void testLongJump() {
110         RandomAssert.assertLongJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_LONG_JUMP, new XoShiRo128PlusPlus(SEED));
111     }
112 }