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 * Create an instance. 45 * 46 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 47 * @param mean Mean of the Gaussian distribution. 48 * @param standardDeviation Standard deviation of the Gaussian distribution. 49 * @throws IllegalArgumentException if {@code standardDeviation <= 0} or is infinite; 50 * or {@code mean} is infinite 51 */ 52 public GaussianSampler(NormalizedGaussianSampler normalized, 53 double mean, 54 double standardDeviation) { 55 // Validation before java.lang.Object constructor exits prevents partially initialized object 56 this(InternalUtils.requireFinite(mean, "mean"), 57 InternalUtils.requireStrictlyPositiveFinite(standardDeviation, "standardDeviation"), 58 normalized); 59 } 60 61 /** 62 * @param mean Mean of the Gaussian distribution. 63 * @param standardDeviation Standard deviation of the Gaussian distribution. 64 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 65 */ 66 private GaussianSampler(double mean, 67 double standardDeviation, 68 NormalizedGaussianSampler normalized) { 69 this.normalized = normalized; 70 this.mean = mean; 71 this.standardDeviation = standardDeviation; 72 } 73 74 /** {@inheritDoc} */ 75 @Override 76 public double sample() { 77 return standardDeviation * normalized.sample() + mean; 78 } 79 80 /** {@inheritDoc} */ 81 @Override 82 public String toString() { 83 return "Gaussian deviate [" + normalized.toString() + "]"; 84 } 85 86 /** 87 * {@inheritDoc} 88 * 89 * <p>Note: This function is available if the underlying {@link NormalizedGaussianSampler} 90 * is a {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler}. 91 * Otherwise a run-time exception is thrown.</p> 92 * 93 * @throws UnsupportedOperationException if the underlying sampler is not a 94 * {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler} or 95 * does not return a {@link NormalizedGaussianSampler} when sharing state. 96 * 97 * @since 1.3 98 */ 99 @Override 100 public SharedStateContinuousSampler withUniformRandomProvider(UniformRandomProvider rng) { 101 return new GaussianSampler(mean, standardDeviation, 102 InternalUtils.newNormalizedGaussianSampler(normalized, rng)); 103 } 104 105 /** 106 * Create a new normalised Gaussian sampler. 107 * 108 * <p>Note: The shared-state functionality is available if the {@link NormalizedGaussianSampler} 109 * is a {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler}. 110 * Otherwise a run-time exception will be thrown when the sampler is used to share state.</p> 111 * 112 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 113 * @param mean Mean of the Gaussian distribution. 114 * @param standardDeviation Standard deviation of the Gaussian distribution. 115 * @return the sampler 116 * @throws IllegalArgumentException if {@code standardDeviation <= 0} or is infinite; 117 * or {@code mean} is infinite 118 * @see #withUniformRandomProvider(UniformRandomProvider) 119 * @since 1.3 120 */ 121 public static SharedStateContinuousSampler of(NormalizedGaussianSampler normalized, 122 double mean, 123 double standardDeviation) { 124 return new GaussianSampler(normalized, mean, standardDeviation); 125 } 126 }