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.apache.commons.rng.core.util.NumberFactory;
21  import org.junit.Assert;
22  import org.junit.Test;
23  
24  public class MiddleSquareWeylSequenceTest {
25      @Test
26      public void testReferenceCode() {
27          /*
28           * The data was generated using the following program based on the author's C code:
29           *     https://mswsrng.wixsite.com/rand
30           *
31           * #include <stdio.h>
32           * #include <stdint.h>
33           *
34           * uint64_t x, w, s;
35           *
36           * inline static uint32_t msws() {
37           *     x *= x; x += (w += s); return x = (x>>32) | (x<<32);
38           * }
39           *
40           * int main() {
41           *     x = 0x012de1babb3c4104;
42           *     w = 0xc8161b4202294965;
43           *     s = 0xb5ad4eceda1ce2a9;
44           *     for (int i=0; i<10; i++) {
45           *         for (int j=0; j<4; j++) {
46           *             printf("0x%08x, ", msws());
47           *         }
48           *         printf("\n");
49           *     }
50           * }
51           */
52          final long[] seed = {0x012de1babb3c4104L, 0xc8161b4202294965L, 0xb5ad4eceda1ce2a9L};
53  
54          final int[] expectedSequence = {
55              0xe7f4010b, 0x37bdb1e7, 0x05d8934f, 0x22970c75,
56              0xe7432a9f, 0xd157c60f, 0x26e9b5ae, 0x3dd91250,
57              0x8dbf85f1, 0x99e3aa17, 0xcb90322b, 0x29a007e2,
58              0x25a431fb, 0xcc612768, 0x510db5cd, 0xeb0aec2f,
59              0x05f88c18, 0xcdb79066, 0x5222c513, 0x9075045c,
60              0xf11a0e0e, 0x0106ab1d, 0xe2546700, 0xdf0a7656,
61              0x170e7908, 0x17a7b775, 0x98d69720, 0x74da3b78,
62              0x410ea18e, 0x4f708277, 0x471853e8, 0xa2cd2587,
63              0x16238d96, 0x57653154, 0x7ecbf9c8, 0xc5dd75bf,
64              0x32ed82a2, 0x4700e664, 0xb0ad77c9, 0xfb87df7b,
65          };
66  
67          RandomAssert.assertEquals(expectedSequence, new MiddleSquareWeylSequence(seed));
68      }
69  
70      /**
71       * Test the self-seeding functionality outputs non-zero output from the initial state.
72       *
73       * <p>Note: The generator quality is dependent on a high complexity Weyl increment. This
74       * test passes a seed without the increment set and expects the generator to work. The
75       * statistical quality of the output is not tested.</p>
76       */
77      @Test
78      public void testSelfSeeding() {
79          final int warmupCycles = 0;
80          final int testCycles = 3;
81          // Do not pass the Weyl increment (the 3rd value in the seed array)
82          RandomAssert.assertNextLongNonZeroOutput(new MiddleSquareWeylSequence(new long[2]),
83                  warmupCycles, testCycles);
84      }
85  
86      /**
87       * Test nextLong() returns two nextInt() values joined together. This tests the custom
88       * nextLong() routine in the implementation that overrides the default.
89       */
90      @Test
91      public void testNextLong() {
92          final long[] seed = {0x012de1babb3c4104L, 0xc8161b4202294965L, 0xb5ad4eceda1ce2a9L};
93          final MiddleSquareWeylSequence rng1 = new MiddleSquareWeylSequence(seed);
94          final MiddleSquareWeylSequence rng2 = new MiddleSquareWeylSequence(seed);
95          for (int i = 0; i < 50; i++) {
96              Assert.assertEquals(NumberFactory.makeLong(rng1.nextInt(), rng1.nextInt()),
97                                  rng2.nextLong());
98          }
99      }
100 }