edu.cornell.lassp.houle.RngPack.RandomElement Maven / Gradle / Ivy
package edu.cornell.lassp.houle.RngPack; import java.util.*; // // RngPack 1.1a by Paul Houle // http://www.honeylocust.com/RngPack/ // /** * RandomElement is an abstract class that encapsulates random number * generators. To base a class on it, you must define the method *
* withraw()
as described below. It is also likely that you * will want to define a constructor or another mechanism for seeding the * the generator. The other classes defined inRandomElement
* add value to the numbers generated byraw()
* ** * Source code is available. * * @author Paul Houle (E-mail: [email protected]) * @version 1.1a * * @see RandomJava * @see RandomShuffle */ public abstract class RandomElement extends Object implements Cloneable { Double BMoutput; // constant needed by Box-Mueller algorithm /** * The abstract method that must be defined to make a working RandomElement. * See the class
RandomJava
for an example of how to do this. * * @see RandomJava * * @return a random double in the range [0,1] */ abstract public double raw(); /** * Fill part or all of an array with doubles. The method defined here uses multiple calls to *raw()
to fill the array. You can eliminate the overhead of * multiple method calls by subclassing this with a version of the generator * that fills the array. On our system this improves the efficiency of *Ranecu
by 20% when filling large arrays. * * * @param d array to be filled with doubles * @param n number of doubles to generate */ public void raw(double d[],int n) { for(int i=0;iraw(double d[],int n) d=d.length
. Since this adds little overhead ford.length
* large, it is only necessary to overrideraw(double d[],int n)
* * @param d array to be filled with doubles. */ public void raw(double d[]) { raw(d,d.length); } /** @param hi upper limit of range @return a random integer in the range 1,2,... ,hi */ public int choose(int hi) { return choose(1,hi); } /** * @param lo lower limit of range * @param hi upper limit of range * @return a random integer in the range lo, lo+1, ... ,hi */ public int choose(int lo,int hi) { int value=lo + (int) ((hi-lo)*raw()); if (value>hi) value=hi; /* otherwise a generator on [0,1] could return a result outside of the legal range: you can override this if you know a generator returns [0,1) or (0,1). */ return value; } /** @return a boolean that's true 0.5 of the time; equivalent to coin(0.5). */ public boolean coin() { return raw()<=0.5; } /** @param p probability that function will return true @return a boolean that's true p of the time. */ public boolean coin(double p) { return raw()<=p; } /** @param lo lower limit of range @param hi upper limit of range @return a uniform random real in the range [lo,hi] */ public double uniform(double lo,double hi) { return (lo+(hi-lo)*raw()); } /** gaussian() uses the Box-Muller algorithm to transform raw()'s into gaussian deviates. @return a random real with a gaussian distribution, standard deviation */ public double gaussian() { double out,x,y,r,z; if (BMoutput != null) { out = BMoutput.doubleValue(); BMoutput = null; return(out); }; do { x=uniform(-1,1); y=uniform(-1,1); r=x*x+y*y; } while (r >= 1.0); z=Math.sqrt(-2.0*Math.log(r)/r); BMoutput=new Double(x*z); return(y*z); } /** * * @param sd standard deviation * @return a gaussian distributed random real with standard deviation sd */ public double gaussian(double sd) { return(gaussian()*sd); } /** * * generate a power-law distribution with exponentalpha
* and lower cutoff *cut
** * *@param alpha the exponent *@param cut the lower cutoff * */ public double powlaw(double alpha,double cut) { return cut*Math.pow(raw(), 1.0/(alpha+1.0) ) ; } public Object clone() throws java.lang.CloneNotSupportedException { return super.clone(); } };