1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.rng.sampling.distribution; 18 19 import org.apache.commons.rng.UniformRandomProvider; 20 21 /** 22 * Sampling from a Gaussian distribution with given mean and 23 * standard deviation. 24 * 25 * <h2>Note</h2> 26 * 27 * <p>The mean and standard deviation are validated to ensure they are finite. This prevents 28 * generation of NaN samples by avoiding invalid arithmetic (inf * 0 or inf - inf). 29 * However use of an extremely large standard deviation and/or mean may result in samples that are 30 * infinite; that is the parameters are not validated to prevent truncation of the output 31 * distribution. 32 * 33 * @since 1.1 34 */ 35 public class GaussianSampler implements SharedStateContinuousSampler { 36 /** Mean. */ 37 private final double mean; 38 /** standardDeviation. */ 39 private final double standardDeviation; 40 /** Normalized Gaussian sampler. */ 41 private final NormalizedGaussianSampler normalized; 42 43 /** 44 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 45 * @param mean Mean of the Gaussian distribution. 46 * @param standardDeviation Standard deviation of the Gaussian distribution. 47 * @throws IllegalArgumentException if {@code standardDeviation <= 0} or is infinite; 48 * or {@code mean} is infinite 49 */ 50 public GaussianSampler(NormalizedGaussianSampler normalized, 51 double mean, 52 double standardDeviation) { 53 if (!(standardDeviation > 0 && standardDeviation < Double.POSITIVE_INFINITY)) { 54 throw new IllegalArgumentException( 55 "standard deviation is not strictly positive and finite: " + standardDeviation); 56 } 57 if (!Double.isFinite(mean)) { 58 throw new IllegalArgumentException("mean is not finite: " + mean); 59 } 60 this.normalized = normalized; 61 this.mean = mean; 62 this.standardDeviation = standardDeviation; 63 } 64 65 /** 66 * @param rng Generator of uniformly distributed random numbers. 67 * @param source Source to copy. 68 */ 69 private GaussianSampler(UniformRandomProvider rng, 70 GaussianSampler source) { 71 this.mean = source.mean; 72 this.standardDeviation = source.standardDeviation; 73 this.normalized = InternalUtils.newNormalizedGaussianSampler(source.normalized, rng); 74 } 75 76 /** {@inheritDoc} */ 77 @Override 78 public double sample() { 79 return standardDeviation * normalized.sample() + mean; 80 } 81 82 /** {@inheritDoc} */ 83 @Override 84 public String toString() { 85 return "Gaussian deviate [" + normalized.toString() + "]"; 86 } 87 88 /** 89 * {@inheritDoc} 90 * 91 * <p>Note: This function is available if the underlying {@link NormalizedGaussianSampler} 92 * is a {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler}. 93 * Otherwise a run-time exception is thrown.</p> 94 * 95 * @throws UnsupportedOperationException if the underlying sampler is not a 96 * {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler} or 97 * does not return a {@link NormalizedGaussianSampler} when sharing state. 98 * 99 * @since 1.3 100 */ 101 @Override 102 public SharedStateContinuousSampler withUniformRandomProvider(UniformRandomProvider rng) { 103 return new GaussianSampler(rng, this); 104 } 105 106 /** 107 * Create a new normalised Gaussian sampler. 108 * 109 * <p>Note: The shared-state functionality is available if the {@link NormalizedGaussianSampler} 110 * is a {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler}. 111 * Otherwise a run-time exception will be thrown when the sampler is used to share state.</p> 112 * 113 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 114 * @param mean Mean of the Gaussian distribution. 115 * @param standardDeviation Standard deviation of the Gaussian distribution. 116 * @return the sampler 117 * @throws IllegalArgumentException if {@code standardDeviation <= 0} or is infinite; 118 * or {@code mean} is infinite 119 * @see #withUniformRandomProvider(UniformRandomProvider) 120 * @since 1.3 121 */ 122 public static SharedStateContinuousSampler of(NormalizedGaussianSampler normalized, 123 double mean, 124 double standardDeviation) { 125 return new GaussianSampler(normalized, mean, standardDeviation); 126 } 127 }