Mega Code Archive

 
Categories / Java / Development Class
 

A GaussianHat is a random number generator that will give you numbers based on a population mean and standard deviation.

// $Id: GaussianHat.java 12 2009-11-09 22:58:47Z gabe.johnson $ //package org.six11.util.data; import java.util.Random; /**  * A GaussianHat is a random number generator that will give you numbers based  * on a population mean and standard deviation. You can ask it for integers or  * probabilities. You may also specify a floor and ceiling (so in that case it's  * not truely Gaussian).  */ public class GaussianHat {   // this is necessary because if you create a few GaussianHats   // during the same millisecond and then use them in the exact   // manner, they will yield the same 'random' numbers if you ask   // for the same kinds of random numbers in the same order, which   // is absolutely no good. So we'll create a single Random that   // will then generate better Randoms from it.   static Random staticRand;   static {     staticRand = new Random(System.currentTimeMillis());   }   double mean;   double sd;   Random rand;   double floor;   double ceiling;   /**    * Creates a copy of the input GaussianHat.    */   public GaussianHat(GaussianHat other) {     this(other.mean, other.sd, other.floor, other.ceiling);   }   public GaussianHat(double mean, double sd, double floor, double ceiling) {     this.mean = mean;     this.sd = sd;     this.floor = floor;     this.ceiling = ceiling;     this.rand = new Random(staticRand.nextLong());   }   public GaussianHat(double mean, double sd) {     this(mean, sd, 0, Double.MAX_VALUE);   }   public GaussianHat(int mean, double sd) {     this((double) mean, sd);   }   public GaussianHat(int mean, int sd) {     this((double) mean, (double) sd);   }   public GaussianHat(int mean, int sd, int floor, int ceiling) {     this((double) mean, (double) sd, (double) floor, (double) ceiling);   }   public GaussianHat(double mean) {     this(mean, 1.0);   }   public void setMean(double mean) {     this.mean = mean;   }   public void setStdDev(double sd) {     this.sd = sd;   }   public int getInt() {     // simply return getDouble() as an int.     return (int) getDouble();   }   public double getDouble() {     // based on the mean and standard deviation, pick a number from a normal     // distribution, cast it to an integer     double d = (rand.nextGaussian() * sd) + mean;     if (d < floor)       d = floor;     if (d > ceiling)       d = ceiling;     return d;   }   public double getUniformDouble() {     double d = rand.nextDouble();     d = floor + (d * (ceiling - floor));     return d;   }   public boolean getYesNo() {     // get a random number from uniform distribution 0..1 and return true if     // that number is less than or equal to the provided 'chance' parameter     return (rand.nextDouble() <= mean);   }   public String toString() {     return mean + " (" + sd + ")";   }   public static void main(String[] args) {     // I have convinced myself that my randomness is OK using JMP     GaussianHat[] intHats = new GaussianHat[] { new GaussianHat(10, 2),         new GaussianHat(10, 4), new GaussianHat(20, 2),         new GaussianHat(20, 4) };     GaussianHat[] chanceHats = new GaussianHat[] {         new GaussianHat(0.60, 0.05), new GaussianHat(0.60, 0.15),         new GaussianHat(0.30, 0.05), new GaussianHat(0.30, 0.15) };     for (int trial = 1; trial <= 100; trial++) {       for (int i = 0; i < intHats.length; i++) {         System.out.print(intHats[i].getInt() + "\t");         if (i == (intHats.length - 1))           System.out.println();       }     }     for (int trial = 1; trial <= 100; trial++) {       for (int i = 0; i < chanceHats.length; i++) {         System.out.print(chanceHats[i].getYesNo() + "\t");         if (i == (chanceHats.length - 1))           System.out.println();       }     }   } }