View Javadoc
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 }