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.util.NumberFactory;
20  
21  /**
22   * This abstract class is a base for algorithms from the Permuted Congruential Generator (PCG)
23   * family that use an internal 64-bit Multiplicative Congruential Generator (MCG) and output
24   * 32-bits per cycle.
25   *
26   * @see <a href="http://www.pcg-random.org/">
27   *  PCG, A Family of Better Random Number Generators</a>
28   * @since 1.3
29   */
30  abstract class AbstractPcgMcg6432 extends IntProvider {
31      /** The state of the MCG. */
32      private long state;
33  
34      /**
35       * Creates a new instance.
36       *
37       * @param seed Initial seed.
38       */
39      AbstractPcgMcg6432(Long seed) {
40          // A seed of zero will result in a non-functional MCG; it must be odd for a maximal
41          // period MCG. The multiplication factor always sets the 2 least-significant bits to 1
42          // if they are already 1 so these are explicitly set. Bit k (zero-based) will have
43          // period 2^(k-1) starting from bit 2 with a period of 1. Bit 63 has period 2^62.
44          state = seed | 3;
45      }
46  
47      /**
48       * Provides the next state of the MCG.
49       *
50       * @param input Current state.
51       * @return next state
52       */
53      private static long bump(long input) {
54          return input * 6364136223846793005L;
55      }
56  
57      /** {@inheritDoc} */
58      @Override
59      public int next() {
60          final long x = state;
61          state = bump(state);
62          return transform(x);
63      }
64  
65      /**
66       * Transform the 64-bit state of the generator to a 32-bit output.
67       * The transformation function shall vary with respect to different generators.
68       *
69       * @param x State.
70       * @return the output
71       */
72      protected abstract int transform(long x);
73  
74      /** {@inheritDoc} */
75      @Override
76      protected byte[] getStateInternal() {
77          return composeStateInternal(NumberFactory.makeByteArray(state),
78                  super.getStateInternal());
79      }
80  
81      /** {@inheritDoc} */
82      @Override
83      protected void setStateInternal(byte[] s) {
84          final byte[][] d = splitStateInternal(s, 8);
85          // As per the constructor, ensure the lower 2 bits of state are set.
86          state = NumberFactory.makeLong(d[0]) | 3;
87          super.setStateInternal(d[1]);
88      }
89  }