/*********************************************************************** * @(#) LCGRandom.java 1.4 11/29/07 * * Copyright (c) 2007, John Miller * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * 3. Neither the name of the University of Georgia nor the names * of its contributors may be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @version 1.4, 29 November 2007 * @author John Miller */ // package jsim.variate; import static java.lang.System.*; /*********************************************************************** * Basic random number generator. * It is a multiplicative Linear Congruential Generator (LCG). * The generator can be adjusted simply by changing the * constants MULTIPIER (a) and MODULUS (m) (be careful). * Three choices for 'a' are given (for a discussion see * http://www.iro.umontreal.ca/~lecuyer/papers.html or * http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tutaor.ps) * The complete generated stream of MODULUS numbers is split * into MAX_STREAMS (stream from 0 to MAX_STREAMS - 1) by * appropriate setting of the SEED array (again be careful). * Note: MRG's or composite LCG's are better, but more complex. */ public class LCGRandom { public static final int MAX_STREAMS = 10; private static final long a = 16807; // 7^5 // private static final long a = 630360016; // alt. 1 // private static final long a = 742938285; // alt. 2 private static final long m = 2147483647; // 2^31 - 1 private static final double one_by_m = 1.0 / m; private static final long SEED [] = { 428956419, 1954324947, // only for 16807 1145661099, 1835732737, 794161987, 1329531353, 200496737, 633816299, 1410143363, 1282538739 }; /** Random number stream. */ private int stream; /** Current stram value. */ private long x; /** Array of parameters. */ private final Double [] params = new Double [1]; /******************************************************************* * Constructs an LCG-based Random Number Generator. * @param stream stream number (integer from 0 to MAX_STREAMS - 1) */ public LCGRandom (int stream) { this.stream = stream; x = SEED [stream]; params [0] = new Double (stream); } // LCGRandom constructor /******************************************************************* * Increment the stream. */ public void incrStream () { stream++; params [0] = new Double (stream); } // incrStream /******************************************************************* * Get the parameters for this generator as given by the constuctor. * @return Double The parameters. */ public Double [] getParameters () { return params; } // getParameters /******************************************************************* * Generates a real-valued random number in the range 0 to 1. * @return double A random number. */ public double gen () { x = (a * x) % m; // 64-bit integer arithmetic return ((double) x) * one_by_m; } // gen /******************************************************************* * Generates an integer-valued random number in the range 0 to m - 1. * @return long An integer-valued random number. */ public long igen () { x = (a * x) % m; // 64-bit integer arithmetic return x; } // igen /******************************************************************* * Main method of testing purposes. * @param args The command-line arguments. */ public static void main (String [] args) { LCGRandom rng = new LCGRandom (1); for (int i = 1; i < 26; i++) { out.print (rng.gen () + " , "); if (i % 5 == 0) out.println (); } // for } // main } // LCGRandom class