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 }