RNG-30: Box-Muller (Gaussian distribution).
Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/362789f3 Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/362789f3 Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/362789f3 Branch: refs/heads/RNG-30__sampling Commit: 362789f332a0bffe883a0f7d6e9659136782de80 Parents: f8fd890 Author: Gilles <[email protected]> Authored: Thu Nov 10 16:46:47 2016 +0100 Committer: Gilles <[email protected]> Committed: Thu Nov 10 16:54:08 2016 +0100 ---------------------------------------------------------------------- .../distribution/BoxMullerGaussianSampler.java | 81 ++++++++++++++++++++ 1 file changed, 81 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-rng/blob/362789f3/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/BoxMullerGaussianSampler.java ---------------------------------------------------------------------- diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/BoxMullerGaussianSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/BoxMullerGaussianSampler.java new file mode 100644 index 0000000..aafe93e --- /dev/null +++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/BoxMullerGaussianSampler.java @@ -0,0 +1,81 @@ +/* + * 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.sampling.distribution; + +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.sampling.AbstractContinuousSampler; + +/** + * <a href="https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform"> + * Box-Muller algorithm</a> for sampling from a Gaussian distribution. + */ +public class BoxMullerGaussianSampler extends AbstractContinuousSampler { + /** Next gaussian. */ + private double nextGaussian = Double.NaN; + /** Mean. */ + private final double mean; + /** standardDeviation. */ + private final double standardDeviation; + + /** + * @param mean Mean of the Gaussian distribution. + * @param standardDeviation Standard deviation of the Gaussian distribution. + * @param rng Generator of uniformly distributed random numbers. + */ + public BoxMullerGaussianSampler(double mean, + double standardDeviation, + UniformRandomProvider rng) { + super(rng); + this.mean = mean; + this.standardDeviation = standardDeviation; + } + + /** {@inheritDoc} */ + @Override + public double sample() { + final double random; + if (Double.isNaN(nextGaussian)) { + // Generate a pair of Gaussian numbers. + + final double x = nextUniform(); + final double y = nextUniform(); + final double alpha = 2 * Math.PI * x; + final double r = Math.sqrt(-2 * Math.log(y)); + + // Return the first element of the generated pair. + random = r * Math.cos(alpha); + + // Keep second element of the pair for next invocation. + nextGaussian = r * Math.sin(alpha); + } else { + // Use the second element of the pair (generated at the + // previous invocation). + random = nextGaussian; + + // Both elements of the pair have been used. + nextGaussian = Double.NaN; + } + + return standardDeviation * random + mean; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return "[Box-Muller method for Gaussian distribution " + super.toString() + "]"; + } +}
