001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.rng.simple; 018 019import org.apache.commons.rng.UniformRandomProvider; 020import org.apache.commons.rng.RestorableUniformRandomProvider; 021import org.apache.commons.rng.simple.internal.ProviderBuilder; 022import org.apache.commons.rng.simple.internal.SeedFactory; 023 024/** 025 * This class provides the API for creating generators of random numbers. 026 * 027 * <p>Usage examples:</p> 028 * <pre><code> 029 * UniformRandomProvider rng = RandomSource.create(RandomSource.MT); 030 * </code></pre> 031 * or 032 * <pre><code> 033 * final int[] seed = new int[] { 196, 9, 0, 226 }; 034 * UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed); 035 * </code></pre> 036 * or 037 * <pre><code> 038 * final int[] seed = RandomSource.createIntArray(256); 039 * UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed); 040 * </code></pre> 041 * where the first argument to method {@code create} is the identifier 042 * of the generator's concrete implementation, and the second the is the 043 * (optional) seed. 044 * 045 * <p> 046 * In the first form, a random seed will be {@link SeedFactory generated 047 * automatically}; in the second form, a fixed seed is used; a random seed 048 * is explicitly generated in the third form. 049 * </p> 050 * 051 * <p> 052 * Seeding is the procedure by which a value (or set of values) is 053 * used to <i>initialize</i> a generator instance. 054 * The requirement that a given seed will always result in the same 055 * internal state allows to create different instances of a generator 056 * that will produce the same sequence of pseudo-random numbers. 057 * </p> 058 * 059 * <p> 060 * The type of data used as a seed depends on the concrete implementation 061 * as some types may not provide enough information to fully initialize 062 * the generator's internal state. 063 * <br> 064 * The reference algorithm's seeding procedure (if provided) operates 065 * on a value of a (single) <i>native</i> type: 066 * Each concrete implementation's constructor creates an instance using 067 * the native type whose information contents is used to set the 068 * internal state. 069 * <br> 070 * When the seed value passed by the caller is of the native type, it is 071 * expected that the sequences produced will be identical to those 072 * produced by other implementations of the same reference algorithm. 073 * <br> 074 * However, when the seed value passed by the caller is not of the native 075 * type, a transformation is performed by this library and the resulting 076 * native type value will <i>not</i> contain more information than the 077 * original seed value. 078 * If the algorithm's native type is "simpler" than the type passed by 079 * the caller, then some (unused) information will even be lost. 080 * <br> 081 * The transformation from non-native to native seed type is arbitrary, 082 * as long as it does not reduce the amount of information required by 083 * the algorithm to initialize its state. 084 * The consequence of the transformation is that sequences produced 085 * by this library may <i>not</i> be the same as the sequences produced 086 * by other implementations of the same algorithm! 087 * </p> 088 * 089 * <p> 090 * For each algorithm, the Javadoc mentions the "ideal" size of the seed, 091 * meaning the number of {@code int} or {@code long} values that is neither 092 * too large (i.e. some of the seed is useless) or too small (i.e. an 093 * internal procedure will fill the state with redundant information 094 * computed from the given seed). 095 * </p> 096 * 097 * <p> 098 * Note that some algorithms are inherently sensitive to having too low 099 * diversity in their initial state. 100 * For example, it is often a bad idea to use a seed that is mostly 101 * composed of zeroes, or of repeated values. 102 * </p> 103 * 104 * <p> 105 * This class provides methods to generate random seeds (single values 106 * or arrays of values, of {@code int} or {@code long} types) that can 107 * be passed to the {@link RandomSource#create(RandomSource,Object,Object[]) 108 * generators factory method}. 109 * </p> 110 * <p> 111 * Although the seed-generating methods defined in this class will likely 112 * return different values each time they are called, there is no guarantee: 113 * </p> 114 * <ul> 115 * <li> 116 * In any sub-sequence, it is <a href="https://en.wikipedia.org/wiki/Birthday_problem"> 117 * expected</a> that the same numbers can occur, with a probability getting 118 * higher as the range of allowed values is smaller and the sequence becomes 119 * longer. 120 * </li> 121 * <li> 122 * It possible that the resulting "seed" will not be <i>good</i> (i.e. 123 * it will not generate a sufficiently uniformly random sequence for the 124 * intended purpose), even if the generator is good! 125 * The only way to ensure that the selected seed will make the generator 126 * produce a good sequence is to submit that sequence to a series of 127 * stringent tests, as provided by tools such as 128 * <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php">dieharder</a> 129 * or <a href="http://simul.iro.umontreal.ca/testu01/tu01.html">TestU01</a>. 130 * </li> 131 * </ul> 132 * 133 * <p> 134 * The current implementations have no provision for producing non-overlapping 135 * sequences. 136 * For parallel applications, a possible workaround is that each thread uses 137 * a generator of a different type (see {@link #TWO_CMRES_SELECT}). 138 * </p> 139 * 140 * <p> 141 * <b>Note:</b> 142 * Seeding is not equivalent to restoring the internal state of an 143 * <i>already initialized</i> generator. 144 * Indeed, generators can have a state that is more complex than the 145 * seed, and seeding is thus a transformation (from seed to state). 146 * Implementations do not provide the inverse transformation (from 147 * state to seed), hence it is not generally possible to know the seed 148 * that would initialize a new generator instance to the current state 149 * of another instance. 150 * Reseeding is also inefficient if the purpose is to continue the 151 * same sequence where another instance left off, as it would require 152 * to "replay" all the calls performed by that other instance (and it 153 * would require to know the number of calls to the primary source of 154 * randomness, which is also not usually accessible). 155 * </p> 156 * 157 * @since 1.0 158 */ 159public enum RandomSource { 160 /** 161 * Source of randomness is {@link org.apache.commons.rng.core.source32.JDKRandom}. 162 * <ul> 163 * <li>Native seed type: {@code Long}.</li> 164 * <li>Native seed size: 1.</li> 165 * </ul> 166 */ 167 JDK(ProviderBuilder.RandomSourceInternal.JDK), 168 /** 169 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well512a}. 170 * <ul> 171 * <li>Native seed type: {@code int[]}.</li> 172 * <li>Native seed size: 16.</li> 173 * </ul> 174 */ 175 WELL_512_A(ProviderBuilder.RandomSourceInternal.WELL_512_A), 176 /** 177 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well1024a}. 178 * <ul> 179 * <li>Native seed type: {@code int[]}.</li> 180 * <li>Native seed size: 32.</li> 181 * </ul> 182 */ 183 WELL_1024_A(ProviderBuilder.RandomSourceInternal.WELL_1024_A), 184 /** 185 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937a}. 186 * <ul> 187 * <li>Native seed type: {@code int[]}.</li> 188 * <li>Native seed size: 624.</li> 189 * </ul> 190 */ 191 WELL_19937_A(ProviderBuilder.RandomSourceInternal.WELL_19937_A), 192 /** 193 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937c}. 194 * <ul> 195 * <li>Native seed type: {@code int[]}.</li> 196 * <li>Native seed size: 624.</li> 197 * </ul> 198 */ 199 WELL_19937_C(ProviderBuilder.RandomSourceInternal.WELL_19937_C), 200 /** 201 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497a}. 202 * <ul> 203 * <li>Native seed type: {@code int[]}.</li> 204 * <li>Native seed size: 1391.</li> 205 * </ul> 206 */ 207 WELL_44497_A(ProviderBuilder.RandomSourceInternal.WELL_44497_A), 208 /** 209 * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497b}. 210 * <ul> 211 * <li>Native seed type: {@code int[]}.</li> 212 * <li>Native seed size: 1391.</li> 213 * </ul> 214 */ 215 WELL_44497_B(ProviderBuilder.RandomSourceInternal.WELL_44497_B), 216 /** 217 * Source of randomness is {@link org.apache.commons.rng.core.source32.MersenneTwister}. 218 * <ul> 219 * <li>Native seed type: {@code int[]}.</li> 220 * <li>Native seed size: 624.</li> 221 * </ul> 222 */ 223 MT(ProviderBuilder.RandomSourceInternal.MT), 224 /** 225 * Source of randomness is {@link org.apache.commons.rng.core.source32.ISAACRandom}. 226 * <ul> 227 * <li>Native seed type: {@code int[]}.</li> 228 * <li>Native seed size: 256.</li> 229 * </ul> 230 */ 231 ISAAC(ProviderBuilder.RandomSourceInternal.ISAAC), 232 /** 233 * Source of randomness is {@link org.apache.commons.rng.core.source64.SplitMix64}. 234 * <ul> 235 * <li>Native seed type: {@code Long}.</li> 236 * <li>Native seed size: 1.</li> 237 * </ul> 238 */ 239 SPLIT_MIX_64(ProviderBuilder.RandomSourceInternal.SPLIT_MIX_64), 240 /** 241 * Source of randomness is {@link org.apache.commons.rng.core.source64.XorShift1024Star}. 242 * <ul> 243 * <li>Native seed type: {@code long[]}.</li> 244 * <li>Native seed size: 16.</li> 245 * </ul> 246 */ 247 XOR_SHIFT_1024_S(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S), 248 /** 249 * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres}. 250 * This generator is equivalent to {@link #TWO_CMRES_SELECT} with the choice of the 251 * pair {@code (0, 1)} for the two subcycle generators. 252 * <ul> 253 * <li>Native seed type: {@code Integer}.</li> 254 * <li>Native seed size: 1.</li> 255 * </ul> 256 */ 257 TWO_CMRES(ProviderBuilder.RandomSourceInternal.TWO_CMRES), 258 /** 259 * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres}, 260 * with explicit selection of the two subcycle generators. 261 * The selection of the subcycle generator is by passing its index in the internal 262 * table, a value between 0 (included) and 13 (included). 263 * The two indices must be different. 264 * Different choices of an ordered pair of indices create independent generators. 265 * <ul> 266 * <li>Native seed type: {@code Integer}.</li> 267 * <li>Native seed size: 1.</li> 268 * </ul> 269 */ 270 TWO_CMRES_SELECT(ProviderBuilder.RandomSourceInternal.TWO_CMRES_SELECT), 271 /** 272 * Source of randomness is {@link org.apache.commons.rng.core.source64.MersenneTwister64}. 273 * <ul> 274 * <li>Native seed type: {@code long[]}.</li> 275 * <li>Native seed size: 312.</li> 276 * </ul> 277 */ 278 MT_64(ProviderBuilder.RandomSourceInternal.MT_64), 279 /** 280 * Source of randomness is {@link org.apache.commons.rng.core.source32.MultiplyWithCarry256}. 281 * <ul> 282 * <li>Native seed type: {@code int[]}.</li> 283 * <li>Native seed size: 257.</li> 284 * </ul> 285 */ 286 MWC_256(ProviderBuilder.RandomSourceInternal.MWC_256), 287 /** 288 * Source of randomness is {@link org.apache.commons.rng.core.source32.KISSRandom}. 289 * <ul> 290 * <li>Native seed type: {@code int[]}.</li> 291 * <li>Native seed size: 4.</li> 292 * </ul> 293 */ 294 KISS(ProviderBuilder.RandomSourceInternal.KISS); 295 296 /** Internal identifier. */ 297 private final ProviderBuilder.RandomSourceInternal internalIdentifier; 298 299 /** 300 * @param id Internal identifier. 301 */ 302 RandomSource(ProviderBuilder.RandomSourceInternal id) { 303 internalIdentifier = id; 304 } 305 306 /** 307 * @return the internal identifier. 308 */ 309 ProviderBuilder.RandomSourceInternal getInternalIdentifier() { 310 return internalIdentifier; 311 } 312 313 /** 314 * Checks whether the type of given {@code seed} is the native type 315 * of the implementation. 316 * 317 * @param seed Seed value. 318 * @return {@code true} if the type of {@code seed} is the native 319 * type for this RNG source. 320 */ 321 public boolean isNativeSeed(Object seed) { 322 return internalIdentifier.isNativeSeed(seed); 323 } 324 325 /** 326 * Creates a random number generator with a random seed. 327 * 328 * <p>Usage example:</p> 329 * <pre><code> 330 * UniformRandomProvider rng = RandomSource.create(RandomSource.MT); 331 * </code></pre> 332 * <p>or, if a {@link RestorableUniformRandomProvider "save/restore"} functionality is needed,</p> 333 * <pre><code> 334 * RestorableUniformRandomProvider rng = RandomSource.create(RandomSource.MT); 335 * </code></pre> 336 * 337 * @param source RNG type. 338 * @return the RNG. 339 * 340 * @see #create(RandomSource,Object,Object[]) 341 */ 342 public static RestorableUniformRandomProvider create(RandomSource source) { 343 return create(source, null); 344 } 345 346 /** 347 * Creates a random number generator with the given {@code seed}. 348 * 349 * <p>Usage example:</p> 350 * <pre><code> 351 * UniformRandomProvider rng = RandomSource.create(RandomSource.TWO_CMRES_SELECT, 26219, 6, 9); 352 * </code></pre> 353 * 354 * <p>Valid types for the {@code seed} are:</p> 355 * <ul> 356 * <li>{@code Integer} (or {@code int})</li> 357 * <li>{@code Long} (or {@code long})</li> 358 * <li>{@code int[]}</li> 359 * <li>{@code long[]}</li> 360 * <li>{@code byte[]}</li> 361 * </ul> 362 * 363 * <p>Notes:</p> 364 * <ul> 365 * <li> 366 * When the seed type passed as argument is more complex (i.e. more 367 * bits can be independently chosen) than the generator's 368 * {@link #isNativeSeed(Object) native type}, the conversion of a 369 * set of different seeds will necessarily result in the same value 370 * of the native seed type. 371 * </li> 372 * <li> 373 * When the native seed type is an array, the same remark applies 374 * when the array contains more bits than the state of the generator. 375 * </li> 376 * <li> 377 * When the native seed type is an array and the {@code seed} is 378 * {@code null}, the size of the generated array will be 128. 379 * </li> 380 * </ul> 381 * 382 * @param source RNG type. 383 * @param seed Seed value. It can be {@code null} (in which case a 384 * random value will be used). 385 * @param data Additional arguments to the implementation's constructor. 386 * Please refer to the documentation of each specific implementation. 387 * @return the RNG. 388 * @throws UnsupportedOperationException if the type of the {@code seed} 389 * is invalid. 390 * @throws IllegalStateException if data is missing to initialize the 391 * generator implemented by the given {@code source}. 392 * 393 * @see #create(RandomSource) 394 */ 395 public static RestorableUniformRandomProvider create(RandomSource source, 396 Object seed, 397 Object ... data) { 398 return ProviderBuilder.create(source.getInternalIdentifier(), seed, data); 399 } 400 401 /** 402 * Creates a number for use as a seed. 403 * 404 * @return a random number. 405 */ 406 public static int createInt() { 407 return SeedFactory.createInt(); 408 } 409 410 /** 411 * Creates a number for use as a seed. 412 * 413 * @return a random number. 414 */ 415 public static long createLong() { 416 return SeedFactory.createLong(); 417 } 418 419 /** 420 * Creates an array of numbers for use as a seed. 421 * 422 * @param n Size of the array to create. 423 * @return an array of {@code n} random numbers. 424 */ 425 public static int[] createIntArray(int n) { 426 return SeedFactory.createIntArray(n); 427 } 428 429 /** 430 * Creates an array of numbers for use as a seed. 431 * 432 * @param n Size of the array to create. 433 * @return an array of {@code n} random numbers. 434 */ 435 public static long[] createLongArray(int n) { 436 return SeedFactory.createLongArray(n); 437 } 438 439 /** 440 * Wraps the given {@code delegate} generator in a new instance that 441 * does not allow access to the "save/restore" functionality. 442 * 443 * @param delegate Generator to which calls will be delegated. 444 * @return a new instance whose state cannot be saved or restored. 445 */ 446 public static UniformRandomProvider unrestorable(final UniformRandomProvider delegate) { 447 return new UniformRandomProvider() { 448 /** {@inheritDoc} */ 449 @Override 450 public void nextBytes(byte[] bytes) { 451 delegate.nextBytes(bytes); 452 } 453 454 /** {@inheritDoc} */ 455 @Override 456 public void nextBytes(byte[] bytes, 457 int start, 458 int len) { 459 delegate.nextBytes(bytes, start, len); 460 } 461 462 /** {@inheritDoc} */ 463 @Override 464 public int nextInt() { 465 return delegate.nextInt(); 466 } 467 468 /** {@inheritDoc} */ 469 @Override 470 public int nextInt(int n) { 471 return delegate.nextInt(n); 472 } 473 474 /** {@inheritDoc} */ 475 @Override 476 public long nextLong() { 477 return delegate.nextLong(); 478 } 479 480 /** {@inheritDoc} */ 481 @Override 482 public long nextLong(long n) { 483 return delegate.nextLong(n); 484 } 485 486 /** {@inheritDoc} */ 487 @Override 488 public boolean nextBoolean() { 489 return delegate.nextBoolean(); 490 } 491 492 /** {@inheritDoc} */ 493 @Override 494 public float nextFloat() { 495 return delegate.nextFloat(); 496 } 497 498 /** {@inheritDoc} */ 499 @Override 500 public double nextDouble() { 501 return delegate.nextDouble(); 502 } 503 504 /** {@inheritDoc} */ 505 @Override 506 public String toString() { 507 return delegate.toString(); 508 } 509 }; 510 } 511}