BaseRandomGenerator.java

  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.  *      https://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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.random;

  22. import org.hipparchus.exception.LocalizedCoreFormats;
  23. import org.hipparchus.exception.MathIllegalArgumentException;
  24. import org.hipparchus.util.FastMath;
  25. import org.hipparchus.util.SinCos;

  26. /**
  27.  * Base class with default implementations for common methods.
  28.  */
  29. abstract class BaseRandomGenerator implements RandomGenerator {

  30.     /** Next gaussian. */
  31.     private double nextGaussian = Double.NaN;

  32.     /** {@inheritDoc} */
  33.     @Override
  34.     public void setSeed(int seed) {
  35.         setSeed(new int[] { seed });
  36.     }

  37.     /** {@inheritDoc} */
  38.     @Override
  39.     public void setSeed(long seed) {
  40.         setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffL) });
  41.     }

  42.     /** {@inheritDoc} */
  43.     @Override
  44.     public int nextInt(int n) throws IllegalArgumentException {
  45.         if (n <= 0) {
  46.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED,
  47.                                                    n, 0);
  48.         }

  49.         if ((n & -n) == n) {
  50.             return (int) ((n * (long) (nextInt() >>> 1)) >> 31);
  51.         }
  52.         int bits;
  53.         int val;
  54.         do {
  55.             bits = nextInt() >>> 1;
  56.             val = bits % n;
  57.         } while (bits - val + (n - 1) < 0);
  58.         return val;
  59.     }

  60.     /** {@inheritDoc} */
  61.     @Override
  62.     public long nextLong(long n) {
  63.         if (n <= 0) {
  64.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED,
  65.                                                    n, 0);
  66.         }

  67.         long bits;
  68.         long val;
  69.         do {
  70.             bits = nextLong() >>> 1;
  71.             val  = bits % n;
  72.         } while (bits - val + (n - 1) < 0);
  73.         return val;
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public double nextGaussian() {

  78.         final double random;
  79.         if (Double.isNaN(nextGaussian)) {
  80.             // generate a new pair of gaussian numbers
  81.             final double x = nextDouble();
  82.             final double y = nextDouble();
  83.             final double alpha = 2 * FastMath.PI * x;
  84.             final double r     = FastMath.sqrt(-2 * FastMath.log(y));
  85.             final SinCos scAlpha = FastMath.sinCos(alpha);
  86.             random       = r * scAlpha.cos();
  87.             nextGaussian = r * scAlpha.sin();
  88.         } else {
  89.             // use the second element of the pair already generated
  90.             random = nextGaussian;
  91.             nextGaussian = Double.NaN;
  92.         }

  93.         return random;

  94.     }

  95.     /**
  96.      * Clears the cache used by the default implementation of
  97.      * {@link #nextGaussian()}.
  98.      */
  99.     protected void clearCache() {
  100.         nextGaussian = Double.NaN;
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public String toString() {
  105.         return getClass().getName();
  106.     }

  107. }