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 }