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 uniform distribution.
22   */
23  public class UniformRandomizer extends Randomizer {
24  
25      /**
26       * Constructor.
27       * Uses default {@link Random} implementation.
28       */
29      public UniformRandomizer() {
30          super();
31      }
32  
33      /**
34       * Constructor.
35       *
36       * @param internalRandom Internal Random instance in charge of generating
37       *                       pseudo-random values.
38       * @throws NullPointerException thrown if provided internal random is null.
39       */
40      public UniformRandomizer(final Random internalRandom) {
41          super(internalRandom);
42      }
43  
44      /**
45       * Returns next boolean value following a uniform distribution (e.g. the
46       * probability of returning either true or false is 50%).
47       *
48       * @return Next boolean value following a uniform distribution.
49       */
50      @Override
51      public boolean nextBoolean() {
52          return getInternalRandom().nextBoolean();
53      }
54  
55      /**
56       * Returns next random integer value within the range of integer values and
57       * following a uniform distribution (e.g. each possible value has
58       * approximately the same probability to be picked).
59       *
60       * @return Next integer value following a uniform distribution.
61       */
62      @Override
63      public int nextInt() {
64          return getInternalRandom().nextInt();
65      }
66  
67      /**
68       * Returns next random integer value within 0 and provided value following
69       * a uniform distribution (e.g. each possible value has approximately the
70       * same probability to be picked).
71       *
72       * @param maxValue Maximum value to be returned (exclusive).
73       * @return Next integer value following a uniform distribution.
74       * @throws IllegalArgumentException if provided values is negative.
75       */
76      public int nextInt(final int maxValue) {
77          return getInternalRandom().nextInt(maxValue);
78      }
79  
80      /**
81       * Fills provided array with uniform integer values within 0 and provided
82       * maxValue following a uniform distribution.
83       *
84       * @param array    Array to be filled.
85       * @param maxValue Maximum value to be returned (exclusive).
86       * @throws IllegalArgumentException if provided value is negative.
87       */
88      public void fill(final int[] array, final int maxValue) {
89          for (int i = 0; i < array.length; i++) {
90              array[i] = nextInt(maxValue);
91          }
92      }
93  
94      /**
95       * Returns array of random uniform integer values within 0 and provided
96       * maxValue.
97       *
98       * @param length   Length of array to be returned.
99       * @param maxValue Maximum value to be returned (exclusive).
100      * @return Array of random uniform integers.
101      * @throws IllegalArgumentException if provided values are zero or negative.
102      */
103     public int[] nextInts(final int length, final int maxValue) {
104         if (length <= 0) {
105             throw new IllegalArgumentException();
106         }
107         final var array = new int[length];
108         fill(array, maxValue);
109         return array;
110     }
111 
112     /**
113      * Returns next random integer value between the range of provided values
114      * following a uniform distribution (e.g. each possible value has
115      * approximately the same probability to be picked).
116      *
117      * @param minValue Minimum value to be returned (inclusive).
118      * @param maxValue Maximum value to be returned (exclusive).
119      * @return Next integer value following a uniform distribution.
120      * @throws IllegalArgumentException Exception thrown if maxValue is smaller
121      *                                  or equal than minValue.
122      */
123     public int nextInt(final int minValue, final int maxValue) {
124         if (maxValue <= minValue) {
125             throw new IllegalArgumentException();
126         }
127 
128         final var diff = maxValue - minValue;
129         return getInternalRandom().nextInt(diff) + minValue;
130     }
131 
132     /**
133      * Fills provided array with uniform integer values within provided
134      * minValue (inclusive) and maxValue (exclusive) following a uniform
135      * distribution.
136      *
137      * @param array    Array to be filled.
138      * @param minValue Minimum value to be returned (inclusive).
139      * @param maxValue Maximum value to be returned (exclusive).
140      * @throws IllegalArgumentException if maxValue is smaller or equal than
141      *                                  minValue.
142      */
143     public void fill(final int[] array, final int minValue, final int maxValue) {
144         if (maxValue <= minValue) {
145             throw new IllegalArgumentException();
146         }
147         final var diff = maxValue - minValue;
148 
149         for (int i = 0; i < array.length; i++) {
150             array[i] = getInternalRandom().nextInt(diff) + minValue;
151         }
152     }
153 
154     /**
155      * Returns array of random uniform integer values within provided minValue
156      * and maxValue.
157      *
158      * @param length   Length of array to be returned.
159      * @param minValue Minimum value to be returned (inclusive).
160      * @param maxValue Maximum value to be returned (exclusive).
161      * @return Array of random uniform integers.
162      * @throws IllegalArgumentException if provided values are zero or negative.
163      */
164     public int[] nextInts(final int length, final int minValue, final int maxValue) {
165         final var array = new int[length];
166         fill(array, minValue, maxValue);
167         return array;
168     }
169 
170     /**
171      * Returns next random long value within the range of long values and
172      * following a uniform distribution (e.g. each possible value has
173      * approximately the same probability to be picked).
174      *
175      * @return Next long value following a uniform distribution.
176      */
177     @Override
178     public long nextLong() {
179         return getInternalRandom().nextLong();
180     }
181 
182     /**
183      * Returns next random long value within 0 and provided value following
184      * a uniform distribution (e.g. each possible value has approximately the
185      * same probability to be picked).
186      *
187      * @param maxValue Maximum value to be returned (exclusive).
188      * @return Next long value following a uniform distribution.
189      * @throws IllegalArgumentException if provided value is negative.
190      */
191     public long nextLong(final long maxValue) {
192         return nextLong(0, maxValue);
193     }
194 
195     /**
196      * Fills provided array with uniform long values within 0 and provided
197      * maxValue following a uniform distribution.
198      *
199      * @param array    Array to be filled.
200      * @param maxValue Maximum value to be returned (exclusive).
201      * @throws IllegalArgumentException if provided value is negative.
202      */
203     public void fill(final long[] array, final long maxValue) {
204         for (int i = 0; i < array.length; i++) {
205             array[i] = nextLong(maxValue);
206         }
207     }
208 
209     /**
210      * Returns array of random uniform long values within 0 and provided
211      * maxValue.
212      *
213      * @param length   Length of array to be returned.
214      * @param maxValue Maximum value to be returned (exclusive).
215      * @return Array of random uniform long integers.
216      * @throws IllegalArgumentException if provided values are zero or negative.
217      */
218     public long[] nextLongs(final int length, final long maxValue) {
219         final var array = new long[length];
220         fill(array, maxValue);
221         return array;
222     }
223 
224     /**
225      * Returns next random long value between the range of provided values
226      * following a uniform distribution (e.g. each possible value has
227      * approximately the same probability to be picked).
228      *
229      * @param minValue Minimum value to be returned (inclusive).
230      * @param maxValue Maximum value to be returned (exclusive).
231      * @return Next long value following a uniform distribution.
232      * @throws IllegalArgumentException Exception thrown if maxValue is smaller
233      *                                  or equal than minValue.
234      */
235     public long nextLong(final long minValue, final long maxValue) {
236         if (maxValue <= minValue) {
237             throw new IllegalArgumentException();
238         }
239 
240         final var diff = maxValue - minValue;
241         final var next = Math.max(getInternalRandom().nextLong(), Long.MIN_VALUE + 1);
242         return (Math.abs(next) % diff) + minValue;
243     }
244 
245     /**
246      * Fills provided array with uniform long values within provided
247      * minValue (inclusive) and maxValue (exclusive) following a uniform
248      * distribution.
249      *
250      * @param array    Array to be filled.
251      * @param minValue Minimum value to be returned (inclusive).
252      * @param maxValue Maximum value to be returned (exclusive).
253      * @throws IllegalArgumentException if maxValue is smaller or equal than
254      *                                  minValue.
255      */
256     public void fill(final long[] array, final long minValue, final long maxValue) {
257         for (int i = 0; i < array.length; i++) {
258             array[i] = nextLong(minValue, maxValue);
259         }
260     }
261 
262     /**
263      * Returns array of random uniform long values within provided minValue
264      * and maxValue.
265      *
266      * @param length   Length of array to be returned.
267      * @param minValue Minimum value to be returned (inclusive).
268      * @param maxValue Maximum value to be returned (exclusive).
269      * @return Array of random uniform integers.
270      * @throws IllegalArgumentException if provided values are zero or negative.
271      */
272     public long[] nextLongs(final int length, final long minValue, final long maxValue) {
273         final var array = new long[length];
274         fill(array, minValue, maxValue);
275         return array;
276     }
277 
278     /**
279      * Returns next random floating-point value within the range 0.0 and 1.0
280      * following a uniform distribution (e.g. each possible value has
281      * approximately the same probability to be picked).
282      *
283      * @return Next float value following a uniform distribution between 0.0 and
284      * 1.0.
285      */
286     @Override
287     public float nextFloat() {
288         return getInternalRandom().nextFloat();
289     }
290 
291     /**
292      * Returns next random floating-point value between 0.0 and provided value
293      * following a uniform distribution (e.g. each possible value has
294      * approximately the same probability to be picked).
295      *
296      * @param maxValue Maximum value to be returned (exclusive).
297      * @return Next floating-point value following a uniform distribution.
298      * @throws IllegalArgumentException if provided value is negative.
299      */
300     public float nextFloat(final float maxValue) {
301         return nextFloat(0.0f, maxValue);
302     }
303 
304     /**
305      * Fills provided array with floating point values within 0.0 and provided
306      * maxValue following a uniform distribution.
307      *
308      * @param array    Array to be filled.
309      * @param maxValue Maximum value to be returned (exclusive).
310      * @throws IllegalArgumentException if provided value is negative.
311      */
312     public void fill(final float[] array, final float maxValue) {
313         for (int i = 0; i < array.length; i++) {
314             array[i] = nextFloat(maxValue);
315         }
316     }
317 
318     /**
319      * Returns array of random uniform floating point values within 0.0 and
320      * provided maxValue.
321      *
322      * @param length   Length of array to be returned.
323      * @param maxValue Maximum value to be returned (exclusive).
324      * @return Array of random uniform floating point.
325      * @throws IllegalArgumentException if provided values are zero or negative.
326      */
327     public float[] nextFloats(final int length, final float maxValue) {
328         final var array = new float[length];
329         fill(array, maxValue);
330         return array;
331     }
332 
333     /**
334      * Returns next random floating-point value between the range of provided
335      * values following a uniform distribution (e.g. each possible value has
336      * approximately the same probability to be picked).
337      *
338      * @param minValue Minimum value to be returned (inclusive).
339      * @param maxValue Maximum value to be returned (exclusive).
340      * @return Next floating-point value following a uniform distribution.
341      * @throws IllegalArgumentException Exception thrown if maxValue is smaller
342      *                                  or equal than minValue.
343      */
344     public float nextFloat(final float minValue, final float maxValue) {
345         if (maxValue <= minValue) {
346             throw new IllegalArgumentException();
347         }
348 
349         final var diff = maxValue - minValue;
350         return getInternalRandom().nextFloat() * diff + minValue;
351     }
352 
353     /**
354      * Fills provided array with uniform floating point values within provided
355      * minValue (inclusive) and maxValue (exclusive) following a uniform
356      * distribution.
357      *
358      * @param array    Array to be filled.
359      * @param minValue Minimum value to be returned (inclusive).
360      * @param maxValue Maximum value to be returned (exclusive).
361      * @throws IllegalArgumentException if maxValue is smaller or equal than
362      *                                  minValue.
363      */
364     public void fill(final float[] array, final float minValue, final float maxValue) {
365         for (int i = 0; i < array.length; i++) {
366             array[i] = nextFloat(minValue, maxValue);
367         }
368     }
369 
370     /**
371      * Returns array of random uniform floating point values within provided
372      * minValue and maxValue.
373      *
374      * @param length   Length of array to be returned.
375      * @param minValue Minimum value to be returned (inclusive).
376      * @param maxValue Maximum value to be returned (exclusive).
377      * @return Array of random floating point values.
378      * @throws IllegalArgumentException if provided values are zero or negative.
379      */
380     public float[] nextFloats(final int length, final float minValue, final float maxValue) {
381         final var array = new float[length];
382         fill(array, minValue, maxValue);
383         return array;
384     }
385 
386     /**
387      * Returns next random double precision floating-point value within the
388      * range 0.0 and 1.0 following a uniform distribution (e.g. each possible
389      * value has approximately the same probability to be picked).
390      *
391      * @return Next float value following a uniform distribution between 0.0 and
392      * 1.0.
393      */
394     @Override
395     public double nextDouble() {
396         return getInternalRandom().nextDouble();
397     }
398 
399     /**
400      * Returns next random floating-point value between 0.0 and provided value
401      * following a uniform distribution (e.g. each possible value has
402      * approximately the same probability to be picked).
403      *
404      * @param maxValue Maximum value to be returned (exclusive).
405      * @return Next floating-point value following a uniform distribution.
406      * @throws IllegalArgumentException if provided value is negative.
407      */
408     public double nextDouble(final double maxValue) {
409         return nextDouble(0.0, maxValue);
410     }
411 
412     /**
413      * Fills provided array with double precision floating point values within
414      * 0.0 and provided maxValue following a uniform distribution.
415      *
416      * @param array    Array to be filled.
417      * @param maxValue Maximum value to be returned (exclusive).
418      * @throws IllegalArgumentException if provided value is negative.
419      */
420     public void fill(final double[] array, final double maxValue) {
421         for (int i = 0; i < array.length; i++) {
422             array[i] = nextDouble(maxValue);
423         }
424     }
425 
426     /**
427      * Returns array of random uniform double precision floating point values
428      * within 0.0 and provided maxValue.
429      *
430      * @param length   Length of array to be returned.
431      * @param maxValue Maximum value to be returned (exclusive).
432      * @return Array of random uniform double precision floating point values.
433      * @throws IllegalArgumentException if provided values are zero or negative.
434      */
435     public double[] nextDoubles(final int length, final double maxValue) {
436         final var array = new double[length];
437         fill(array, maxValue);
438         return array;
439     }
440 
441     /**
442      * Returns next random double precision floating-point value between the
443      * range of provided values following a uniform distribution (e.g. each
444      * possible value has approximately the same probability to be picked).
445      *
446      * @param minValue Minimum value to be returned (inclusive).
447      * @param maxValue Maximum value to be returned (exclusive).
448      * @return Next floating-point value following a uniform distribution.
449      * @throws IllegalArgumentException Exception thrown if maxValue is smaller
450      *                                  or equal than minValue.
451      */
452     public double nextDouble(final double minValue, final double maxValue) {
453         if (maxValue <= minValue) {
454             throw new IllegalArgumentException();
455         }
456 
457         final var diff = maxValue - minValue;
458         return getInternalRandom().nextDouble() * diff + minValue;
459     }
460 
461     /**
462      * Fills provided array with uniform double precision floating point values
463      * within provided minValue (inclusive) and maxValue (exclusive) following
464      * a uniform distribution.
465      *
466      * @param array    Array to be filled.
467      * @param minValue Minimum value to be returned (inclusive).
468      * @param maxValue Maximum value to be returned (exclusive).
469      * @throws IllegalArgumentException if maxValue is smaller or equal than
470      *                                  minValue.
471      */
472     public void fill(final double[] array, final double minValue, final double maxValue) {
473         for (int i = 0; i < array.length; i++) {
474             array[i] = nextDouble(minValue, maxValue);
475         }
476     }
477 
478     /**
479      * Returns array of random uniform floating point values within provided
480      * minValue and maxValue.
481      *
482      * @param length   Length of array to be returned.
483      * @param minValue Minimum value to be returned (inclusive).
484      * @param maxValue Maximum value to be returned (exclusive).
485      * @return Array of random floating point values.
486      * @throws IllegalArgumentException if provided values are zero or negative.
487      */
488     public double[] nextDoubles(final int length, final double minValue, final double maxValue) {
489         final var array = new double[length];
490         fill(array, minValue, maxValue);
491         return array;
492     }
493 
494     /**
495      * Returns the randomizer type of this instance.
496      *
497      * @return Randomizer type.
498      */
499     @Override
500     public RandomizerType getType() {
501         return RandomizerType.UNIFORM_RANDOMIZER;
502     }
503 }