GaussianHat.java Source code

Java tutorial

Introduction

Here is the source code for GaussianHat.java

Source

// $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();
            }
        }
    }
}