ngmf.ui.calc.RandomNormal Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oms Show documentation
Show all versions of oms Show documentation
Object Modeling System (OMS) is a pure Java object-oriented framework.
OMS v3.+ is a highly interoperable and lightweight modeling framework for component-based model and simulation development on multiple platforms.
/*
* $Id: RandomNormal.java 7cba5ba59d73 2018-11-29 [email protected] $
*
* This file is part of the Object Modeling System (OMS),
* 2007-2012, Olaf David and others, Colorado State University.
*
* OMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1.
*
* OMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OMS. If not, see .
*/
package ngmf.ui.calc;
import java.util.Random;
/**
* Utility class that generates normally-distributed
* random values using several algorithms.
*/
public class RandomNormal {
/** mean */
private float mean;
/** standard deviation */
private float stddev;
/** next random value from
* the polar algorithm */
private float nextPolar;
/** true if the next polar
* value is available */
private boolean haveNextPolar = false;
/** generator of uniformly-distributed random values */
private static Random gen = new Random();
/**
* Set the mean and standard deviation.
* @param mean the mean
* @param stddev the standard deviation
*/
public void setParameters(float mean, float stddev) {
this.mean = mean;
this.stddev = stddev;
}
/**
* Compute the next random value using the Central Limit Theorem,
* which states that the averages of sets of uniformly-distributed
* random values are normally distributed.
* @return the random value
*/
public float nextCentral() {
// Average 12 uniformly-distributed random values.
float sum = 0.0f;
for (int j = 0; j < 12; ++j)
sum += gen.nextFloat();
// Subtract 6 to center about 0.
return stddev*(sum - 6) + mean;
}
/**
* Compute the next randomn value using the polar algorithm.
* Requires two uniformly-distributed random values in [-1, +1).
* Actually computes two random values and saves the second one
* for the next invokation.
* @return the random value
*/
public float nextPolar() {
// If there's a saved value, return it.
if (haveNextPolar) {
haveNextPolar = false;
return nextPolar;
}
float u1, u2, r; // point coordinates and their radius
do {
// u1 and u2 will be uniformly-distributed
// random values in [-1, +1).
u1 = 2*gen.nextFloat() - 1;
u2 = 2*gen.nextFloat() - 1;
// Want radius r inside the unit circle.
r = u1*u1 + u2*u2;
} while (r >= 1);
// Factor incorporates the standard deviation.
float factor = (float) (stddev*Math.sqrt(-2*Math.log(r)/r));
// v1 and v2 are normally-distributed random values.
float v1 = factor*u1 + mean;
float v2 = factor*u2 + mean;
// Save v1 for next time.
nextPolar = v1;
haveNextPolar = true;
return v2;
}
// Constants for the ratio algorithm.
private static final float C1 = (float) Math.sqrt(8/Math.E);
private static final float C2 = (float) (4*Math.exp(0.25));
private static final float C3 = (float) (4*Math.exp(-1.35));
/**
* Compute the next random value using the ratio algorithm.
* Requires two uniformly-distributed random values in [0, 1).
* @return the random value
*/
public float nextRatio() {
float u, v, x, xx;
do {
// u and v are two uniformly-distributed random values
// in [0, 1), and u != 0.
while ((u = gen.nextFloat()) == 0); // try again if 0
v = gen.nextFloat();
float y = C1*(v - 0.5f); // y coord of point (u, y)
x = y/u; // ratio of point's coords
xx = x*x;
} while (
(xx > 5f - C2*u) // quick acceptance
&&
( (xx >= C3/u + 1.4f) || // quick rejection
(xx > (float) (-4*Math.log(u))) ) // final test
);
return stddev*x + mean;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy