/* $RCSfile$
* $Author$
* $Date$
* $Revision$
*
* Copyright (C) 1997-2007 The Chemistry Development Kit (CDK) project
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program 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; either version 2.1
* of the License, or (at your option) any later version.
* All we ask is that proper credit is given for our work, which includes
* - but is not limited to - adding the above copyright notice to the beginning
* of your source code files, and to any copyright notice that you may distribute
* with programs based on this work.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.openscience.cdk.math;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import java.util.Random;
/**
* Class supplying useful methods to generate random numbers.
* This class isn't supposed to be instantiated. You should use it by calling
* its static methods.
*
* @cdk.module standard
* @cdk.githash
*/
@TestClass("org.openscience.cdk.math.RandomNumbersToolTest")
public class RandomNumbersTool extends Random {
private static final long serialVersionUID = -8238833473383641882L;
private static java.util.Random random;
private static long randomSeed;
static {
randomSeed = System.currentTimeMillis();
random = new java.util.Random(randomSeed);
}
/**
* Sets the base generator to be used by this class.
* <p/>
*
* @param base_random a <code>java.util.Random</code> subclass.
*/
@TestMethod("testSetRandom")
public static void setRandom(java.util.Random base_random) {
random = base_random;
}
/**
* Sets the seed of this random number generator using a single
* <code>long</code> seed.
*
* @param new_seed the seed to be used by the random number generator.
*/
@TestMethod("testSetRandomSeed_long")
public static void setRandomSeed(long new_seed) {
randomSeed = new_seed;
random.setSeed(randomSeed);
}
/**
* Returns the seed being used by this random number generator.
* <p/>
*
* @return the <code>long</code> seed.
*/
@TestMethod("testGetRandomSeed")
public static long getRandomSeed() {
return randomSeed;
}
/**
* Returns the instance of Random used by this class.
*
* @return An object of Random
*/
@TestMethod("testSetRandom")
public static Random getRandom() {
return random;
}
/**
* Generates a random integer between <code>0</code> and <code>1</code>.
* <p/>
*
* @return a random integer between <code>0</code> and <code>1</code>.
*/
@TestMethod("testRandomInt")
public static int randomInt() {
return randomInt(0, 1);
}
/**
* Generates a random integer between the specified values.
* <p/>
*
* @param lo the lower bound for the generated integer.
* @param hi the upper bound for the generated integer.
* @return a random integer between <code>lo</code> and <code>hi</code>.
*/
@TestMethod("testRandomInt_int_int")
public static int randomInt(int lo, int hi) {
return (Math.abs(random.nextInt()) % (hi - lo + 1)) + lo;
}
/**
* Generates a random long between <code>0</code> and <code>1</code>.
* <p/>
*
* @return a random long between <code>0</code> and <code>1</code>.
*/
@TestMethod("testRandomLong")
public static long randomLong() {
return randomLong(0, 1);
}
/**
* Generates a random long between the specified values.
* <p/>
*
* @param lo the lower bound for the generated long.
* @param hi the upper bound for the generated long.
* @return a random long between <code>lo</code> and <code>hi</code>.
*/
@TestMethod("testRandomLong_long_long")
public static long randomLong(long lo, long hi) {
return (Math.abs(random.nextLong()) % (hi - lo + 1)) + lo;
}
/**
* Generates a random float between <code>0</code> and <code>1</code>.
* <p/>
*
* @return a random float between <code>0</code> and <code>1</code>.
*/
@TestMethod("testRandomFloat")
public static float randomFloat() {
return random.nextFloat();
}
/**
* Generates a random float between the specified values.
* <p/>
*
* @param lo the lower bound for the generated float.
* @param hi the upper bound for the generated float.
* @return a random float between <code>lo</code> and <code>hi</code>.
*/
@TestMethod("testRandomFloat_float_float")
public static float randomFloat(float lo, float hi) {
return (hi - lo) * random.nextFloat() + lo;
}
/**
* Generates a random double between <code>0</code> and <code>1</code>.
* <p/>
*
* @return a random double between <code>0</code> and <code>1</code>.
*/
@TestMethod("testRandomDouble")
public static double randomDouble() {
return random.nextDouble();
}
/**
* Generates a random double between the specified values.
* <p/>
*
* @param lo the lower bound for the generated double.
* @param hi the upper bound for the generated double.
* @return a random double between <code>lo</code> and <code>hi</code>.
*/
@TestMethod("testRandomDouble_double_double")
public static double randomDouble(double lo, double hi) {
return (hi - lo) * random.nextDouble() + lo;
}
/**
* Generates a random boolean.
* <p/>
*
* @return a random boolean.
*/
@TestMethod("testRandomBoolean")
public static boolean randomBoolean() {
return (randomInt() == 1);
}
/**
* Generates a random bit: either <code>0</code> or <code>1</code>.
* <p/>
*
* @return a random bit.
*/
@TestMethod("testRandomBit")
public static int randomBit() {
return randomInt();
}
/**
* Returns a boolean value based on a biased coin toss.
* <p/>
*
* @param p the probability of success.
* @return <code>true</code> if a success was found; <code>false</code>
* otherwise.
*/
@TestMethod("testFlipCoin")
public static boolean flipCoin(double p) {
return (randomDouble() < p ? true : false);
}
/**
* Generates a random float from a Gaussian distribution with the specified
* deviation.
* <p/>
*
* @param dev the desired deviation.
* @return a random float from a Gaussian distribution with deviation
* <code>dev</code>.
*/
@TestMethod("testGaussianFloat")
public static float gaussianFloat(float dev) {
return (float) random.nextGaussian() * dev;
}
/**
* Generates a random double from a Gaussian distribution with the specified
* deviation.
* <p/>
*
* @param dev the desired deviation.
* @return a random double from a Gaussian distribution with deviation
* <code>dev</code>.
*/
@TestMethod("testGaussianDouble")
public static double gaussianDouble(double dev) {
return random.nextGaussian() * dev;
}
/**
* Generates a random double from an Exponential distribution with the specified
* mean value.
* <p/>
*
* @param mean the desired mean value.
* @return a random double from an Exponential distribution with mean value
* <code>mean</code>.
*/
@TestMethod("testExponentialDouble")
public static double exponentialDouble(double mean) {
return -mean * Math.log(randomDouble());
}
}