blob: 3fa5ace1ee0ae65d35f515dd08c0051f2fea0970 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.rng.examples.sampling;
import java.io.PrintWriter;
import java.io.IOException;
import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.simple.RandomSource;
import org.apache.commons.rng.sampling.distribution.ZigguratNormalizedGaussianSampler;
import org.apache.commons.rng.sampling.distribution.MarsagliaNormalizedGaussianSampler;
import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler;
import org.apache.commons.rng.sampling.distribution.ChengBetaSampler;
import org.apache.commons.rng.sampling.distribution.AhrensDieterExponentialSampler;
import org.apache.commons.rng.sampling.distribution.AhrensDieterMarsagliaTsangGammaSampler;
import org.apache.commons.rng.sampling.distribution.InverseTransformParetoSampler;
import org.apache.commons.rng.sampling.distribution.LogNormalSampler;
import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler;
import org.apache.commons.rng.sampling.distribution.GaussianSampler;
import org.apache.commons.rng.sampling.distribution.ContinuousSampler;
/**
* Approximation of the probability density by the histogram of the sampler output.
*/
public class ProbabilityDensityApproximation {
/** Number of (equal-width) bins in the histogram. */
private final int numBins;
/** Number of samples to be generated. */
private final long numSamples;
/**
* Application.
*
* @param numBins Number of "equal-width" bins.
* @param numSamples Number of samples.
*/
private ProbabilityDensityApproximation(int numBins,
long numSamples) {
this.numBins = numBins;
this.numSamples = numSamples;
}
/**
* @param sampler Sampler.
* @param min Right abscissa of the first bin: every sample smaller
* than that value will increment an additional bin (of infinite width)
* placed before the first "equal-width" bin.
* @param Left abscissa of the last bin: every sample larger than or
* equal to that value will increment an additional bin (of infinite
* width) placed after the last "equal-width" bin.
* @param output Filename.
*/
private void createDensity(ContinuousSampler sampler,
double min,
double max,
String outputFile)
throws IOException {
final double binSize = (max - min) / numBins;
final long[] histogram = new long[numBins];
long n = 0;
long belowMin = 0;
long aboveMax = 0;
while (++n < numSamples) {
final double r = sampler.sample();
if (r < min) {
++belowMin;
continue;
}
if (r >= max) {
++aboveMax;
continue;
}
final int binIndex = (int) ((r - min) / binSize);
++histogram[binIndex];
}
final double binHalfSize = 0.5 * binSize;
final double norm = 1 / (binSize * numSamples);
final PrintWriter out = new PrintWriter(outputFile);
out.println("# Sampler: " + sampler);
out.println("# Number of bins: " + numBins);
out.println("# Min: " + min + " (fraction of samples below: " + (belowMin / (double) numSamples) + ")");
out.println("# Max: " + max + " (fraction of samples above: " + (aboveMax / (double) numSamples) + ")");
out.println("# Bin width: " + binSize);
out.println("# Histogram normalization factor: " + norm);
out.println("#");
out.println("# " + (min - binHalfSize) + " " + (belowMin * norm));
for (int i = 0; i < numBins; i++) {
out.println((min + (i + 1) * binSize - binHalfSize) + " " + (histogram[i] * norm));
}
out.println("# " + (max + binHalfSize) + " " + (aboveMax * norm));
out.close();
}
/**
* Program entry point.
*
* @param args Argument. They must be provided, in the following order:
* <ol>
* <li>Number of "equal-width" bins.</li>
* <li>Number of samples.</li>
* </ol>
* @throws IOException if failure occurred while writing to files.
*/
public static void main(String[] args)
throws IOException {
final int numBins = Integer.valueOf(args[0]);
final long numSamples = Long.valueOf(args[1]);
final ProbabilityDensityApproximation app = new ProbabilityDensityApproximation(numBins, numSamples);
final UniformRandomProvider rng = RandomSource.create(RandomSource.XOR_SHIFT_1024_S);
final double gaussMean = 1;
final double gaussSigma = 2;
final double gaussMin = -9;
final double gaussMax = 11;
app.createDensity(new GaussianSampler(new ZigguratNormalizedGaussianSampler(rng),
gaussMean, gaussSigma),
gaussMin, gaussMax, "gauss.ziggurat.txt");
app.createDensity(new GaussianSampler(new MarsagliaNormalizedGaussianSampler(rng),
gaussMean, gaussSigma),
gaussMin, gaussMax, "gauss.marsaglia.txt");
app.createDensity(new GaussianSampler(new BoxMullerNormalizedGaussianSampler(rng),
gaussMean, gaussSigma),
gaussMin, gaussMax, "gauss.boxmuller.txt");
final double alphaBeta = 4.3;
final double betaBeta = 2.1;
final double betaMin = 0;
final double betaMax = 1;
app.createDensity(new ChengBetaSampler(rng, alphaBeta, betaBeta),
betaMin, betaMax, "beta.case1.txt");
final double alphaBetaAlt = 0.5678;
final double betaBetaAlt = 0.1234;
app.createDensity(new ChengBetaSampler(rng, alphaBetaAlt, betaBetaAlt),
betaMin, betaMax, "beta.case2.txt");
final double meanExp = 3.45;
final double expMin = 0;
final double expMax = 60;
app.createDensity(new AhrensDieterExponentialSampler(rng, meanExp),
expMin, expMax, "exp.txt");
final double thetaGammaSmallerThanOne = 0.1234;
final double alphaGamma = 3.456;
final double gammaMin = 0;
final double gammaMax1 = 40;
app.createDensity(new AhrensDieterMarsagliaTsangGammaSampler(rng, alphaGamma, thetaGammaSmallerThanOne),
gammaMin, gammaMax1, "gamma.case1.txt");
final double thetaGammaLargerThanOne = 2.345;
final double gammaMax2 = 70;
app.createDensity(new AhrensDieterMarsagliaTsangGammaSampler(rng, alphaGamma, thetaGammaLargerThanOne),
gammaMin, gammaMax2, "gamma.case2.txt");
final double scalePareto = 23.45;
final double shapePareto = 0.789;
final double paretoMin = 23;
final double paretoMax = 400;
app.createDensity(new InverseTransformParetoSampler(rng, scalePareto, shapePareto),
paretoMin, paretoMax, "pareto.txt");
final double loUniform = -9.876;
final double hiUniform = 5.432;
app.createDensity(new ContinuousUniformSampler(rng, loUniform, hiUniform),
loUniform, hiUniform, "uniform.txt");
final double scaleLogNormal = 2.345;
final double shapeLogNormal = 0.1234;
final double logNormalMin = 5;
final double logNormalMax = 25;
app.createDensity(new LogNormalSampler(new ZigguratNormalizedGaussianSampler(rng),
scaleLogNormal, shapeLogNormal),
logNormalMin, logNormalMax, "lognormal.ziggurat.txt");
app.createDensity(new LogNormalSampler(new MarsagliaNormalizedGaussianSampler(rng),
scaleLogNormal, shapeLogNormal),
logNormalMin, logNormalMax, "lognormal.marsaglia.txt");
app.createDensity(new LogNormalSampler(new BoxMullerNormalizedGaussianSampler(rng),
scaleLogNormal, shapeLogNormal),
logNormalMin, logNormalMax, "lognormal.boxmuller.txt");
}
}