All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.finmath.randomnumbers.AcceptanceRejectionRandomNumberGenerator Maven / Gradle / Ivy

/*
 * (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
 *
 * Created on 21 May 2018
 */
package net.finmath.randomnumbers;

import java.util.function.DoubleUnaryOperator;

import org.apache.commons.lang3.Validate;

/**
 * Class implementing RandomNumberGenerator by the acceptance rejection method.
 *
 * Note that the acceptance rejection methods requires a two dimensional uniform random number sequence with independent components.
 *
 * @author Christian Fries
 * @version 1.0
 */
public class AcceptanceRejectionRandomNumberGenerator implements RandomNumberGenerator {

	private static final long serialVersionUID = -9060003224133337426L;

	private final RandomNumberGenerator uniformRandomNumberGenerator;
	private final DoubleUnaryOperator targetDensity;
	private final DoubleUnaryOperator referenceDensity;
	private final DoubleUnaryOperator referenceDistributionICDF;
	private final double acceptanceLevel;

	public AcceptanceRejectionRandomNumberGenerator(final RandomNumberGenerator uniformRandomNumberGenerator,
			final DoubleUnaryOperator targetDensity,
			final DoubleUnaryOperator referenceDensity,
			final DoubleUnaryOperator referenceDistributionICDF,
			final double acceptanceLevel) {
		Validate.inclusiveBetween(2, Integer.MAX_VALUE, uniformRandomNumberGenerator.getDimension(), "The acceptance rejection method requires a uniform distributed random number generator with at least dimension 2.");

		this.uniformRandomNumberGenerator = uniformRandomNumberGenerator;
		this.targetDensity = targetDensity;
		this.referenceDensity = referenceDensity;
		this.referenceDistributionICDF = referenceDistributionICDF;
		this.acceptanceLevel = acceptanceLevel;
	}

	@Override
	public double[] getNext() {
		boolean rejected = true;
		double y = Double.NaN;
		while(rejected) {
			final double[] uniform = uniformRandomNumberGenerator.getNext();
			final double u = uniform[0];
			y = referenceDistributionICDF.applyAsDouble(uniform[1]);
			rejected = targetDensity.applyAsDouble(y) < u * acceptanceLevel * referenceDensity.applyAsDouble(y);
		}
		return new double[] { y };
	}

	@Override
	public int getDimension() {
		return 1;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy