| /* | |
| * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| package java.util.random; | |
| import java.math.BigInteger; | |
| import java.security.SecureRandom; | |
| import java.util.Objects; | |
| import java.util.concurrent.ThreadLocalRandom; | |
| import jdk.internal.util.random.RandomSupport; | |
| import java.util.stream.DoubleStream; | |
| import java.util.stream.IntStream; | |
| import java.util.stream.LongStream; | |
| import java.util.stream.Stream; | |
| import static java.lang.Math.*; | |
| /** | |
| * The {@link RandomGenerator} interface is designed to provide a common | |
| * protocol for objects that generate random or (more typically) pseudorandom | |
| * sequences of numbers (or Boolean values). Such a sequence may be obtained by | |
| * either repeatedly invoking a method that returns a single pseudorandomly | |
| * chosen value, or by invoking a method that returns a stream of | |
| * pseudorandomly chosen values. | |
| * | |
| * <p> Ideally, given an implicitly or explicitly specified range of values, | |
| * each value would be chosen independently and uniformly from that range. In | |
| * practice, one may have to settle for some approximation to independence and | |
| * uniformity. | |
| * | |
| * <p> In the case of {@code int}, {@code long}, and {@code boolean} values, if | |
| * there is no explicit specification of range, then the range includes all | |
| * possible values of the type. In the case of {@code float} and {@code double} | |
| * values, first a value is always chosen uniformly from the set of | |
| * 2<sup><i>w</i></sup> values between 0.0 (inclusive) and 1.0 (exclusive), | |
| * where <i>w</i> is {@link Float#PRECISION} for {@code float} values | |
| * and {@link Double#PRECISION} for {@code double} | |
| * values, such that adjacent values differ by 2<sup>−<i>w</i></sup> | |
| * (notice that this set is a <i>subset</i> of the set of | |
| * <i>all representable floating-point values</i> between 0.0 (inclusive) and 1.0 (exclusive)); | |
| * then if an explicit range was specified, then the chosen number is | |
| * computationally scaled and translated so as to appear to have been chosen | |
| * approximately uniformly from that explicit range. | |
| * | |
| * <p> Each method that returns a stream produces a stream of values each of | |
| * which is chosen in the same manner as for a method that returns a single | |
| * pseudorandomly chosen value. For example, if {@code r} implements | |
| * {@link RandomGenerator}, then the method call {@code r.ints(100)} returns a | |
| * stream of 100 {@code int} values. These are not necessarily the exact same | |
| * values that would have been returned if instead {@code r.nextInt()} had been | |
| * called 100 times; all that is guaranteed is that each value in the stream is | |
| * chosen in a similar pseudorandom manner from the same range. | |
| * | |
| * <p> Every object that implements the {@link RandomGenerator} interface by | |
| * using a pseudorandom algorithm is assumed to contain a finite amount of | |
| * state. Using such an object to generate a pseudorandomly chosen value alters | |
| * its state by computing a new state as a function of the current state, | |
| * without reference to any information other than the current state. The number | |
| * of distinct possible states of such an object is called its <i>period</i>. | |
| * (Some implementations of the {@link RandomGenerator} interface may be truly | |
| * random rather than pseudorandom, for example relying on the statistical | |
| * behavior of a physical object to derive chosen values. Such implementations | |
| * do not have a fixed period.) | |
| * | |
| * <p> As a rule, objects that implement the {@link RandomGenerator} interface | |
| * need not be thread-safe. It is recommended that multithreaded applications | |
| * use either {@link ThreadLocalRandom} or (preferably) pseudorandom number | |
| * generators that implement the {@link SplittableGenerator} or | |
| * {@link JumpableGenerator} interface. | |
| * | |
| * <p> Objects that implement {@link RandomGenerator} are typically not | |
| * cryptographically secure. Consider instead using {@link SecureRandom} to get | |
| * a cryptographically secure pseudorandom number generator for use by | |
| * security-sensitive applications. Note, however, that {@link SecureRandom} | |
| * does implement the {@link RandomGenerator} interface, so that instances of | |
| * {@link SecureRandom} may be used interchangeably with other types of | |
| * pseudorandom generators in applications that do not require a secure | |
| * generator. | |
| * | |
| * <p>Unless explicit stated otherwise, the use of null for any method argument | |
| * will cause a NullPointerException. | |
| * | |
| * @since 17 | |
| * | |
| */ | |
| public interface RandomGenerator { | |
| /** | |
| * Returns an instance of {@link RandomGenerator} that utilizes the | |
| * {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link RandomGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static RandomGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, RandomGenerator.class); | |
| } | |
| /** | |
| * Returns a {@link RandomGenerator} meeting the minimal requirement | |
| * of having an <a href="package-summary.html#algorithms">algorithm</a> | |
| * whose state bits are greater than or equal 64. | |
| * | |
| * @implSpec Since algorithms will improve over time, there is no | |
| * guarantee that this method will return the same algorithm over time. | |
| * <p> The default implementation selects L32X64MixRandom. | |
| * | |
| * @return a {@link RandomGenerator} | |
| */ | |
| static RandomGenerator getDefault() { | |
| return of("L32X64MixRandom"); | |
| } | |
| /** | |
| * Return true if the implementation of RandomGenerator (algorithm) has been | |
| * marked for deprecation. | |
| * | |
| * @implNote Random number generator algorithms evolve over time; new | |
| * algorithms will be introduced and old algorithms will | |
| * lose standing. If an older algorithm is deemed unsuitable | |
| * for continued use, it will be marked as deprecated to indicate | |
| * that it may be removed at some point in the future. | |
| * | |
| * @return true if the implementation of RandomGenerator (algorithm) has been | |
| * marked for deprecation | |
| * | |
| * @implSpec The default implementation checks for the @Deprecated annotation. | |
| */ | |
| default boolean isDeprecated() { | |
| return this.getClass().isAnnotationPresent(Deprecated.class); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code double} values. | |
| * | |
| * @return a stream of pseudorandomly chosen {@code double} values | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link RandomGenerator#doubles(long) doubles} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextDouble nextDouble}(). | |
| */ | |
| default DoubleStream doubles() { | |
| return DoubleStream.generate(this::nextDouble).sequential(); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code double} values, where each value is between the specified origin | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code double} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code randomNumberOrigin} is not finite, | |
| * or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link RandomGenerator#doubles(long, double, double) doubles} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}, randomNumberOrigin, randomNumberBound). | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextDouble(double, double) nextDouble}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code double} values. | |
| * | |
| * @param streamSize the number of values to generate | |
| * | |
| * @return a stream of pseudorandomly chosen {@code double} values | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextDouble nextDouble()}. | |
| */ | |
| default DoubleStream doubles(long streamSize) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| return doubles().limit(streamSize); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code double} values, where each value is | |
| * between the specified origin (inclusive) and the specified bound | |
| * (exclusive). | |
| * | |
| * @param streamSize the number of values to generate | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code double} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is less than zero, | |
| * or {@code randomNumberOrigin} is not finite, | |
| * or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextDouble(double, double) nextDouble}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default DoubleStream doubles(long streamSize, double randomNumberOrigin, | |
| double randomNumberBound) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code double} values, where each value is between the specified | |
| * {@code left} boundary and the specified {@code right} boundary. | |
| * The {@code left} boundary is included as indicated by | |
| * {@code isLeftIncluded}; similarly, the {@code right} boundary is included | |
| * as indicated by {@code isRightIncluded}. | |
| * | |
| * <p>The stream potentially produces all multiples <i>k</i> δ | |
| * (<i>k</i> integer) lying in the interval specified by the parameters, | |
| * where δ > 0 is the smallest number for which all these multiples | |
| * are exact {@code double}s. | |
| * They are therefore all equidistant. | |
| * The uniformity of the distribution of the {@code double}s produced by | |
| * the stream depends on the quality of the underlying {@link #nextLong(long)}. | |
| * | |
| * @implSpec The default implementation first determines the δ above. | |
| * It then computes both the smallest integer <i>k</i><sub><i>l</i></sub> | |
| * such that <i>k</i><sub><i>l</i></sub> δ lies <em>inside</em> | |
| * the given interval, and the smallest integer <i>n</i> > 0 such that | |
| * (<i>k</i><sub><i>l</i></sub> + <i>n</i>) δ lies | |
| * <em>outside</em> the interval. | |
| * Finally, it returns a stream which generates the {@code double}s | |
| * according to (<i>k</i><sub><i>l</i></sub> + {@code nextLong(}<i>n</i>{@code )}) | |
| * δ. | |
| * The stream never produces {@code -0.0}, although it may produce | |
| * {@code 0.0} if the specified interval contains 0. | |
| * | |
| * @param left the left boundary | |
| * @param right the right boundary | |
| * @param isLeftIncluded whether the {@code left} boundary is included | |
| * @param isRightIncluded whether the {@code right} boundary is included | |
| * | |
| * @return a stream of pseudorandomly chosen {@code double} values, each | |
| * between {@code left} and {@code right}, as specified above. | |
| * | |
| * @throws IllegalArgumentException if {@code left} is not finite, | |
| * or {@code right} is not finite, or if the specified interval | |
| * is empty. | |
| * | |
| * @since 22 | |
| */ | |
| default DoubleStream equiDoubles(double left, double right, | |
| boolean isLeftIncluded, boolean isRightIncluded) { | |
| if (!(Double.NEGATIVE_INFINITY < left | |
| && right < Double.POSITIVE_INFINITY | |
| && (isLeftIncluded ? left : nextUp(left)) | |
| <= (isRightIncluded ? right : nextDown(right)))) { | |
| throw new IllegalArgumentException( | |
| "the boundaries must be finite and the interval must not be empty"); | |
| } | |
| /* | |
| * Inspired by | |
| * Goualard, "Drawing random floating-point numbers from an | |
| * interval", ACM TOMACS, 2022, 32 (3) | |
| * (https://hal.science/hal-03282794v4) | |
| * although implemented differently. | |
| * | |
| * It is assumed that left <= right. | |
| * Whether the boundaries of the interval I = <left, right> are included | |
| * is indicated by isLeftIncluded and isRightIncluded. | |
| * | |
| * delta > 0 is the smallest double such that every product k delta | |
| * (k integer) that lies in I is an exact double as well. | |
| * It turns out that delta is always a power of 2. | |
| * | |
| * kl is the smallest k such that k delta is inside I. | |
| * kr > kl is the smallest k such that k delta is outside I. | |
| * n is kr - kl | |
| */ | |
| double delta; // captured | |
| long kl; // captured | |
| long kr; | |
| long n; // captured | |
| if (left <= -right) { | |
| /* | |
| * Here, | |
| * left <= 0, left <= right <= -left | |
| * P = Double.PRECISION | |
| * | |
| * delta is the distance from left to the next double in the | |
| * direction of positive infinity. | |
| * Most of the time, this is equivalent to the ulp of left, but not | |
| * always. | |
| * For example, for left == -1.0, Math.ulp(left) == 2.220446049250313E-16, | |
| * whereas delta as computed here is 1.1102230246251565E-16. | |
| * | |
| * Every product k delta lying in [left, -left] is an exact double. | |
| * Thus, every product k delta lying in I is an exact double, too. | |
| * Any other positive eps < delta does not meet this property: | |
| * some product k eps lying in I is not an exact double. | |
| * On the other hand, any other eps > delta would generate more | |
| * sparse products k eps, that is, fewer doubles in I. | |
| * delta is therefore the best value to ensure the largest number | |
| * of equidistant doubles in the interval I. | |
| * | |
| * left / delta is an exact double and an exact integer with | |
| * -2^P <= left / delta <= 0 | |
| * Thus, kl is computed exactly. | |
| * | |
| * Mathematically, | |
| * kr = ceil(right / delta), if !isRightIncluded | |
| * kr = floor(right / delta) + 1, if isRightIncluded | |
| * The double division rd = right / delta never overflows and is | |
| * exact, except in the presence of underflows. But even underflows | |
| * do not affect the outcomes of ceil() and floor(), except, | |
| * in turn, when the result drops to 0, that is, rd = 0. | |
| * | |
| * crd is a corrected version of rd when rd is zero. It is simply | |
| * right / delta, but rounded away from 0 to preserve information | |
| * ensuring correct outcomes in ceil() and floor(). | |
| * | |
| * We know that -2^P <= kl, so | |
| * -2^P <= kl + nextLong(n) | |
| * Also, since right <= -left, we know that | |
| * kr <= -kl + 1 | |
| * so that | |
| * 0 < n <= -2 kl + 1 | |
| * This implies | |
| * kl + nextLong(n) <= kl + (-2 kl) = -kl <= 2^P | |
| * and thus | |
| * -2^P <= kl + nextLong(n) <= 2^P | |
| * which shows that kl + nextLong(n) can be cast exactly to double. | |
| * | |
| * Further, if isLeftIncluded then left = kl delta, so that we get | |
| * left = kl * delta <= (kl + nextLong(n)) * delta | |
| * For any other k < kl, when nextLong(n) = 0 we would have | |
| * (k + nextLong(n)) * delta < left | |
| * Otherwise, left = (kl - 1) delta, and therefore | |
| * left = (kl - 1) * delta < (kl + nextLong(n)) * delta | |
| * For any other k < kl, when nextLong(n) = 0 we would get | |
| * (k + nextLong(n)) * delta <= left | |
| * Either way, the lhs expression would not belong to I. | |
| * That is, kl is the smallest integer such that kl delta always | |
| * lies in I (it is an exact double). | |
| * | |
| * Similar considerations show that kr is the smallest integer such | |
| * that kr delta lies to the right of I (it is an exact double). | |
| * | |
| * All the above means that (kl + nextLong(n)) * delta is an exact | |
| * double lying in I and that kl and kr, thus n, are the best | |
| * possible choices to ensure the largest number of equidistant | |
| * doubles in I. Uniform distribution relies on the guarantee | |
| * afforded by nextLong(). | |
| */ | |
| delta = nextUp(left) - left; | |
| double rd = right / delta; | |
| double crd = rd != 0 || right == 0 ? rd : copySign(Double.MIN_VALUE, right); | |
| kr = isRightIncluded ? (long) floor(crd) + 1 : (long) ceil(crd); | |
| kl = (long) (left / delta) + (isLeftIncluded ? 0 : 1); | |
| } else { | |
| /* Here, | |
| * right > 0, -right < left <= right | |
| * | |
| * Considerations similar to the ones above apply here as well. | |
| */ | |
| delta = right - nextDown(right); | |
| double ld = left / delta; | |
| double cld = ld != 0 || left == 0 ? ld : copySign(Double.MIN_VALUE, left); | |
| kl = isLeftIncluded ? (long) ceil(cld) : (long) floor(cld) + 1; | |
| kr = (long) (right / delta) + (isRightIncluded ? 1 : 0); | |
| } | |
| n = kr - kl; | |
| return DoubleStream.generate(() -> (kl + nextLong(n)) * delta).sequential(); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code int} values. | |
| * | |
| * @return a stream of pseudorandomly chosen {@code int} values | |
| * | |
| * @implNote It is permitted to implement this method in a manner | |
| * equivalent to {@link RandomGenerator#ints(long) ints} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextInt() nextInt}(). | |
| */ | |
| default IntStream ints() { | |
| return IntStream.generate(this::nextInt).sequential(); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code int} values, where each value is between the specified origin | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code int} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link RandomGenerator#ints(long, int, int) ints} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}, randomNumberOrigin, randomNumberBound). | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextInt(int, int) nextInt}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default IntStream ints(int randomNumberOrigin, int randomNumberBound) { | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code int} values. | |
| * | |
| * @param streamSize the number of values to generate | |
| * | |
| * @return a stream of pseudorandomly chosen {@code int} values | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextInt() nextInt}(). | |
| */ | |
| default IntStream ints(long streamSize) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| return ints().limit(streamSize); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code int} values, where each value is between | |
| * the specified origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param streamSize the number of values to generate | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code int} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero, or {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextInt(int, int) nextInt}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default IntStream ints(long streamSize, int randomNumberOrigin, | |
| int randomNumberBound) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return ints(randomNumberOrigin, randomNumberBound).limit(streamSize); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code long} values. | |
| * | |
| * @return a stream of pseudorandomly chosen {@code long} values | |
| * | |
| * @implNote It is permitted to implement this method in a manner | |
| * equivalent to {@link RandomGenerator#longs(long) longs} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextLong() nextLong}(). | |
| */ | |
| default LongStream longs() { | |
| return LongStream.generate(this::nextLong).sequential(); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of pseudorandomly chosen | |
| * {@code long} values, where each value is between the specified origin | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code long} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link RandomGenerator#longs(long, long, long) longs} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}, randomNumberOrigin, randomNumberBound). | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextLong(long, long) nextLong}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default LongStream longs(long randomNumberOrigin, long randomNumberBound) { | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code long} values. | |
| * | |
| * @param streamSize the number of values to generate | |
| * | |
| * @return a stream of pseudorandomly chosen {@code long} values | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * | |
| * @implSpec The default implementation produces a sequential stream | |
| * that repeatedly calls {@link RandomGenerator#nextLong() nextLong}(). | |
| */ | |
| default LongStream longs(long streamSize) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| return longs().limit(streamSize); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of | |
| * pseudorandomly chosen {@code long} values, where each value is between | |
| * the specified origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param streamSize the number of values to generate | |
| * @param randomNumberOrigin the least value that can be produced | |
| * @param randomNumberBound the upper bound (exclusive) for each value produced | |
| * | |
| * @return a stream of pseudorandomly chosen {@code long} values, each between | |
| * the specified origin (inclusive) and the specified bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero, or {@code randomNumberOrigin} | |
| * is greater than or equal to {@code randomNumberBound} | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link RandomGenerator#nextLong(long, long) nextLong}(randomNumberOrigin, randomNumberBound). | |
| */ | |
| default LongStream longs(long streamSize, long randomNumberOrigin, | |
| long randomNumberBound) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| RandomSupport.checkRange(randomNumberOrigin, randomNumberBound); | |
| return longs(randomNumberOrigin, randomNumberBound).limit(streamSize); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code boolean} value. | |
| * | |
| * <p> The default implementation tests the high-order bit (sign bit) of a | |
| * value produced by {@link RandomGenerator#nextInt() nextInt}(), on the | |
| * grounds that some algorithms for pseudorandom number generation produce | |
| * values whose high-order bits have better statistical quality than the | |
| * low-order bits. | |
| * | |
| * @return a pseudorandomly chosen {@code boolean} value | |
| * | |
| * @implSpec The default implementation produces a result based on the | |
| * sign bit of a number generated by {@link nextInt()}. | |
| */ | |
| default boolean nextBoolean() { | |
| return nextInt() < 0; | |
| } | |
| /** | |
| * Fills a user-supplied byte array with generated byte values | |
| * pseudorandomly chosen uniformly from the range of values between -128 | |
| * (inclusive) and 127 (inclusive). | |
| * | |
| * @implNote Algorithm used to fill the byte array; | |
| * <pre>{@code | |
| * void nextBytes(byte[] bytes) { | |
| * int i = 0; | |
| * int len = bytes.length; | |
| * for (int words = len >> 3; words--> 0; ) { | |
| * long rnd = nextLong(); | |
| * for (int n = 8; n--> 0; rnd >>>= Byte.SIZE) | |
| * bytes[i++] = (byte)rnd; | |
| * } | |
| * if (i < len) | |
| * for (long rnd = nextLong(); i < len; rnd >>>= Byte.SIZE) | |
| * bytes[i++] = (byte)rnd; | |
| * }}</pre> | |
| * | |
| * @param bytes the byte array to fill with pseudorandom bytes | |
| * @throws NullPointerException if bytes is null | |
| * | |
| * @implSpec The default implementation produces results from repeated calls | |
| * to {@link nextLong()}. | |
| */ | |
| default void nextBytes(byte[] bytes) { | |
| int i = 0; | |
| int len = bytes.length; | |
| for (int words = len >> 3; words--> 0; ) { | |
| long rnd = nextLong(); | |
| for (int n = 8; n--> 0; rnd >>>= Byte.SIZE) | |
| bytes[i++] = (byte)rnd; | |
| } | |
| if (i < len) | |
| for (long rnd = nextLong(); i < len; rnd >>>= Byte.SIZE) | |
| bytes[i++] = (byte)rnd; | |
| } | |
| /** | |
| * Returns a pseudorandom {@code float} value between zero (inclusive) and | |
| * one (exclusive). | |
| * | |
| * @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive) | |
| * | |
| * @implSpec The default implementation uses the {@link Float#PRECISION} | |
| * high-order bits from a call to {@link RandomGenerator#nextInt() nextInt()}. | |
| */ | |
| default float nextFloat() { | |
| return (nextInt() >>> (Float.SIZE - Float.PRECISION)) * 0x1.0p-24f; | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code float} value between zero | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param bound the upper bound (exclusive) for the returned value. | |
| * Must be positive and finite | |
| * | |
| * @return a pseudorandomly chosen {@code float} value between | |
| * zero (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code bound} is not | |
| * both positive and finite | |
| * | |
| * @implSpec The default implementation checks that {@code bound} is a | |
| * positive finite float. Then invokes {@code nextFloat()}, scaling | |
| * the result so that the final result lies between {@code 0.0f} (inclusive) | |
| * and {@code bound} (exclusive). | |
| */ | |
| default float nextFloat(float bound) { | |
| RandomSupport.checkBound(bound); | |
| return RandomSupport.boundedNextFloat(this, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code float} value between the | |
| * specified origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param origin the least value that can be returned | |
| * @param bound the upper bound (exclusive) | |
| * | |
| * @return a pseudorandomly chosen {@code float} value between the | |
| * origin (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code origin} is not finite, | |
| * or {@code bound} is not finite, or {@code origin} | |
| * is greater than or equal to {@code bound} | |
| * | |
| * @implSpec The default implementation verifies that the {@code origin} | |
| * and {@code bound} are valid then invokes {@code nextFloat()} | |
| * scaling and translating the result to fit between {@code origin} | |
| * and {@code bound} (exclusive). | |
| */ | |
| default float nextFloat(float origin, float bound) { | |
| RandomSupport.checkRange(origin, bound); | |
| return RandomSupport.boundedNextFloat(this, origin, bound); | |
| } | |
| /** | |
| * Returns a pseudorandom {@code double} value between zero (inclusive) and | |
| * one (exclusive). | |
| * | |
| * @return a pseudorandom {@code double} value between zero (inclusive) | |
| * and one (exclusive) | |
| * | |
| * @implSpec The default implementation uses the {@link Double#PRECISION} | |
| * high-order bits from a call to {@link RandomGenerator#nextLong() nextLong()}. | |
| */ | |
| default double nextDouble() { | |
| return (nextLong() >>> (Double.SIZE - Double.PRECISION)) * 0x1.0p-53; | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code double} value between zero | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param bound the upper bound (exclusive) for the returned value. | |
| * Must be positive and finite | |
| * | |
| * @return a pseudorandomly chosen {@code double} value between | |
| * zero (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code bound} is not | |
| * both positive and finite | |
| * | |
| * @implSpec The default implementation checks that {@code bound} is a | |
| * positive finite double. Then invokes {@code nextDouble()}, scaling | |
| * the result so that the final result lies between {@code 0.0} (inclusive) | |
| * and {@code bound} (exclusive). | |
| */ | |
| default double nextDouble(double bound) { | |
| RandomSupport.checkBound(bound); | |
| return RandomSupport.boundedNextDouble(this, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code double} value between the | |
| * specified origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param origin the least value that can be returned | |
| * @param bound the upper bound (exclusive) for the returned value | |
| * | |
| * @return a pseudorandomly chosen {@code double} value between the | |
| * origin (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code origin} is not finite, | |
| * or {@code bound} is not finite, or {@code origin} | |
| * is greater than or equal to {@code bound} | |
| * @implSpec The default implementation verifies that the {@code origin} | |
| * and {@code bound} are valid, then invokes {@code nextDouble()} | |
| * scaling and translating the result to fit between {@code origin} | |
| * and {@code bound}( exclusive). | |
| */ | |
| default double nextDouble(double origin, double bound) { | |
| RandomSupport.checkRange(origin, bound); | |
| return RandomSupport.boundedNextDouble(this, origin, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code int} value. | |
| * | |
| * @return a pseudorandomly chosen {@code int} value | |
| * | |
| * @implSpec The default implementation uses the 32 high-order bits from a call to | |
| * {@link RandomGenerator#nextLong nextLong}(). | |
| */ | |
| default int nextInt() { | |
| return (int)(nextLong() >>> 32); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code int} value between zero | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param bound the upper bound (exclusive) for the returned value. | |
| * Must be positive. | |
| * | |
| * @return a pseudorandomly chosen {@code int} value between | |
| * zero (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code bound} is not positive | |
| * | |
| * @implSpec The default implementation checks that {@code bound} is positive. | |
| * It then invokes {@link #nextInt()} one or more times to ensure a uniform | |
| * distribution in the range 0 (inclusive) | |
| * to {@code bound} (exclusive). | |
| * It assumes the distribution of {@link #nextInt()} to be uniform. | |
| */ | |
| default int nextInt(int bound) { | |
| RandomSupport.checkBound(bound); | |
| return RandomSupport.boundedNextInt(this, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code int} value between the specified | |
| * origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param origin the least value that can be returned | |
| * @param bound the upper bound (exclusive) for the returned value | |
| * | |
| * @return a pseudorandomly chosen {@code int} value between the | |
| * origin (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code origin} is greater than | |
| * or equal to {@code bound} | |
| * | |
| * @implSpec The default implementation checks that {@code origin} | |
| * is less than {@code bound}. | |
| * It then invokes {@link #nextInt()} one or more times to ensure a uniform | |
| * distribution in the range {@code origin} (inclusive) | |
| * to {@code bound} (exclusive). | |
| * It assumes the distribution of {@link #nextInt()} to be uniform. | |
| */ | |
| default int nextInt(int origin, int bound) { | |
| RandomSupport.checkRange(origin, bound); | |
| return RandomSupport.boundedNextInt(this, origin, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code long} value. | |
| * | |
| * @return a pseudorandomly chosen {@code long} value | |
| */ | |
| long nextLong(); | |
| /** | |
| * Returns a pseudorandomly chosen {@code long} value between zero | |
| * (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param bound the upper bound (exclusive) for the returned value. | |
| * Must be positive. | |
| * | |
| * @return a pseudorandomly chosen {@code long} value between | |
| * zero (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code bound} is not positive | |
| * | |
| * @implSpec The default implementation checks that {@code bound} is positive. | |
| * It then invokes {@link #nextLong()} one or more times to ensure a uniform | |
| * distribution in the range 0 (inclusive) | |
| * to {@code bound} (exclusive). | |
| * It assumes the distribution of {@link #nextLong()} to be uniform. | |
| */ | |
| default long nextLong(long bound) { | |
| RandomSupport.checkBound(bound); | |
| return RandomSupport.boundedNextLong(this, bound); | |
| } | |
| /** | |
| * Returns a pseudorandomly chosen {@code long} value between the | |
| * specified origin (inclusive) and the specified bound (exclusive). | |
| * | |
| * @param origin the least value that can be returned | |
| * @param bound the upper bound (exclusive) for the returned value | |
| * | |
| * @return a pseudorandomly chosen {@code long} value between the | |
| * origin (inclusive) and the bound (exclusive) | |
| * | |
| * @throws IllegalArgumentException if {@code origin} is greater than | |
| * or equal to {@code bound} | |
| * | |
| * @implSpec The default implementation checks that {@code origin} | |
| * is less than {@code bound}. | |
| * It then invokes {@link #nextLong()} one or more times to ensure a uniform | |
| * distribution in the range {@code origin} (inclusive) | |
| * to {@code bound} (exclusive). | |
| * It assumes the distribution of {@link #nextLong()} to be uniform. | |
| */ | |
| default long nextLong(long origin, long bound) { | |
| RandomSupport.checkRange(origin, bound); | |
| return RandomSupport.boundedNextLong(this, origin, bound); | |
| } | |
| /** | |
| * Returns a {@code double} value pseudorandomly chosen from a Gaussian | |
| * (normal) distribution whose mean is 0 and whose standard deviation is 1. | |
| * | |
| * @return a {@code double} value pseudorandomly chosen from a | |
| * Gaussian distribution | |
| * | |
| * @implSpec The default implementation uses McFarland's fast modified | |
| * ziggurat algorithm (largely table-driven, with rare cases handled by | |
| * computation and rejection sampling). Walker's alias method for sampling | |
| * a discrete distribution also plays a role. | |
| */ | |
| default double nextGaussian() { | |
| // See Knuth, TAOCP, Vol. 2, 3rd edition, Section 3.4.1 Algorithm C. | |
| return RandomSupport.computeNextGaussian(this); | |
| } | |
| /** | |
| * Returns a {@code double} value pseudorandomly chosen from a Gaussian | |
| * (normal) distribution with a mean and standard deviation specified by the | |
| * arguments. | |
| * | |
| * @param mean the mean of the Gaussian distribution to be drawn from | |
| * @param stddev the standard deviation (square root of the variance) | |
| * of the Gaussian distribution to be drawn from | |
| * | |
| * @return a {@code double} value pseudorandomly chosen from the | |
| * specified Gaussian distribution | |
| * | |
| * @throws IllegalArgumentException if {@code stddev} is negative | |
| * | |
| * @implSpec The default implementation uses McFarland's fast modified | |
| * ziggurat algorithm (largely table-driven, with rare cases handled by | |
| * computation and rejection sampling). Walker's alias method for sampling | |
| * a discrete distribution also plays a role. | |
| */ | |
| default double nextGaussian(double mean, double stddev) { | |
| if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative"); | |
| return mean + stddev * RandomSupport.computeNextGaussian(this); | |
| } | |
| /** | |
| * Returns a nonnegative {@code double} value pseudorandomly chosen from | |
| * an exponential distribution whose mean is 1. | |
| * | |
| * @return a nonnegative {@code double} value pseudorandomly chosen from an | |
| * exponential distribution | |
| * | |
| * @implSpec The default implementation uses McFarland's fast modified | |
| * ziggurat algorithm (largely table-driven, with rare cases handled by | |
| * computation and rejection sampling). Walker's alias method for sampling | |
| * a discrete distribution also plays a role. | |
| */ | |
| default double nextExponential() { | |
| return RandomSupport.computeNextExponential(this); | |
| } | |
| /** | |
| * The {@link StreamableGenerator} interface augments the | |
| * {@link RandomGenerator} interface to provide methods that return streams | |
| * of {@link RandomGenerator} objects. Ideally, such a stream of objects | |
| * would have the property that the behavior of each object is statistically | |
| * independent of all the others. In practice, one may have to settle for | |
| * some approximation to this property. | |
| * | |
| * <p> A generator that implements interface {@link SplittableGenerator} may | |
| * choose to use its {@link SplittableGenerator#splits splits}() method to | |
| * implement the {@link StreamableGenerator#rngs rngs}() method required by this | |
| * interface. | |
| * | |
| * <p> A generator that implements interface {@link JumpableGenerator} may | |
| * choose to use its {@link JumpableGenerator#jumps() jumps}() method to implement the | |
| * {@link StreamableGenerator#rngs() rngs}() method required by this interface. | |
| * | |
| * <p> A generator that implements interface {@link LeapableGenerator} may | |
| * choose to use its {@link LeapableGenerator#leaps() leaps}() method to | |
| * implement the {@link StreamableGenerator#rngs() rngs}() method required by this | |
| * interface. | |
| * | |
| * <p> Objects that implement {@link StreamableGenerator} are typically not | |
| * cryptographically secure. Consider instead using {@link SecureRandom} to | |
| * get a cryptographically secure pseudo-random number generator for use by | |
| * security-sensitive applications. | |
| */ | |
| interface StreamableGenerator extends RandomGenerator { | |
| /** | |
| * Returns an instance of {@link StreamableGenerator} that utilizes the | |
| * {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link StreamableGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static StreamableGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, StreamableGenerator.class); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of objects, each of which | |
| * implements the {@link RandomGenerator} interface. Ideally the | |
| * generators in the stream will appear to be statistically independent. | |
| * The new generators are of the same | |
| * <a href="package-summary.html#algorithms">algorithm</a> as this generator. | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @implNote It is permitted to implement this method in a manner | |
| * equivalent to {@link StreamableGenerator#rngs(long) rngs} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| */ | |
| Stream<RandomGenerator> rngs(); | |
| /** | |
| * Returns an effectively unlimited stream of objects, each of which | |
| * implements the {@link RandomGenerator} interface. Ideally the | |
| * generators in the stream will appear to be statistically independent. | |
| * The new generators are of the same | |
| * <a href="package-summary.html#algorithms">algorithm</a> as this generator. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * | |
| * @implSpec The default implementation calls {@link StreamableGenerator#rngs() rngs}() and | |
| * then limits its length to {@code streamSize}. | |
| */ | |
| default Stream<RandomGenerator> rngs(long streamSize) { | |
| RandomSupport.checkStreamSize(streamSize); | |
| return rngs().limit(streamSize); | |
| } | |
| } | |
| /** | |
| * This interface is designed to provide a common protocol for objects that | |
| * generate sequences of pseudorandom values and can be <i>split</i> into | |
| * two objects (the original one and a new one) each of which obey that same | |
| * protocol (and therefore can be recursively split indefinitely). | |
| * | |
| * <p> Ideally, all {@link SplittableGenerator} objects produced by | |
| * recursive splitting from a single original {@link SplittableGenerator} | |
| * object are statistically independent of one another and individually | |
| * uniform. Therefore we would expect the set of values collectively | |
| * generated by a set of such objects to have the same statistical | |
| * properties as if the same quantity of values were generated by a single | |
| * thread using a single {@link SplittableGenerator} object. In practice, | |
| * one must settle for some approximation to independence and uniformity. | |
| * | |
| * <p> Methods are provided to perform a single splitting operation and also | |
| * to produce a stream of generators split off from the original (by either | |
| * iterative or recursive splitting, or a combination). | |
| * | |
| * <p> Objects that implement {@link SplittableGenerator} are typically not | |
| * cryptographically secure. Consider instead using {@link SecureRandom} to | |
| * get a cryptographically secure pseudo-random number generator for use by | |
| * security-sensitive applications. | |
| */ | |
| interface SplittableGenerator extends StreamableGenerator { | |
| /** | |
| * Returns an instance of {@link SplittableGenerator} that utilizes the | |
| * {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link SplittableGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static SplittableGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, SplittableGenerator.class); | |
| } | |
| /** | |
| * Returns a new pseudorandom number generator, split off from this one, | |
| * that implements the {@link RandomGenerator} and | |
| * {@link SplittableGenerator} interfaces. | |
| * | |
| * <p> This pseudorandom number generator may be used as a source of | |
| * pseudorandom bits used to initialize the state of the new one. | |
| * | |
| * @return a new object that implements the {@link RandomGenerator} and | |
| * {@link SplittableGenerator} interfaces | |
| */ | |
| SplittableGenerator split(); | |
| /** | |
| * Returns a new pseudorandom number generator, split off from this one, | |
| * that implements the {@link RandomGenerator} and | |
| * {@link SplittableGenerator} interfaces. | |
| * | |
| * @param source a {@link SplittableGenerator} instance to be used instead | |
| * of this one as a source of pseudorandom bits used to | |
| * initialize the state of the new ones. | |
| * | |
| * @return an object that implements the {@link RandomGenerator} and | |
| * {@link SplittableGenerator} interfaces | |
| * | |
| * @throws NullPointerException if source is null | |
| */ | |
| SplittableGenerator split(SplittableGenerator source); | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link SplittableGenerator} | |
| * interface. | |
| * | |
| * <p> This pseudorandom number generator may be used as a source of | |
| * pseudorandom bits used to initialize the state the new ones. | |
| * | |
| * @implNote It is permitted to implement this method in a manner | |
| * equivalent to {@link SplittableGenerator#splits(long) splits} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @return a stream of {@link SplittableGenerator} objects | |
| * | |
| * @implSpec The default implementation invokes | |
| * {@link SplittableGenerator#splits(SplittableGenerator) splits(this)}. | |
| */ | |
| default Stream<SplittableGenerator> splits() { | |
| return this.splits(this); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link SplittableGenerator} interface. | |
| * | |
| * <p> This pseudorandom number generator may be used as a source of | |
| * pseudorandom bits used to initialize the state the new ones. | |
| * | |
| * @param streamSize the number of values to generate | |
| * | |
| * @return a stream of {@link SplittableGenerator} objects | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| */ | |
| Stream<SplittableGenerator> splits(long streamSize); | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link SplittableGenerator} | |
| * interface. | |
| * | |
| * @param source a {@link SplittableGenerator} instance to be used instead | |
| * of this one as a source of pseudorandom bits used to | |
| * initialize the state of the new ones. | |
| * | |
| * @return a stream of {@link SplittableGenerator} objects | |
| * | |
| * @implNote It is permitted to implement this method in a manner | |
| * equivalent to {@link SplittableGenerator#splits(long, SplittableGenerator) splits} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}, source). | |
| * | |
| * @throws NullPointerException if source is null | |
| */ | |
| Stream<SplittableGenerator> splits(SplittableGenerator source); | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link SplittableGenerator} interface. | |
| * | |
| * @param streamSize the number of values to generate | |
| * @param source a {@link SplittableGenerator} instance to be used instead | |
| * of this one as a source of pseudorandom bits used to | |
| * initialize the state of the new ones. | |
| * | |
| * @return a stream of {@link SplittableGenerator} objects | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * @throws NullPointerException if source is null | |
| */ | |
| Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source); | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link RandomGenerator} | |
| * interface. Ideally the generators in the stream will appear to be | |
| * statistically independent. | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @implSpec The default implementation calls {@link SplittableGenerator#splits() splits}(). | |
| */ | |
| default Stream<RandomGenerator> rngs() { | |
| return this.splits().map(x -> x); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link RandomGenerator} interface. Ideally the generators in the | |
| * stream will appear to be statistically independent. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is | |
| * less than zero | |
| * | |
| * @implSpec The default implementation calls {@link SplittableGenerator#splits(long) splits}(streamSize). | |
| */ | |
| default Stream<RandomGenerator> rngs(long streamSize) { | |
| return this.splits(streamSize).map(x -> x); | |
| } | |
| } | |
| /** | |
| * This interface is designed to provide a common protocol for objects that | |
| * generate pseudorandom values and can easily <i>jump</i> forward, by a | |
| * moderate amount (ex. 2<sup>64</sup>) to a distant point in the state cycle. | |
| * | |
| * <p> Ideally, all {@link JumpableGenerator} objects produced by iterative | |
| * jumping from a single original {@link JumpableGenerator} object are | |
| * statistically independent of one another and individually uniform. In | |
| * practice, one must settle for some approximation to independence and | |
| * uniformity. In particular, a specific implementation may assume that each | |
| * generator in a stream produced by the | |
| * {@link JumpableGenerator#jump jump()} method is used to produce a number | |
| * of values no larger than either 2<sup>64</sup> or the square root of its | |
| * period. Implementors are advised to use algorithms whose period is at | |
| * least 2<sup>127</sup>. | |
| * | |
| * <p> Methods are provided to perform a single jump operation and also to | |
| * produce a stream of generators produced from the original by iterative | |
| * copying and jumping of internal state. A typical strategy for a | |
| * multithreaded application is to create a single {@link JumpableGenerator} | |
| * object, calls its {@link JumpableGenerator#jump jump}() method exactly | |
| * once, and then parcel out generators from the resulting stream, one to | |
| * each thread. It is generally not a good idea to call | |
| * {@link JumpableGenerator#jump jump}() on a generator that was itself | |
| * produced by the {@link JumpableGenerator#jump jump}() method, because the | |
| * result may be a generator identical to another generator already produce | |
| * by that call to the {@link JumpableGenerator#jump jump}() method. For | |
| * this reason, the return type of the {@link JumpableGenerator#jumps jumps}() | |
| * method is {@link Stream<RandomGenerator>} rather than | |
| * {@link Stream<JumpableGenerator>}, even though the actual generator | |
| * objects in that stream likely do also implement the | |
| * {@link JumpableGenerator} interface. | |
| * | |
| * <p> Objects that implement {@link JumpableGenerator} are typically not | |
| * cryptographically secure. Consider instead using {@link SecureRandom} to | |
| * get a cryptographically secure pseudo-random number generator for use by | |
| * security-sensitive applications. | |
| */ | |
| interface JumpableGenerator extends StreamableGenerator { | |
| /** | |
| * Returns an instance of {@link JumpableGenerator} that utilizes the | |
| * {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link JumpableGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static JumpableGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, JumpableGenerator.class); | |
| } | |
| /** | |
| * Returns a new generator whose internal state is an exact copy of this | |
| * generator (therefore their future behavior should be identical if | |
| * subjected to the same series of operations). | |
| * | |
| * @return a new object that is a copy of this generator | |
| */ | |
| JumpableGenerator copy(); | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to jump | |
| * forward a large, fixed distance (typically 2<sup>64</sup> or more) | |
| * within its state cycle. | |
| */ | |
| void jump(); | |
| /** | |
| * Returns the distance by which the | |
| * {@link JumpableGenerator#jump jump}() method will jump forward within | |
| * the state cycle of this generator object. | |
| * | |
| * @return the default jump distance (as a {@code double} value) | |
| */ | |
| double jumpDistance(); | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link RandomGenerator} | |
| * interface. | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link JumpableGenerator#jumps(long) jumps} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link JumpableGenerator#copy copy}() and {@link JumpableGenerator#jump jump}() | |
| * on this generator, and the copies become the generators produced by the stream. | |
| */ | |
| default Stream<RandomGenerator> jumps() { | |
| return Stream.generate(this::copyAndJump).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link RandomGenerator} interface. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is less than zero | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link JumpableGenerator#copy copy}() and {@link JumpableGenerator#jump jump}() | |
| * on this generator, and the copies become the generators produced by the stream. | |
| */ | |
| default Stream<RandomGenerator> jumps(long streamSize) { | |
| return jumps().limit(streamSize); | |
| } | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link RandomGenerator} | |
| * interface. Ideally the generators in the stream will appear to be | |
| * statistically independent. | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @implSpec The default implementation calls {@link JumpableGenerator#jumps jumps}(). | |
| */ | |
| default Stream<RandomGenerator> rngs() { | |
| return this.jumps(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link RandomGenerator} interface. Ideally the generators in the | |
| * stream will appear to be statistically independent. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is less than zero | |
| * | |
| * @implSpec The default implementation calls {@link JumpableGenerator#jumps(long) jumps}(streamSize). | |
| */ | |
| default Stream<RandomGenerator> rngs(long streamSize) { | |
| return this.jumps(streamSize); | |
| } | |
| /** | |
| * Copy this generator, jump this generator forward, then return the | |
| * copy. | |
| * | |
| * @return a copy of this generator object before the jump occurred | |
| * | |
| * @implSpec The default implementation copies this, jumps and then | |
| * returns the copy. | |
| */ | |
| default RandomGenerator copyAndJump() { | |
| RandomGenerator result = copy(); | |
| jump(); | |
| return result; | |
| } | |
| } | |
| /** | |
| * This interface is designed to provide a common protocol for objects that | |
| * generate sequences of pseudorandom values and can easily not only jump | |
| * but also <i>leap</i> forward, by a large amount (ex. 2<sup>128</sup>), to | |
| * a very distant point in the state cycle. | |
| * | |
| * Typically one will construct a series of {@link LeapableGenerator} | |
| * objects by iterative leaping from a single original | |
| * {@link LeapableGenerator} object, and then for each such object produce a | |
| * subseries of objects by iterative jumping. There is little conceptual | |
| * difference between leaping and jumping, but typically a leap will be a | |
| * very long jump in the state cycle (perhaps distance 2<sup>128</sup> or | |
| * so). | |
| * | |
| * <p> Ideally, all {@link LeapableGenerator} objects produced by iterative | |
| * leaping and jumping from a single original {@link LeapableGenerator} | |
| * object are statistically independent of one another and individually | |
| * uniform. In practice, one must settle for some approximation to | |
| * independence and uniformity. In particular, a specific implementation may | |
| * assume that each generator in a stream produced by the {@code leaps} | |
| * method is used to produce (by jumping) a number of objects no larger than | |
| * 2<sup>64</sup>. Implementors are advised to use algorithms whose period | |
| * is at least 2<sup>191</sup>. | |
| * | |
| * <p> Methods are provided to perform a single leap operation and also to | |
| * produce a stream of generators produced from the original by iterative | |
| * copying and leaping of internal state. The generators produced must | |
| * implement the {@link JumpableGenerator} interface but need not also | |
| * implement the {@link LeapableGenerator} interface. A typical strategy for | |
| * a multithreaded application is to create a single | |
| * {@link LeapableGenerator} object, calls its {@code leaps} method exactly | |
| * once, and then parcel out generators from the resulting stream, one to | |
| * each thread. Then the {@link JumpableGenerator#jump() jump}() method of | |
| * each such generator be called to produce a substream of generator | |
| * objects. | |
| * | |
| * <p> Objects that implement {@link LeapableGenerator} are typically not | |
| * cryptographically secure. Consider instead using {@link SecureRandom} to | |
| * get a cryptographically secure pseudo-random number generator for use by | |
| * security-sensitive applications. | |
| */ | |
| interface LeapableGenerator extends JumpableGenerator { | |
| /** | |
| * Returns an instance of {@link LeapableGenerator} that utilizes the | |
| * {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link LeapableGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static LeapableGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, LeapableGenerator.class); | |
| } | |
| /** | |
| * Returns a new generator whose internal state is an exact copy of this | |
| * generator (therefore their future behavior should be identical if | |
| * subjected to the same series of operations). | |
| * | |
| * @return a new object that is a copy of this generator | |
| */ | |
| LeapableGenerator copy(); | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to leap | |
| * forward a large, fixed distance (typically 2<sup>96</sup> or more) | |
| * within its state cycle. | |
| */ | |
| void leap(); | |
| /** | |
| * Returns the distance by which the | |
| * {@link LeapableGenerator#leap() leap}() method will leap forward within | |
| * the state cycle of this generator object. | |
| * | |
| * @return the default leap distance (as a {@code double} value) | |
| */ | |
| double leapDistance(); | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the {@link JumpableGenerator} | |
| * interface. | |
| * | |
| * @return a stream of objects that implement the {@link JumpableGenerator} interface | |
| * | |
| * @implNote It is permitted to implement this method in a manner equivalent to | |
| * {@link LeapableGenerator#leaps(long) leaps} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link LeapableGenerator#copy() copy}() and {@link LeapableGenerator#leap() leap}() | |
| * on this generator, and the copies become the generators produced by the stream. | |
| */ | |
| default Stream<JumpableGenerator> leaps() { | |
| return Stream.generate(this::copyAndLeap).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link JumpableGenerator} interface. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * | |
| * @return a stream of objects that implement the {@link JumpableGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is less than zero | |
| * | |
| * @implSpec The default implementation produces a sequential stream that repeatedly | |
| * calls {@link LeapableGenerator#copy() copy}() and {@link LeapableGenerator#leap() leap}() | |
| * on this generator, and the copies become the generators produced by the stream. | |
| */ | |
| default Stream<JumpableGenerator> leaps(long streamSize) { | |
| return leaps().limit(streamSize); | |
| } | |
| /** | |
| * Copy this generator, leap this generator forward, then return the | |
| * copy. | |
| * | |
| * @return a copy of this generator object before the leap occurred | |
| * | |
| * @implSpec The default implementation copies this, leaps and then | |
| * returns the copy. | |
| */ | |
| default JumpableGenerator copyAndLeap() { | |
| JumpableGenerator result = copy(); | |
| leap(); | |
| return result; | |
| } | |
| } | |
| /** | |
| * This interface is designed to provide a common protocol for objects that | |
| * generate sequences of pseudorandom values and can easily <i>jump</i> | |
| * forward, by an arbitrary amount, to a distant point in the state cycle. | |
| * | |
| * <p> Ideally, all {@link ArbitrarilyJumpableGenerator} objects produced by | |
| * iterative jumping from a single original | |
| * {@link ArbitrarilyJumpableGenerator} object are statistically independent | |
| * of one another and individually uniform, provided that they do not | |
| * traverse overlapping portions of the state cycle. In practice, one must | |
| * settle for some approximation to independence and uniformity. In | |
| * particular, a specific implementation may assume that each generator in a | |
| * stream produced by the {@link JumpableGenerator#jump() jump}() method is | |
| * used to produce a number of values no larger than the jump distance | |
| * specified. Implementors are advised to use algorithms whose period is at | |
| * least 2<sup>127</sup>. | |
| * | |
| * <p> For many applications, it suffices to jump forward by a power of two | |
| * or some small multiple of a power of two, but this power of two may not | |
| * be representable as a {@code long} value. To avoid the use of | |
| * {@link BigInteger} values as jump distances, {@code double} values are | |
| * used instead. | |
| * | |
| * <p> Methods are provided to perform a single jump operation and also to | |
| * produce a stream of generators produced from the original by iterative | |
| * copying and jumping of internal state. A typical strategy for a | |
| * multithreaded application is to create a single | |
| * {@link ArbitrarilyJumpableGenerator} object, call its | |
| * {@link JumpableGenerator#jump() jump}() method exactly once, and then | |
| * parcel out generators from the resulting stream, one to each thread. | |
| * However, each generator produced also has type | |
| * {@link ArbitrarilyJumpableGenerator}; with care, different jump distances | |
| * can be used to traverse the entire state cycle in various ways. | |
| * | |
| * <p> Objects that implement {@link ArbitrarilyJumpableGenerator} are | |
| * typically not cryptographically secure. Consider instead using | |
| * {@link SecureRandom} to get a cryptographically secure pseudo-random | |
| * number generator for use by security-sensitive applications. | |
| */ | |
| interface ArbitrarilyJumpableGenerator extends LeapableGenerator { | |
| /** | |
| * Returns an instance of {@link ArbitrarilyJumpableGenerator} that | |
| * utilizes the {@code name} <a href="package-summary.html#algorithms">algorithm</a>. | |
| * | |
| * @param name Name of random number generator | |
| * <a href="package-summary.html#algorithms">algorithm</a> | |
| * | |
| * @return An instance of {@link ArbitrarilyJumpableGenerator} | |
| * | |
| * @throws NullPointerException if name is null | |
| * @throws IllegalArgumentException if the named algorithm is not found | |
| */ | |
| static ArbitrarilyJumpableGenerator of(String name) { | |
| Objects.requireNonNull(name); | |
| return RandomGeneratorFactory.of(name, ArbitrarilyJumpableGenerator.class); | |
| } | |
| /** | |
| * Returns a new generator whose internal state is an exact copy of this | |
| * generator (therefore their future behavior should be identical if | |
| * subjected to the same series of operations). | |
| * | |
| * @return a new object that is a copy of this generator | |
| */ | |
| ArbitrarilyJumpableGenerator copy(); | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to jump | |
| * forward a distance equal to 2<sup>{@code logDistance}</sup> within | |
| * its state cycle. | |
| * | |
| * @param logDistance the base-2 logarithm of the distance to jump forward within the state | |
| * cycle | |
| * | |
| * @throws IllegalArgumentException if {@code logDistance} is | |
| * 2<sup>{@code logDistance}</sup> is | |
| * greater than the period of this generator | |
| */ | |
| void jumpPowerOfTwo(int logDistance); | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to jump | |
| * forward a specified distance within its state cycle. | |
| * | |
| * @param distance the distance to jump forward within the state cycle | |
| * | |
| * @throws IllegalArgumentException if {@code distance} is not greater than | |
| * or equal to 0.0, or is greater than the | |
| * period of this generator | |
| */ | |
| void jump(double distance); | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to jump | |
| * forward a large, fixed distance (typically 2<sup>64</sup> or more) | |
| * within its state cycle. The distance used is that returned by method | |
| * {@link ArbitrarilyJumpableGenerator#jumpDistance() jumpDistance}(). | |
| * | |
| * @implSpec The default implementation invokes jump(jumpDistance()). | |
| */ | |
| default void jump() { jump(jumpDistance()); } | |
| /** | |
| * Returns an effectively unlimited stream of new pseudorandom number | |
| * generators, each of which implements the | |
| * {@link ArbitrarilyJumpableGenerator} interface, produced by jumping | |
| * copies of this generator by different integer multiples of the | |
| * specified jump distance. | |
| * | |
| * @param distance a distance to jump forward within the state cycle | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code distance} is not greater than | |
| * or equal to 0.0, or is greater than the | |
| * period of this generator | |
| * | |
| * @implSpec The default implementation is equivalent to | |
| * {@link ArbitrarilyJumpableGenerator#jumps(long) jumps} | |
| * ({@link Long#MAX_VALUE Long.MAX_VALUE}). | |
| */ | |
| default Stream<ArbitrarilyJumpableGenerator> jumps(double distance) { | |
| return Stream.generate(() -> copyAndJump(distance)).sequential(); | |
| } | |
| /** | |
| * Returns a stream producing the given {@code streamSize} number of new | |
| * pseudorandom number generators, each of which implements the | |
| * {@link ArbitrarilyJumpableGenerator} interface, produced by jumping | |
| * copies of this generator by different integer multiples of the | |
| * specified jump distance. | |
| * | |
| * @param streamSize the number of generators to generate | |
| * @param distance a distance to jump forward within the state cycle | |
| * | |
| * @return a stream of objects that implement the {@link RandomGenerator} interface | |
| * | |
| * @throws IllegalArgumentException if {@code streamSize} is less than zero or if | |
| * {@code distance} is not greater than | |
| * or equal to 0.0, or is greater than the | |
| * period of this generator | |
| * | |
| * @implSpec The default implementation is equivalent to | |
| * jumps(distance).limit(streamSize). | |
| */ | |
| default Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) { | |
| return jumps(distance).limit(streamSize); | |
| } | |
| /** | |
| * Alter the state of this pseudorandom number generator so as to jump | |
| * forward a very large, fixed distance (typically 2<sup>128</sup> or | |
| * more) within its state cycle. The distance used is that returned by | |
| * method | |
| * {@link ArbitrarilyJumpableGenerator#leapDistance() leapDistance}(). | |
| */ | |
| default void leap() { jump(leapDistance()); } | |
| /** | |
| * Copy this generator, jump this generator forward, then return the | |
| * copy. | |
| * | |
| * @param distance a distance to jump forward within the state cycle | |
| * | |
| * @return a copy of this generator object before the jump occurred | |
| * | |
| * @throws IllegalArgumentException if {@code distance} is not greater than | |
| * or equal to 0.0, or is greater than the | |
| * period of this generator | |
| * | |
| * @implSpec The default implementation copies this, jumps(distance) and then | |
| * returns the copy. | |
| */ | |
| default ArbitrarilyJumpableGenerator copyAndJump(double distance) { | |
| ArbitrarilyJumpableGenerator result = copy(); | |
| jump(distance); | |
| return result; | |
| } | |
| } | |
| } |