/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library 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 3 of the License, or (at your option) any later version.
This library 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 library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.util.random;
import xxl.core.math.functions.RealFunction;
/** The class provides a random number generator delivering random numbers distributed
* like a user-defined function F. <BR>
*
* If f(x) is the pdf of the distribution F, a function g(x) with f(x) <= c * g(x) for some constant c
* must be given with g(x) the pdf of a distribution G.
* Random numbers with distribution F could be obtained by the following algorithm:
* (1) Generrate a random number x with distribution G <BR>
* (2) calculate r = c * g(x) / f(x) <BR>
* (3) Generrate an unifomly distribution random number u ( ~ U[0,1]) <BR>
* (4) IF u*r < 1 return x, otherwise start again <BR>
* To obtain random numbers x with x ~ G the {@link InversionDistributionBasedPRNG} could be used. <BR>
* For producing random numbers use an instance of this class with the
* {@link xxl.core.cursors.sources.ContinuousRandomNumber ContinuousRandomNumber cursor}.
*/
public class RejectionDistributionBasedPRNG implements ContinuousRandomWrapper{
/** pdf of the distribution F */
RealFunction f;
/** pdf of the distribution G */
RealFunction g;
/** some constant with f(x) <= c * g(x) f.a. x */
double c;
/** random wrapper delivering random numbers x with x ~ G */
ContinuousRandomWrapper crwG;
/** random wrapper delivering random numbers u with u ~ U[0,1] */
ContinuousRandomWrapper crw;
/** Constructs a new object of the class.
*
*
* @param crw random wrapper delivering random numbers u with u ~ U[0,1]
* @param f pdf of the distribution F the produced random numbers should belong to
* @param g pdf of the distribution G with f(x) <= c * g(x) f.a. x
* @param c the constant c in f(x) <= c * g(x) f.a. x
* @param crwG random wrapper delivering random numbers x with x ~ G
*
* @see InversionDistributionBasedPRNG
* @see ContinuousRandomWrapper
* @see xxl.core.math.functions.RealFunction
*/
public RejectionDistributionBasedPRNG( ContinuousRandomWrapper crw, RealFunction f, RealFunction g, double c, ContinuousRandomWrapper crwG){
this.crw = crw;
this.f = f;
this.g = g;
this.c = c;
this.crwG = crwG;
}
/** Return the next computed pseudo random number x with x ~ F.
* @return the next computed pseudo random number x with x ~ F.
*/
public double nextDouble(){
double x = -1.0;
boolean found = false;
do{
x = crwG.nextDouble();
double r = c * g.eval( x) / f.eval( x);
double u = crw.nextDouble();
if ( u*r < 1.0)
found = true;
}
while (! found);
return x;
}
}