/*
 * Encog(tm) Core v3.4 - Java Version
 * http://www.heatonresearch.com/encog/
 * https://github.com/encog/encog-java-core
 
 * Copyright 2008-2016 Heaton Research, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *   
 * For more information on Heaton Research copyrights, licenses 
 * and trademarks visit:
 * http://www.heatonresearch.com/copyright
 */
package org.encog.mathutil.randomize.generate;

/**
 * A Linear Congruential random number generator.  A Linear Congruential Generator (LCG) yields a sequence of
 * randomized numbers calculated with a linear equation. The method represents one of the oldest and best-known
 * pseudorandom number generator algorithms. Most programming languages use this technique.
 *
 * http://en.wikipedia.org/wiki/Linear_congruential_generator/
 * Donald Knuth, The Art of Computer Programming, Volume 3, Section 3.2.1
 */
public class LinearCongruentialRandom extends AbstractBoxMuller {

    /**
     * First part of default mod.
     */
    public static final long DEFAULT_MOD1 = 2L;

    /**
     * Second part of default mod.
     */
    public static final long DEFAULT_MOD2 = 32L;

    /**
     * Default mult.
     */
    public static final long DEFAULT_MULT = 1103515245L;

    /**
     * Default inc.
     */
    public static final long DEFAULT_INC = 12345L;

    /**
     * The modulus.
     */
    private final long modulus;

    /**
     * The multiplier.
     */
    private final long multiplier;

    /**
     * The amount to increment.
     */
    private final long increment;

    /**
     * The current seed, set to an initial value and always holds the value of
     * the last random number generated.
     */
    private long seed;

    /**
     * The maximum rand number that the standard GCC based LCG will generate.
     */
    public static final long MAX_RAND = 4294967295L;

    /**
     * Construct the default LCG. You need only specify a seed.
     *
     * @param theSeed The seed to use.
     */
    public LinearCongruentialRandom(final long theSeed) {
        this((long) Math.pow(DEFAULT_MOD1, DEFAULT_MOD2),
                DEFAULT_MULT, DEFAULT_INC, theSeed);
    }

    /**
     * Constructor to use a seed equal to system time.
     */
    public LinearCongruentialRandom() {
        this(System.currentTimeMillis());
    }

    /**
     * Create a LCG with the specified modulus, multiplier and increment. Unless
     * you REALLY KNOW WHAT YOU ARE DOING, just use the constructor that just
     * takes a seed. It will set these values to the same as set by the GCC C
     * compiler. Setting these values wrong can create fairly useless random
     * numbers.
     *
     * @param theModulus    The modulus for the LCG algorithm.
     * @param theMultiplier The multiplier for the LCG algorithm.
     * @param theIncrement  The increment for the LCG algorithm.
     * @param theSeed       The seed for the LCG algorithm. Using the same seed will give
     *                      the same random number sequence each time, whether in Java or
     *                      DotNet.
     */
    public LinearCongruentialRandom(final long theModulus,
                                    final long theMultiplier, final long theIncrement,
                                    final long theSeed) {
        super();
        this.modulus = theModulus;
        this.multiplier = theMultiplier;
        this.increment = theIncrement;
        this.seed = theSeed % MAX_RAND;
    }

    /**
     * @return The LCG increment.
     */
    public final long getIncrement() {
        return this.increment;
    }

    /**
     * @return The LCG modulus.
     */
    public final long getModulus() {
        return this.modulus;
    }

    /**
     * @return The LCG multiplier.
     */
    public final long getMultiplier() {
        return this.multiplier;
    }

    /**
     * @return The current seed. Set to a constant to start, thereafter the
     *         previously generated random number.
     */
    public final long getSeed() {
        return this.seed;
    }

    /**
     * @return The next random number as a double between 0 and 1.
     */
    @Override
    public final double nextDouble() {
        return (double) nextLong() / LinearCongruentialRandom.MAX_RAND;
    }

    /**
     * @return The next random number as a long between 0 and MAX_RAND.
     */
    @Override
    public final long nextLong() {
        this.seed = (this.multiplier * this.seed + this.increment)
                % this.modulus;
        return this.seed;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean nextBoolean() {
        return nextDouble() > 0.5;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public float nextFloat() {
        return (float) nextDouble();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int nextInt() {
        return (int) nextLong();
    }
}

 

Ads help maintain this website.