//package edu.cornell.lassp.houle.RngPack; import java.util.*; // // RngPack 1.0 by Paul Houle // http://www.msc.cornell.edu/~houle/rngpack // /** * * Ranecu is an advanced multiplicative linear congruential random number * generator with a period of aproximately 10<SUP>18</SUP>. * Ranecu is a direct translation from Fortran of the <B>RANECU</B> * subroutine * published in the paper * <BR> * F. James, <CITE>Comp. Phys. Comm.</CITE> <STRONG>60</STRONG> (1990) p 329-344 * <BR> * The algorithm was originally described in * <BR> * P. L'Ecuyer, <CITE>Commun. ACM.</CITE> <STRONG>1988</STRONG> (1988) p 742 * <BR> * * <P> * <A HREF="../src/edu/cornell/lassp/houle/RngPack/Ranecu.java" TARGET="edu.cornell.lassp.houle.source"> * Source code </A> is available. * * @author <A HREF="http://www.msc.cornell.edu/~houle"> Paul Houle </A> (E-mail: <A HREF="mailto:houle@msc.cornell.edu">houle@msc.cornell.edu</A>) * @version 1.0 */ public class Ranecu extends RandomSeedable { int iseed1,iseed2; /** * default iseed1 = 12345 */ public static int DEFSEED1=12345; /** * default iseed2 = 67890 */ public static int DEFSEED2=67890; /** * * Initialize <BOLD>RANECU</BOLD> with the default seeds from * James. * */ public Ranecu() { iseed1=DEFSEED1; iseed2=DEFSEED2; }; /** * * Initialize <BOLD>RANECU</BOLD> with two specified integer seeds. Use * this to introduce repeatable seeds. Equivalent to * * <CODE>Ranecu(s1*(long) Integer.MAX_VALUE)+s2)</CODE> * * @param s1 seed integer 1 (MSW) * @param s2 seed integer 2 (LSW) * */ public Ranecu(int s1,int s2){ iseed1=s1; iseed2=s2; }; /* * * Initialize <TT>RANECU</TT> with a long seed. * * @param l long integer seed */ public Ranecu(long l) { iseed1 = (int) l/Integer.MAX_VALUE; iseed2 = (int) l%Integer.MAX_VALUE; }; /* * * Initialize <TT>RANECU</TT> from the clock without saving a copy * of the seed. Example: * * <PRE> * RandomElement e = new Ranecu(new Date()); * </PRE> * * to save the seed for future restarts, see the <CODE>ClockSeed()</CODE> * method defined in RandomSeedable. * * @param d a date, typically <CODE>new Date()</CODE> * @see RandomSeedable#ClockSeed() */ public Ranecu(Date d) { iseed1 = (int) d.getTime()/Integer.MAX_VALUE; iseed2 = (int) d.getTime()%Integer.MAX_VALUE; }; /** @see RandomElement#raw */ final public double raw() { int k,iz; k=iseed1/53688; iseed1=40014*(iseed1-k*53668)-k*12211; if (iseed1<0) iseed1=iseed1+2147483563; k=iseed2/52774; iseed2=40692*(iseed2-k*52774)-k*3791; if (iseed2<0) iseed2=iseed2+2147483399; iz=iseed1-iseed2; if(iz<1) iz=iz+2147483562; return(iz*4.656613e-10); }; /** * This is an inline version that returns an array of doubles for speed. */ final public void raw(double d[],int n) { int i,k,iz; for(i=0;i<n;i++) { k=iseed1/53688; iseed1=40014*(iseed1-k*53668)-k*12211; if (iseed1<0) iseed1=iseed1+2147483563; k=iseed2/52774; iseed2=40692*(iseed2-k*52774)-k*3791; if (iseed2<0) iseed2=iseed2+2147483399; iz=iseed1-iseed2; if(iz<1) iz=iz+2147483562; d[i]=iz*4.656613e-10; }; }; /** * * @return the current generator state as a long. Can be used to * restart the generator where one left off. * */ public long getSeed() { return iseed1*(long) Integer.MAX_VALUE + iseed2; }; };