1 /*
2 * Copyright (C) 2012 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.statistics;
17
18 import java.util.Random;
19
20 /**
21 * Generates pseudo-random values following a Gaussian distribution having
22 * the specified mMean and standard deviation. By default, mMean is equal to
23 * DEFAULT_MEAN and the standard deviation is equal to
24 * DEFAULT_STANDARD_DEVIATION.
25 */
26 public class GaussianRandomizer extends Randomizer {
27
28 /**
29 * Specifies mMean value to be used for random value generation if no mMean
30 * is provided.
31 */
32 public static final double DEFAULT_MEAN = 0.0;
33
34 /**
35 * Specifies standard deviation to be used for random value generation if
36 * none is provided.
37 */
38 public static final double DEFAULT_STANDARD_DEVIATION = 1.0;
39
40 /**
41 * Contains mMean value to be used for random value generation.
42 */
43 private double mean;
44
45 /**
46 * Standard deviation value to be used for random value generation.
47 */
48 private double standardDeviation;
49
50 /**
51 * Constructor.
52 * Uses default {@link Random} implementation.
53 */
54 public GaussianRandomizer() {
55 this(new Random());
56 }
57
58 /**
59 * Constructor.
60 * Uses default {@link Random} implementation.
61 *
62 * @param mean Mean value of generated Gaussian values.
63 * @param standardDeviation Standard deviation of generated Gaussian values.
64 * @throws IllegalArgumentException thrown if provided standard deviation
65 * is negative or zero.
66 * @throws NullPointerException if provided internal Random instance is null.
67 */
68 public GaussianRandomizer(final double mean, final double standardDeviation) {
69 this(new Random(), mean, standardDeviation);
70 }
71
72 /**
73 * Constructor.
74 * Because neither mMean nor standard deviation are provided, values
75 * DEFAULT_MEAN and DEFAULT_STANDARD_DEVIATION will be used instead.
76 *
77 * @param internalRandom Internal Random instance in charge of generating
78 * pseudo-random values.
79 * @throws NullPointerException thrown if provided internal random is null.
80 */
81 public GaussianRandomizer(final Random internalRandom) {
82 super(internalRandom);
83 mean = DEFAULT_MEAN;
84 standardDeviation = DEFAULT_STANDARD_DEVIATION;
85 }
86
87 /**
88 * Constructor.
89 *
90 * @param internalRandom Internal Random instance if charge of generating
91 * pseudo-random values.
92 * @param mean Mean value of generated Gaussian values.
93 * @param standardDeviation Standard deviation of generated Gaussian values.
94 * @throws IllegalArgumentException thrown if provided standard deviation
95 * is negative or zero.
96 * @throws NullPointerException if provided internal Random instance is null.
97 */
98 public GaussianRandomizer(final Random internalRandom, final double mean, final double standardDeviation) {
99 super(internalRandom);
100
101 if (standardDeviation <= 0.0) {
102 throw new IllegalArgumentException();
103 }
104 this.mean = mean;
105 this.standardDeviation = standardDeviation;
106 }
107
108 /**
109 * Returns mMean value to be used for Gaussian random value generation.
110 *
111 * @return Mean value.
112 */
113 public double getMean() {
114 return mean;
115 }
116
117 /**
118 * Sets mMean value to be used for Gaussian random value generation.
119 *
120 * @param mean Mean value.
121 */
122 public void setMean(final double mean) {
123 this.mean = mean;
124 }
125
126 /**
127 * Returns standard deviation to be used for Gaussian random value
128 * generation.
129 *
130 * @return Standard deviation.
131 */
132 public double getStandardDeviation() {
133 return standardDeviation;
134 }
135
136 /**
137 * Sets standard deviation to be used for Gaussian random value generation.
138 *
139 * @param standardDeviation Standard deviation.
140 * @throws IllegalArgumentException exception thrown if provided standard
141 * deviation is negative or zero.
142 */
143 public void setStandardDeviation(final double standardDeviation) {
144 if (standardDeviation <= 0.0) {
145 throw new IllegalArgumentException();
146 }
147 this.standardDeviation = standardDeviation;
148 }
149
150 /**
151 * Returns next random boolean value. The probability of returning true
152 * is equal to obtaining a Gaussian value below the mMean, which is 50%.
153 *
154 * @return Next boolean value.
155 */
156 @Override
157 public boolean nextBoolean() {
158 return nextBoolean(mean);
159 }
160
161 /**
162 * Returns next random boolean value. The probability of returning true
163 * is equal to obtaining a Gaussian value below the provided threshold,
164 * which is equal to erfc function.
165 *
166 * @param threshold Threshold to determine whether returned values will be
167 * true or false.
168 * @return Next random boolean value.
169 */
170 public boolean nextBoolean(final double threshold) {
171 return (standardDeviation * getInternalRandom().nextGaussian() + mean) < threshold;
172 }
173
174 /**
175 * Fills provided array with random booleans where the probability
176 * of returning true is equal to obtaining a Gaussian value below the
177 * provided threshold, which is equal to erfc function.
178 *
179 * @param array array to be filled.
180 * @param threshold Threshold to determine whether generated values will be
181 * true or false.
182 */
183 public void fill(final boolean[] array, final double threshold) {
184 for (int i = 0; i < array.length; i++) {
185 array[i] = nextBoolean(threshold);
186 }
187 }
188
189 /**
190 * Returns array of booleans having provided length and containing random
191 * boolean values. The probability of returning true is equal to
192 * obtaining a Gaussian value below the provided threshold, which is equal
193 * to erfc function.
194 *
195 * @param length Length of array to be created.
196 * @param threshold Threshold to determine whether returned values will be
197 * true or false.
198 * @return Array of random booleans.
199 * @throws IllegalArgumentException if provided length is zero or negative.
200 */
201 public boolean[] nextBooleans(final int length, final double threshold) {
202 if (length <= 0) {
203 throw new IllegalArgumentException();
204 }
205
206 final var array = new boolean[length];
207 fill(array, threshold);
208 return array;
209 }
210
211 /**
212 * Returns next random Gaussian integer value having provided mMean and
213 * standard deviation.
214 *
215 * @return Next random Gaussian integer value.
216 */
217 @Override
218 public int nextInt() {
219 return (int) (standardDeviation * getInternalRandom().nextGaussian() + mean);
220 }
221
222 /**
223 * Returns next random Gaussian long value having provided mMean and
224 * standard deviation.
225 *
226 * @return Next random Gaussian long value.
227 */
228 @Override
229 public long nextLong() {
230 return (long) (standardDeviation * getInternalRandom().nextGaussian() + mean);
231 }
232
233 /**
234 * Returns next random Gaussian floating-point value having provided mMean
235 * and standard deviation.
236 *
237 * @return Next random Gaussian floating-point value.
238 */
239 @Override
240 public float nextFloat() {
241 return (float) (standardDeviation * getInternalRandom().nextGaussian() + mean);
242 }
243
244 /**
245 * Returns next random Gaussian double precision floating-point value having
246 * provided mMean and standard deviation.
247 *
248 * @return Next random Gaussian double precision floating-point value.
249 */
250 @Override
251 public double nextDouble() {
252 return standardDeviation * getInternalRandom().nextGaussian() + mean;
253 }
254
255 /**
256 * Returns the randomizer type of this instance.
257 *
258 * @return Randomizer type.
259 */
260 @Override
261 public RandomizerType getType() {
262 return RandomizerType.GAUSSIAN_RANDOMIZER;
263 }
264 }