001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.rng.sampling.distribution; 018 019import org.apache.commons.rng.UniformRandomProvider; 020 021/** 022 * Sampling from a Gaussian distribution with given mean and 023 * standard deviation. 024 * 025 * <h2>Note</h2> 026 * 027 * <p>The mean and standard deviation are validated to ensure they are finite. This prevents 028 * generation of NaN samples by avoiding invalid arithmetic (inf * 0 or inf - inf). 029 * However use of an extremely large standard deviation and/or mean may result in samples that are 030 * infinite; that is the parameters are not validated to prevent truncation of the output 031 * distribution. 032 * 033 * @since 1.1 034 */ 035public class GaussianSampler implements SharedStateContinuousSampler { 036 /** Mean. */ 037 private final double mean; 038 /** standardDeviation. */ 039 private final double standardDeviation; 040 /** Normalized Gaussian sampler. */ 041 private final NormalizedGaussianSampler normalized; 042 043 /** 044 * Create an instance. 045 * 046 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 047 * @param mean Mean of the Gaussian distribution. 048 * @param standardDeviation Standard deviation of the Gaussian distribution. 049 * @throws IllegalArgumentException if {@code standardDeviation <= 0} or is infinite; 050 * or {@code mean} is infinite 051 */ 052 public GaussianSampler(NormalizedGaussianSampler normalized, 053 double mean, 054 double standardDeviation) { 055 // Validation before java.lang.Object constructor exits prevents partially initialized object 056 this(InternalUtils.requireFinite(mean, "mean"), 057 InternalUtils.requireStrictlyPositiveFinite(standardDeviation, "standardDeviation"), 058 normalized); 059 } 060 061 /** 062 * @param mean Mean of the Gaussian distribution. 063 * @param standardDeviation Standard deviation of the Gaussian distribution. 064 * @param normalized Generator of N(0,1) Gaussian distributed random numbers. 065 */ 066 private GaussianSampler(double mean, 067 double standardDeviation, 068 NormalizedGaussianSampler normalized) { 069 this.normalized = normalized; 070 this.mean = mean; 071 this.standardDeviation = standardDeviation; 072 } 073 074 /** {@inheritDoc} */ 075 @Override 076 public double sample() { 077 return standardDeviation * normalized.sample() + mean; 078 } 079 080 /** {@inheritDoc} */ 081 @Override 082 public String toString() { 083 return "Gaussian deviate [" + normalized.toString() + "]"; 084 } 085 086 /** 087 * {@inheritDoc} 088 * 089 * <p>Note: This function is available if the underlying {@link NormalizedGaussianSampler} 090 * is a {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler}. 091 * Otherwise a run-time exception is thrown.</p> 092 * 093 * @throws UnsupportedOperationException if the underlying sampler is not a 094 * {@link org.apache.commons.rng.sampling.SharedStateSampler SharedStateSampler} or 095 * does not return a {@link NormalizedGaussianSampler} when sharing state. 096 * 097 * @since 1.3 098 */ 099 @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}