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  
18  package org.apache.commons.rng.simple.internal;
19  
20  import org.apache.commons.math3.stat.inference.ChiSquareTest;
21  import org.apache.commons.rng.UniformRandomProvider;
22  import org.apache.commons.rng.core.source64.SplitMix64;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.Test;
25  import java.util.Arrays;
26  
27  /**
28   * Tests for the {@link SeedUtils}.
29   */
30  class SeedUtilsTest {
31      /**
32       * Test the int hex permutation has 8 unique hex digits per permutation.
33       * A uniformity test is performed on to check each hex digits is used evenly at each
34       * character position.
35       */
36      @Test
37      void testCreateIntHexPermutation() {
38          final UniformRandomProvider rng = new SplitMix64(-567435247L);
39          final long[][] samples = new long[8][16];
40          for (int i = 0; i < 1000; i++) {
41              int sample = SeedUtils.createIntHexPermutation(rng);
42              int observed = 0;
43              for (int j = 0; j < 8; j++) {
44                  final int digit = sample & 0xf;
45                  Assertions.assertEquals(0, observed & (1 << digit), "Duplicate digit in sample");
46                  observed |= 1 << digit;
47                  samples[j][digit]++;
48                  sample >>>= 4;
49              }
50          }
51  
52          final ChiSquareTest chiSquareTest = new ChiSquareTest();
53          final double[] expected = new double[16];
54          Arrays.fill(expected, 1.0 / 16);
55          // Pass if we cannot reject null hypothesis that distributions are the same.
56          for (int j = 0; j < 8; j++) {
57              Assertions.assertFalse(chiSquareTest.chiSquareTest(expected, samples[j], 0.001),
58                  "Not uniform in digit " + j);
59          }
60      }
61  
62      /**
63       * Test the long hex permutation has 8 unique hex digits per permutation in the upper and
64       * lower 32-bits.
65       * A uniformity test is performed on to check each hex digits is used evenly at each
66       * character position.
67       */
68      @Test
69      void testCreateLongHexPermutation() {
70          final UniformRandomProvider rng = new SplitMix64(34645768L);
71          final long[][] samples = new long[16][16];
72          for (int i = 0; i < 1000; i++) {
73              long sample = SeedUtils.createLongHexPermutation(rng);
74              // Check lower 32-bits
75              long observed = 0;
76              for (int j = 0; j < 8; j++) {
77                  final int digit = (int) (sample & 0xfL);
78                  Assertions.assertEquals(0, observed & (1 << digit), "Duplicate digit in lower sample");
79                  observed |= 1 << digit;
80                  samples[j][digit]++;
81                  sample >>>= 4;
82              }
83              // Check upper 32-bits
84              observed = 0;
85              for (int j = 8; j < 16; j++) {
86                  final int digit = (int) (sample & 0xfL);
87                  Assertions.assertEquals(0, observed & (1 << digit), "Duplicate digit in upper sample");
88                  observed |= 1 << digit;
89                  samples[j][digit]++;
90                  sample >>>= 4;
91              }
92          }
93  
94          final ChiSquareTest chiSquareTest = new ChiSquareTest();
95          final double[] expected = new double[16];
96          Arrays.fill(expected, 1.0 / 16);
97          // Pass if we cannot reject null hypothesis that distributions are the same.
98          for (int j = 0; j < 16; j++) {
99              Assertions.assertFalse(chiSquareTest.chiSquareTest(expected, samples[j], 0.001),
100                 "Not uniform in digit " + j);
101         }
102     }
103 }