// Copyright (C) 2010 Steffen Rendle, Zeno Gantner // Copyright (C) 2011 Zeno Gantner, Chris Newell // // This file is part of MyMediaLite. // // MyMediaLite is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // MyMediaLite 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with MyMediaLite. If not, see <http://www.gnu.org/licenses/>. package org.mymedialite.util; /** * Draws random values from a normal distributed using a simple rejection method. * @version 2.03 */ public class Random extends java.util.Random { private static final long serialVersionUID = 1L; private static Random instance = null; /** Default constructor */ public Random() { super(); } /** * Creates a Random object initialized with a seed. * @param seed an integer for initializing the random number generator */ public Random(long seed) { super(seed); } /** * Initializes the instance with a given random seed. * @param seed a seed value */ public static void initInstance(long seed) { instance = new Random(seed); } /** * Gets the instance. If it does not exist yet, it will be created. * @return the singleton instance */ public static Random getInstance() { //if (instance == null) instance = new Random(); instance = new Random(1234567890L); return instance; } private double sqrt_e_div_2_pi = Math.sqrt(Math.E / (2 * Math.PI)); /** * Get a random number within a specified range. * @param min the minimum of the range * @param max the maximum of the range * @return a random number within the specified range */ public int nextInt(int min, int max) { return nextInt(max - min) + min; } /** * Get the next exp. * @param lambda */ public double nextExp(double lambda) { double u = this.nextDouble(); return -(1 / lambda) * Math.log(1 - u); } /** * Get the next number from the standard normal distribution. * @return a random number drawn from the standard normal distribution */ public double nextNormal() { double y; double x; do { double u = this.nextDouble(); x = this.nextExp(1); y = 2 * u * sqrt_e_div_2_pi * Math.exp(-x); } while ( y < (2 / (2 * Math.PI)) * Math.exp(-0.5 * x * x)); if (this.nextDouble() < 0.5) { return x; } else { return -x; } } /** * Draw the next number from a normal distribution. * @param mean mean of the Gaussian * @param stdev standard deviation of the Gaussian * @return a random number drawn from a normal distribution with the given mean and standard deviation */ public double nextNormal(double mean, double stdev) { return mean + stdev * nextNormal(); } }