All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cornell.lassp.houle.RngPack.Ranlux Maven / Gradle / Ivy

The newest version!
package edu.cornell.lassp.houle.RngPack;
import java.util.*;
import java.io.Serializable;

//
// RngPack 1.1a by Paul Houle
// http://www.honeylocust.com/RngPack/
//

/**
*
*     RANLUX is an advanced pseudo-random number generator based on the
*     RCARRY algorithm proposed in 1991 by Marsaglia and Zaman.
*     RCARRY
*     used a subtract-and-borrow algorithm with a period on the order of
*     10171 but still had detectable correlations between
*     numbers.  Martin Luescher proposed the RANLUX
*     algorithm in 1993;  RANLUX generates pseudo-random numbers using
*     RCARRY but throws away numbers to destroy correlations.
*     Thus RANLUX trades execution speed for quality;  by choosing a
*     larger luxury setting one gets better random numbers slower.
*     By the tests availible at the time it was proposed,
*     RANLUX at the default luxury setting appears to be a
*     significant advance quality over previous
*     generators.
*
* 
*
*
* * * * * * * * * * * * * * * * * *
* LUXURY LEVELS *
levelp
0 24equivalent to the original RCARRY of Marsaglia * and Zaman, very long period, but fails many tests.
148considerable improvement in quality over level 0, * now passes the gap test, but still fails spectral test.
297 passes all known tests, but theoretically still * defective.
3223 * DEFAULT VALUE. Any theoretically possible * correlations have very small chance of being observed.
4389highest possible luxury, all 24 bits chaotic.
*
*
*
* VALIDATION *
* * The Java version of RANLUX has been verified against published * values of numbers 1-5 and 101-105 produced by the reference implementation * of RANLUX for the following initial conditions: * *
    *
  • Default initialization: Ranlux() *
  • Initialization with: Ranlux(0,0) *
  • Initialization with: Ranlux(389,1) *
  • Initialization with: Ranlux(75,0) *
* References: * * * *

* * Source code is available. * * @author Paul Houle (E-mail: [email protected]) * @version 1.1a */ public class Ranlux extends RandomSeedable implements Serializable { /** * Maximum luxury level: maxlev=4 */ public static final int maxlev=4; /** * Default luxury level: lxdflt=3 */ public static final int lxdflt=3; static final int igiga = 1000000000, jsdflt = 314159265; static final int twop12 = 4096,itwo24 = 1 << 24,icons = 2147483563; static final int ndskip[]={0,24,73,199,365}; int iseeds[],isdext[],next[]; int luxlev=lxdflt,nskip,inseed,jseed; int in24 = 0, kount = 0, mkount = 0, i24 = 24, j24 = 10; float seeds[],carry= (float) 0.0,twom24,twom12; boolean diagOn=false; /** * Default initialization of RANLUX. Uses default seed * jsdflt=314159265 and luxury level 3. */ public Ranlux() { init_arrays(); rluxdef(); }; /** * Initialize RANLUX with specified luxury level * and seed. * * @param lux luxury level from 0-4. * @param ins seed, a positive integer. * */ public Ranlux(int lux,int ins) { init_arrays(); rluxgo(lux,Math.abs(ins)); }; /** * Initialize RANLUX with specified luxury level * and seed. * * @param lux luxury level from 0-4. * @param ins seed, a positive long. * */ public Ranlux(int lux,long ins) { init_arrays(); rluxgo(lux,Math.abs((int) (ins%Integer.MAX_VALUE))); }; /** * * Initialize RANLUX with default luxury level * and a specified seed. * * @param ins seed, a positive integer */ public Ranlux(int ins) { init_arrays(); rluxgo(lxdflt,Math.abs(ins)); }; /** * * Initialize RANLUX with default luxury level * and a specified seed. * * @param ins seed, a positive integer */ public Ranlux(long ins) { init_arrays(); rluxgo(lxdflt,Math.abs((int) (ins%Integer.MAX_VALUE))); }; /** * * Initialize RANLUX with specified luxury level * and a Date object. Can be used to conveniently initialize RANLUX * from the clock, * *

* RandomElement e = Ranlux(4,new Date());
* 
* * @param lux luxury level from 0-4. * @param d date used to generate seed * */ public Ranlux(int lux,Date d) { init_arrays(); rluxgo(lux,(int) (ClockSeed(d)%Integer.MAX_VALUE) ); }; /** * * Initialize RANLUX with default luxury level * and a Date object. Can be used to conveniently initialize RANLUX * from the clock, * *
* RandomElement e = Ranlux(new Date());
* 
* * @param d date used to generate seed * */ public Ranlux(Date d) { init_arrays(); rluxgo(lxdflt,(int) (ClockSeed(d)%Integer.MAX_VALUE) ); }; /** * Turns diagnostic messages on and off. If setDiag(true) is * called, RANLUX will print diagnostic information to * System.err * * @param b diagnostic message status */ public void setDiag(boolean b) { diagOn=b; }; /** * * The random number generator. * * @return a pseudo-random double in the range (0,1) */ public final double raw() { int i,k,lp; float uni,out; uni=seeds[j24]-seeds[i24]-carry; if (uni < (float) 0.0) { uni=uni+ (float) 1.0; carry = twom24; } else carry = (float) 0.0; seeds[i24]=uni; i24=next[i24]; j24=next[j24]; out=uni; if (uni=igiga) { mkount++; kount -= igiga; }; return out; }; private void init_arrays() { /* * * converted from fortran: fortran arrays start at 1, java arrays start at * 0. Here we take the low road to compatibility... We declare arrays that * are one bigger than the fortran code. This wastes three ints and a double; * If you're porting this to a Commodore 64 you might need the space. * */ iseeds = new int[24+1]; isdext = new int[25+1]; next = new int[24+1]; seeds = new float[24+1]; }; private void rluxdef() { int lp,i,k; jseed = jsdflt; inseed = jseed; diag("RANLUX DEFAULT INITIALIZATION: "+jseed); luxlev = lxdflt; nskip = ndskip[luxlev]; lp = nskip + 24; in24 = 0; kount = 0; mkount = 0; diag("RANLUX DEFAULT LUXURY LEVEL = "+luxlev+" p = "+lp); twom24 = (float) 1.0; for(i = 1;i <= 24;i++) { twom24 = twom24 * (float) 0.5; k = jseed / 53668; jseed = 40014 * (jseed-k*53668) - k * 12211; if (jseed<0) jseed = jseed + icons; iseeds[i] = jseed % itwo24; }; twom12 = twom24 * (float) 4096.0; for(i = 1 ; i<=24;i++) { seeds[i] = iseeds[i] * twom24; next[i] = i - 1; }; next[1] = 24; i24 = 24; j24 = 10; carry = (float) 0.0; if (seeds[24] == 0.0) carry = twom24; }; private final void rluxgo(int lux,int ins) { int ilx, i, iouter, isk, k, inner, izip, izip2; float uni; if (lux<00) { luxlev = lxdflt; } else if (lux<=maxlev) { luxlev = lux; } else if (lux<24 || lux>2000) { luxlev = maxlev; diag("RANLUX ILLEGAL LUXURY RLUXGO: "+lux); } else { luxlev = lux; for(ilx=0;ilx<=maxlev;ilx++) if (lux == ndskip[ilx]+24) luxlev=ilx; }; if (luxlev <= maxlev) { nskip = ndskip[luxlev]; diag("RANLUX LUXURY LEVEL SET BY RLUXGO : "+luxlev+" P= "+(nskip+24)); } else { nskip = luxlev-24; diag("RANLUX P-VALUE SET BY RLUXGO TO: "+luxlev); }; in24=0; if (ins<0) diag("Illegal initialization by RLUXGO, negative input seed"); if (ins>0) { jseed = ins; diag("RANLUX INITIALIZED BY RLUXGO FROM SEED "+jseed); } else { jseed=jsdflt; diag("RANLUX INITIALIZED BY RLUXGO FROM DEFAULT SEED"); }; inseed = jseed; twom24 = (float) 1.0; for(i=1;i<=24;i++) { twom24 = twom24 * (float) 0.5; k = jseed / 53668; jseed = 40014 * (jseed-k*53668) - k * 12211; if (jseed < 0) jseed = jseed + icons; iseeds[i] = jseed % itwo24; }; twom12=twom24*4096; for(i=1;i<=24;i++) { seeds[i] = iseeds[i] * twom24; next[i] = i - 1; }; next[1]=24; i24=24; j24=10; carry = (float) 0.0; if (seeds[24] == 0.0) carry = twom24; kount = 0; mkount = 0; }; private void diag(String s) { if (diagOn) System.err.println(s); }; };




© 2015 - 2024 Weber Informatics LLC | Privacy Policy