59088
|
1 |
/*
|
|
2 |
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation. Oracle designates this
|
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
|
9 |
* by Oracle in the LICENSE file that accompanied this code.
|
|
10 |
*
|
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
15 |
* accompanied this code).
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License version
|
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
20 |
*
|
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
22 |
* or visit www.oracle.com if you need additional information or have any
|
|
23 |
* questions.
|
|
24 |
*/
|
|
25 |
|
|
26 |
package java.util.random;
|
|
27 |
|
|
28 |
import java.math.BigInteger;
|
|
29 |
import java.util.Objects;
|
|
30 |
import java.util.stream.DoubleStream;
|
|
31 |
import java.util.stream.IntStream;
|
|
32 |
import java.util.stream.LongStream;
|
|
33 |
import java.util.stream.Stream;
|
|
34 |
|
|
35 |
/**
|
|
36 |
* The {@link RandomGenerator} interface is designed to provide a common protocol for objects that
|
|
37 |
* generate random or (more typically) pseudorandom sequences of numbers (or Boolean values).
|
|
38 |
* Such a sequence may be obtained by either repeatedly invoking a method that returns a single
|
|
39 |
* (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly
|
|
40 |
* chosen values.
|
|
41 |
* <p>
|
|
42 |
* Ideally, given an implicitly or explicitly specified range of values, each value would be chosen
|
|
43 |
* independently and uniformly from that range. In practice, one may have to settle for some
|
|
44 |
* approximation to independence and uniformity.
|
|
45 |
* <p>
|
|
46 |
* In the case of {@code int}, {@code long}, and {@link Boolean} values, if there is no explicit
|
|
47 |
* specification of range, then the range includes all possible values of the type. In the case of
|
|
48 |
* {@code float} and {@code double} values, a value is always chosen from the set of
|
|
49 |
* 2<sup><i>w</i></sup> values between 0.0 (inclusive) and 1.0 (exclusive), where <i>w</i> is 23 for
|
|
50 |
* {@code float} values and 52 for {@code double} values, such that adjacent values differ by
|
|
51 |
* 2<sup>−<i>w</i></sup>; if an explicit range is specified, then the chosen number is
|
|
52 |
* computationally scaled and translated so as to appear to have been chosen from that range.
|
|
53 |
* <p>
|
|
54 |
* Each method that returns a stream produces a stream of values each of which is chosen in the same
|
|
55 |
* manner as for a method that returns a single (pseudo)randomly chosen value. For example, if
|
|
56 |
* {@code r} implements {@link RandomGenerator}, then the method call {@code r.ints(100)} returns a
|
|
57 |
* stream of 100 {@code int} values. These are not necessarily the exact same values that would
|
|
58 |
* have been returned if instead {@code r.nextInt()} had been called 100 times; all that is
|
|
59 |
* guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the
|
|
60 |
* same range.
|
|
61 |
* <p>
|
|
62 |
* Every object that implements the {@link RandomNumberGenerator} interface by using a
|
|
63 |
* pseudorandom algorithm is assumed to contain a finite amount of state. Using such an object to
|
|
64 |
* generate a pseudorandomly chosen value alters its state by computing a new state as a function
|
|
65 |
* of the current state, without reference to any information other than the current state.
|
|
66 |
* The number of distinct possible states of such an object is called its <i>period</i>.
|
|
67 |
* (Some implementations of the {@link RandomNumberGenerator} interface may be truly random
|
|
68 |
* rather than pseudorandom, for example relying on the statistical behavior of a physical
|
|
69 |
* object to derive chosen values. Such implementations do not have a fixed period.)
|
|
70 |
* <p>
|
|
71 |
* As a rule, objects that implement the {@link RandomGenerator} interface need not be thread-safe.
|
|
72 |
* It is recommended that multithreaded applications use either {@link ThreadLocalRandom} or
|
|
73 |
* (preferably) pseudorandom number generators that implement the {@link SplittableGenerator} or
|
|
74 |
* {@link JumpableGenerator} interface.
|
|
75 |
* <p>
|
|
76 |
* To implement this interface, a class only needs to provide concrete definitions for the methods
|
|
77 |
* {@code nextLong()} and {@code period()}. Default implementations are provided for all other
|
|
78 |
* methods (but it may be desirable to override some of them, especially {@code nextInt()} if the
|
|
79 |
* underlying algorithm is {@code int}-based). Moreover, it may be preferable instead to implement
|
|
80 |
* a more specialized interface such as {@link JumpableGenerator} or {@link LeapableGenerator},
|
|
81 |
* or to extend an abstract implementation-support class such as {@link AbstractSplittableGenerator}
|
|
82 |
* or {@link AbstractArbitrarilyJumpableGenerator}.
|
|
83 |
* <p>
|
|
84 |
* Objects that implement {@link RandomGenerator} are typically not cryptographically secure.
|
|
85 |
* Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
|
|
86 |
* pseudorandom number generator for use by security-sensitive applications. Note, however, that
|
|
87 |
* {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so that
|
|
88 |
* instances of {@code java.security.SecureRandom} may be used interchangeably with other types of
|
|
89 |
* pseudorandom generators in applications that do not require a secure generator.
|
|
90 |
*
|
|
91 |
* @since 14
|
|
92 |
*/
|
|
93 |
public interface RandomGenerator {
|
|
94 |
|
|
95 |
/**
|
|
96 |
* Supported random number Algorithms.
|
|
97 |
*/
|
|
98 |
public enum Algorithm {
|
|
99 |
/**
|
|
100 |
* L64X128MixRandom algorithm
|
|
101 |
*/
|
|
102 |
L64X128MixRandom("L64X128MixRandom"),
|
|
103 |
/**
|
|
104 |
* L64X256MixRandom algorithm
|
|
105 |
*/
|
|
106 |
L64X256MixRandom("L64X256MixRandom"),
|
|
107 |
/**
|
|
108 |
* L64X1024MixRandom algorithm
|
|
109 |
*/
|
|
110 |
L64X1024MixRandom("L64X1024MixRandom"),
|
|
111 |
/**
|
|
112 |
* L128X256MixRandom algorithm
|
|
113 |
*/
|
|
114 |
L128X256MixRandom("L128X256MixRandom"),
|
|
115 |
/**
|
|
116 |
* MRG32k3a algorithm
|
|
117 |
*/
|
|
118 |
MRG32k3a("MRG32k3a"),
|
|
119 |
/**
|
|
120 |
* Legacy Random algorithm
|
|
121 |
*/
|
|
122 |
@Deprecated
|
|
123 |
Random("Random"),
|
|
124 |
/**
|
|
125 |
* Legacy SecureRandom algorithm
|
|
126 |
*/
|
|
127 |
@Deprecated
|
|
128 |
SecureRandom("SecureRandom"),
|
|
129 |
/**
|
|
130 |
* Xoroshiro128StarStar algorithm
|
|
131 |
*/
|
|
132 |
Xoroshiro128StarStar("Xoroshiro128StarStar"),
|
|
133 |
/**
|
|
134 |
* Xoshiro256StarStar algorithm
|
|
135 |
*/
|
|
136 |
Xoshiro256StarStar("Xoshiro256StarStar");
|
|
137 |
|
|
138 |
private String name;
|
|
139 |
|
|
140 |
private Algorithm(String name) {
|
|
141 |
this.name = name;
|
|
142 |
}
|
|
143 |
|
|
144 |
public String toString() {
|
|
145 |
return name;
|
|
146 |
}
|
|
147 |
|
|
148 |
/**
|
|
149 |
* Returns an instance of {@link RandomGenerator} that utilizes this algorithm.
|
|
150 |
*
|
|
151 |
* @return An instance of {@link RandomGenerator}
|
|
152 |
*/
|
|
153 |
public RandomGenerator instance() {
|
|
154 |
return RandomGeneratorFactory.of(name, RandomGenerator.class);
|
|
155 |
}
|
|
156 |
|
|
157 |
/**
|
|
158 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
159 |
* of {@link RandomGenerator} that utilizes this algorithm.
|
|
160 |
*
|
|
161 |
* @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
|
|
162 |
*/
|
|
163 |
public RandomGeneratorFactory<RandomGenerator> factory() {
|
|
164 |
return RandomGeneratorFactory.factoryOf(name, RandomGenerator.class);
|
|
165 |
}
|
|
166 |
}
|
|
167 |
|
|
168 |
/**
|
|
169 |
* Returns an instance of {@link RandomGenerator} that utilizes the
|
|
170 |
* {@code name} algorithm.
|
|
171 |
*
|
|
172 |
* @param name Name of random number generator algorithm
|
|
173 |
*
|
|
174 |
* @return An instance of {@link RandomGenerator}
|
|
175 |
*/
|
|
176 |
public static RandomGenerator of(String name) {
|
|
177 |
Objects.requireNonNull(name);
|
|
178 |
return RandomGeneratorFactory.of(name, RandomGenerator.class);
|
|
179 |
}
|
|
180 |
|
|
181 |
/**
|
|
182 |
* Returns an instance of {@link RandomGenerator} that utilizes the
|
|
183 |
* specified {@code algorithm}.
|
|
184 |
*
|
|
185 |
* @param algorithm Random number generator algorithm
|
|
186 |
*
|
|
187 |
* @return An instance of {@link RandomGenerator}
|
|
188 |
*/
|
|
189 |
public static RandomGenerator of(Algorithm algorithm) {
|
|
190 |
Objects.requireNonNull(algorithm);
|
|
191 |
return RandomGeneratorFactory.of(algorithm.toString(), RandomGenerator.class);
|
|
192 |
}
|
|
193 |
|
|
194 |
/**
|
|
195 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
196 |
* of {@link RandomGenerator} that utilizes the {@code name} algorithm.
|
|
197 |
*
|
|
198 |
* @param name Name of random number generator algorithm
|
|
199 |
*
|
|
200 |
* @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
|
|
201 |
*/
|
|
202 |
public static RandomGeneratorFactory<RandomGenerator> factoryOf(String name) {
|
|
203 |
Objects.requireNonNull(name);
|
|
204 |
return RandomGeneratorFactory.factoryOf(name, RandomGenerator.class);
|
|
205 |
}
|
|
206 |
|
|
207 |
/**
|
|
208 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
209 |
* of {@link RandomGenerator} that utilizes the specified {@code algorithm}.
|
|
210 |
*
|
|
211 |
* @param algorithm Random number generator algorithm
|
|
212 |
*
|
|
213 |
* @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
|
|
214 |
*/
|
|
215 |
public static RandomGeneratorFactory<RandomGenerator> factoryOf(Algorithm algorithm) {
|
|
216 |
Objects.requireNonNull(algorithm);
|
|
217 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), RandomGenerator.class);
|
|
218 |
}
|
|
219 |
|
|
220 |
/**
|
|
221 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
222 |
* {@code double} values.
|
|
223 |
*
|
|
224 |
* @return a stream of pseudorandomly chosen {@code double} values
|
|
225 |
*
|
|
226 |
* @implNote It is permitted to implement this method in a manner
|
|
227 |
* equivalent to {@code doubles(Long.MAX_VALUE)}.
|
|
228 |
*
|
|
229 |
* @implNote The default implementation produces a sequential stream
|
|
230 |
* that repeatedly calls {@code nextDouble()}.
|
|
231 |
*/
|
|
232 |
default DoubleStream doubles() {
|
|
233 |
return DoubleStream.generate(this::nextDouble).sequential();
|
|
234 |
}
|
|
235 |
|
|
236 |
/**
|
|
237 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
238 |
* {@code double} values, where each value is between the specified
|
|
239 |
* origin (inclusive) and the specified bound (exclusive).
|
|
240 |
*
|
|
241 |
* @param randomNumberOrigin the least value that can be produced
|
|
242 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
243 |
*
|
|
244 |
* @return a stream of pseudorandomly chosen {@code double} values, each between
|
|
245 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
246 |
*
|
|
247 |
* @throws IllegalArgumentException if {@code randomNumberOrigin} is not finite,
|
|
248 |
* or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin}
|
|
249 |
* is greater than or equal to {@code randomNumberBound}
|
|
250 |
*
|
|
251 |
* @implNote It is permitted to implement this method in a manner equivalent to
|
|
252 |
* {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
|
253 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
254 |
* calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
|
|
255 |
*/
|
|
256 |
default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
|
|
257 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
258 |
return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential();
|
|
259 |
}
|
|
260 |
|
|
261 |
/**
|
|
262 |
* Returns a stream producing the given {@code streamSize} number of
|
|
263 |
* pseudorandomly chosen {@code double} values.
|
|
264 |
*
|
|
265 |
* @param streamSize the number of values to generate
|
|
266 |
*
|
|
267 |
* @return a stream of pseudorandomly chosen {@code double} values
|
|
268 |
*
|
|
269 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
270 |
* less than zero
|
|
271 |
*
|
|
272 |
* @implNote The default implementation produces a sequential stream
|
|
273 |
* that repeatedly calls {@code nextDouble()}.
|
|
274 |
*/
|
|
275 |
default DoubleStream doubles(long streamSize) {
|
|
276 |
RandomSupport.checkStreamSize(streamSize);
|
|
277 |
return doubles().limit(streamSize);
|
|
278 |
}
|
|
279 |
|
|
280 |
/**
|
|
281 |
* Returns a stream producing the given {@code streamSize} number of
|
|
282 |
* pseudorandomly chosen {@code double} values, where each value is between
|
|
283 |
* the specified origin (inclusive) and the specified bound (exclusive).
|
|
284 |
*
|
|
285 |
* @param streamSize the number of values to generate
|
|
286 |
* @param randomNumberOrigin the least value that can be produced
|
|
287 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
288 |
*
|
|
289 |
* @return a stream of pseudorandomly chosen {@code double} values, each between
|
|
290 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
291 |
*
|
|
292 |
* @throws IllegalArgumentException if {@code streamSize} is less than zero,
|
|
293 |
* or {@code randomNumberOrigin} is not finite,
|
|
294 |
* or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin}
|
|
295 |
* is greater than or equal to {@code randomNumberBound}
|
|
296 |
*
|
|
297 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
298 |
* calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
|
|
299 |
*/
|
|
300 |
default DoubleStream doubles(long streamSize, double randomNumberOrigin,
|
|
301 |
double randomNumberBound) {
|
|
302 |
RandomSupport.checkStreamSize(streamSize);
|
|
303 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
304 |
return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize);
|
|
305 |
}
|
|
306 |
|
|
307 |
/**
|
|
308 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
309 |
* {@code int} values.
|
|
310 |
*
|
|
311 |
* @return a stream of pseudorandomly chosen {@code int} values
|
|
312 |
*
|
|
313 |
* @implNote It is permitted to implement this method in a manner
|
|
314 |
* equivalent to {@code ints(Long.MAX_VALUE)}.
|
|
315 |
* @implNote The default implementation produces a sequential stream
|
|
316 |
* that repeatedly calls {@code nextInt()}.
|
|
317 |
*/
|
|
318 |
default IntStream ints() {
|
|
319 |
return IntStream.generate(this::nextInt).sequential();
|
|
320 |
}
|
|
321 |
|
|
322 |
/**
|
|
323 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
324 |
* {@code int} values, where each value is between the specified
|
|
325 |
* origin (inclusive) and the specified bound (exclusive).
|
|
326 |
*
|
|
327 |
* @param randomNumberOrigin the least value that can be produced
|
|
328 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
329 |
*
|
|
330 |
* @return a stream of pseudorandomly chosen {@code int} values, each between
|
|
331 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
332 |
*
|
|
333 |
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
|
334 |
* is greater than or equal to {@code randomNumberBound}
|
|
335 |
*
|
|
336 |
* @implNote It is permitted to implement this method in a manner equivalent to
|
|
337 |
* {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
|
338 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
339 |
* calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
|
|
340 |
*/
|
|
341 |
default IntStream ints(int randomNumberOrigin, int randomNumberBound) {
|
|
342 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
343 |
return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential();
|
|
344 |
}
|
|
345 |
|
|
346 |
/**
|
|
347 |
* Returns a stream producing the given {@code streamSize} number of
|
|
348 |
* pseudorandomly chosen {@code int} values.
|
|
349 |
*
|
|
350 |
* @param streamSize the number of values to generate
|
|
351 |
*
|
|
352 |
* @return a stream of pseudorandomly chosen {@code int} values
|
|
353 |
*
|
|
354 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
355 |
* less than zero
|
|
356 |
*
|
|
357 |
* @implNote The default implementation produces a sequential stream
|
|
358 |
* that repeatedly calls {@code nextInt()}.
|
|
359 |
*/
|
|
360 |
default IntStream ints(long streamSize) {
|
|
361 |
RandomSupport.checkStreamSize(streamSize);
|
|
362 |
return ints().limit(streamSize);
|
|
363 |
}
|
|
364 |
|
|
365 |
/**
|
|
366 |
* Returns a stream producing the given {@code streamSize} number of
|
|
367 |
* pseudorandomly chosen {@code int} values, where each value is between
|
|
368 |
* the specified origin (inclusive) and the specified bound (exclusive).
|
|
369 |
*
|
|
370 |
* @param streamSize the number of values to generate
|
|
371 |
* @param randomNumberOrigin the least value that can be produced
|
|
372 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
373 |
*
|
|
374 |
* @return a stream of pseudorandomly chosen {@code int} values, each between
|
|
375 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
376 |
*
|
|
377 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
378 |
* less than zero, or {@code randomNumberOrigin}
|
|
379 |
* is greater than or equal to {@code randomNumberBound}
|
|
380 |
*
|
|
381 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
382 |
* calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
|
|
383 |
*/
|
|
384 |
default IntStream ints(long streamSize, int randomNumberOrigin,
|
|
385 |
int randomNumberBound) {
|
|
386 |
RandomSupport.checkStreamSize(streamSize);
|
|
387 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
388 |
return ints(randomNumberOrigin, randomNumberBound).limit(streamSize);
|
|
389 |
}
|
|
390 |
|
|
391 |
/**
|
|
392 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
393 |
* {@code long} values.
|
|
394 |
*
|
|
395 |
* @return a stream of pseudorandomly chosen {@code long} values
|
|
396 |
*
|
|
397 |
* @implNote It is permitted to implement this method in a manner
|
|
398 |
* equivalent to {@code longs(Long.MAX_VALUE)}.
|
|
399 |
* @implNote The default implementation produces a sequential stream
|
|
400 |
* that repeatedly calls {@code nextLong()}.
|
|
401 |
*/
|
|
402 |
default LongStream longs() {
|
|
403 |
return LongStream.generate(this::nextLong).sequential();
|
|
404 |
}
|
|
405 |
|
|
406 |
/**
|
|
407 |
* Returns an effectively unlimited stream of pseudorandomly chosen
|
|
408 |
* {@code long} values, where each value is between the specified
|
|
409 |
* origin (inclusive) and the specified bound (exclusive).
|
|
410 |
*
|
|
411 |
* @param randomNumberOrigin the least value that can be produced
|
|
412 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
413 |
*
|
|
414 |
* @return a stream of pseudorandomly chosen {@code long} values, each between
|
|
415 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
416 |
*
|
|
417 |
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
|
418 |
* is greater than or equal to {@code randomNumberBound}
|
|
419 |
*
|
|
420 |
* @implNote It is permitted to implement this method in a manner equivalent to
|
|
421 |
* {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
|
422 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
423 |
* calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
|
|
424 |
*/
|
|
425 |
default LongStream longs(long randomNumberOrigin, long randomNumberBound) {
|
|
426 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
427 |
return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential();
|
|
428 |
}
|
|
429 |
|
|
430 |
/**
|
|
431 |
* Returns a stream producing the given {@code streamSize} number of
|
|
432 |
* pseudorandomly chosen {@code long} values.
|
|
433 |
*
|
|
434 |
* @param streamSize the number of values to generate
|
|
435 |
*
|
|
436 |
* @return a stream of pseudorandomly chosen {@code long} values
|
|
437 |
*
|
|
438 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
439 |
* less than zero
|
|
440 |
*
|
|
441 |
* @implNote The default implementation produces a sequential stream
|
|
442 |
* that repeatedly calls {@code nextLong()}.
|
|
443 |
*/
|
|
444 |
default LongStream longs(long streamSize) {
|
|
445 |
RandomSupport.checkStreamSize(streamSize);
|
|
446 |
return longs().limit(streamSize);
|
|
447 |
}
|
|
448 |
|
|
449 |
/**
|
|
450 |
* Returns a stream producing the given {@code streamSize} number of
|
|
451 |
* pseudorandomly chosen {@code long} values, where each value is between
|
|
452 |
* the specified origin (inclusive) and the specified bound (exclusive).
|
|
453 |
*
|
|
454 |
* @param streamSize the number of values to generate
|
|
455 |
* @param randomNumberOrigin the least value that can be produced
|
|
456 |
* @param randomNumberBound the upper bound (exclusive) for each value produced
|
|
457 |
*
|
|
458 |
* @return a stream of pseudorandomly chosen {@code long} values, each between
|
|
459 |
* the specified origin (inclusive) and the specified bound (exclusive)
|
|
460 |
*
|
|
461 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
462 |
* less than zero, or {@code randomNumberOrigin}
|
|
463 |
* is greater than or equal to {@code randomNumberBound}
|
|
464 |
*
|
|
465 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
466 |
* calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
|
|
467 |
*/
|
|
468 |
default LongStream longs(long streamSize, long randomNumberOrigin,
|
|
469 |
long randomNumberBound) {
|
|
470 |
RandomSupport.checkStreamSize(streamSize);
|
|
471 |
RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
|
|
472 |
return longs(randomNumberOrigin, randomNumberBound).limit(streamSize);
|
|
473 |
}
|
|
474 |
|
|
475 |
/**
|
|
476 |
* Returns a pseudorandomly chosen {@code boolean} value.
|
|
477 |
* <p>
|
|
478 |
* The default implementation tests the high-order bit (sign bit) of a value produced by
|
|
479 |
* {@code nextInt()}, on the grounds that some algorithms for pseudorandom number generation
|
|
480 |
* produce values whose high-order bits have better statistical quality than the low-order bits.
|
|
481 |
*
|
|
482 |
* @return a pseudorandomly chosen {@code boolean} value
|
|
483 |
*/
|
|
484 |
default boolean nextBoolean() {
|
|
485 |
return nextInt() < 0;
|
|
486 |
}
|
|
487 |
|
|
488 |
/**
|
|
489 |
* Returns a pseudorandom {@code float} value between zero (inclusive) and one (exclusive).
|
|
490 |
* <p>
|
|
491 |
* The default implementation uses the 24 high-order bits from a call to {@code nextInt()}.
|
|
492 |
*
|
|
493 |
* @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive)
|
|
494 |
*/
|
|
495 |
default float nextFloat() {
|
|
496 |
return (nextInt() >>> 8) * 0x1.0p-24f;
|
|
497 |
}
|
|
498 |
|
|
499 |
/**
|
|
500 |
* Returns a pseudorandomly chosen {@code float} value between zero
|
|
501 |
* (inclusive) and the specified bound (exclusive).
|
|
502 |
*
|
|
503 |
* @param bound the upper bound (exclusive) for the returned value.
|
|
504 |
* Must be positive and finite
|
|
505 |
*
|
|
506 |
* @return a pseudorandomly chosen {@code float} value between
|
|
507 |
* zero (inclusive) and the bound (exclusive)
|
|
508 |
*
|
|
509 |
* @throws IllegalArgumentException if {@code bound} is not
|
|
510 |
* both positive and finite
|
|
511 |
*
|
|
512 |
* @implNote The default implementation simply calls
|
|
513 |
* {@code RandomSupport.checkBound(bound)} and then
|
|
514 |
* {@code RandomSupport.boundedNextFloat(this, bound)}.
|
|
515 |
*/
|
|
516 |
default float nextFloat(float bound) {
|
|
517 |
RandomSupport.checkBound(bound);
|
|
518 |
return RandomSupport.boundedNextFloat(this, bound);
|
|
519 |
}
|
|
520 |
|
|
521 |
/**
|
|
522 |
* Returns a pseudorandomly chosen {@code float} value between the
|
|
523 |
* specified origin (inclusive) and the specified bound (exclusive).
|
|
524 |
*
|
|
525 |
* @param origin the least value that can be returned
|
|
526 |
* @param bound the upper bound (exclusive)
|
|
527 |
*
|
|
528 |
* @return a pseudorandomly chosen {@code float} value between the
|
|
529 |
* origin (inclusive) and the bound (exclusive)
|
|
530 |
*
|
|
531 |
* @throws IllegalArgumentException if {@code origin} is not finite,
|
|
532 |
* or {@code bound} is not finite, or {@code origin}
|
|
533 |
* is greater than or equal to {@code bound}
|
|
534 |
*
|
|
535 |
* @implNote The default implementation simply calls
|
|
536 |
* {@code RandomSupport.checkRange(origin, bound)} and then
|
|
537 |
* {@code RandomSupport.boundedNextFloat(this, origin, bound)}.
|
|
538 |
*/
|
|
539 |
default float nextFloat(float origin, float bound) {
|
|
540 |
RandomSupport.checkRange(origin, bound);
|
|
541 |
return RandomSupport.boundedNextFloat(this, origin, bound);
|
|
542 |
}
|
|
543 |
|
|
544 |
/**
|
|
545 |
* Returns a pseudorandom {@code double} value between zero (inclusive) and one (exclusive).
|
|
546 |
* <p>
|
|
547 |
* The default implementation uses the 53 high-order bits from a call to {@code nextLong()}.
|
|
548 |
*
|
|
549 |
* @return a pseudorandom {@code double} value between zero (inclusive) and one (exclusive)
|
|
550 |
*/
|
|
551 |
default double nextDouble() {
|
|
552 |
return (nextLong() >>> 11) * 0x1.0p-53;
|
|
553 |
}
|
|
554 |
|
|
555 |
/**
|
|
556 |
* Returns a pseudorandomly chosen {@code double} value between zero
|
|
557 |
* (inclusive) and the specified bound (exclusive).
|
|
558 |
*
|
|
559 |
* @param bound the upper bound (exclusive) for the returned value.
|
|
560 |
* Must be positive and finite
|
|
561 |
*
|
|
562 |
* @return a pseudorandomly chosen {@code double} value between
|
|
563 |
* zero (inclusive) and the bound (exclusive)
|
|
564 |
*
|
|
565 |
* @throws IllegalArgumentException if {@code bound} is not
|
|
566 |
* both positive and finite
|
|
567 |
*
|
|
568 |
* @implNote The default implementation simply calls
|
|
569 |
* {@code RandomSupport.checkBound(bound)} and then
|
|
570 |
* {@code RandomSupport.boundedNextDouble(this, bound)}.
|
|
571 |
*/
|
|
572 |
default double nextDouble(double bound) {
|
|
573 |
RandomSupport.checkBound(bound);
|
|
574 |
return RandomSupport.boundedNextDouble(this, bound);
|
|
575 |
}
|
|
576 |
|
|
577 |
/**
|
|
578 |
* Returns a pseudorandomly chosen {@code double} value between the
|
|
579 |
* specified origin (inclusive) and the specified bound (exclusive).
|
|
580 |
*
|
|
581 |
* @param origin the least value that can be returned
|
|
582 |
* @param bound the upper bound (exclusive) for the returned value
|
|
583 |
*
|
|
584 |
* @return a pseudorandomly chosen {@code double} value between the
|
|
585 |
* origin (inclusive) and the bound (exclusive)
|
|
586 |
*
|
|
587 |
* @throws IllegalArgumentException if {@code origin} is not finite,
|
|
588 |
* or {@code bound} is not finite, or {@code origin}
|
|
589 |
* is greater than or equal to {@code bound}
|
|
590 |
*
|
|
591 |
* @implNote The default implementation simply calls
|
|
592 |
* {@code RandomSupport.checkRange(origin, bound)} and then
|
|
593 |
* {@code RandomSupport.boundedNextDouble(this, origin, bound)}.
|
|
594 |
*/
|
|
595 |
default double nextDouble(double origin, double bound) {
|
|
596 |
RandomSupport.checkRange(origin, bound);
|
|
597 |
return RandomSupport.boundedNextDouble(this, origin, bound);
|
|
598 |
}
|
|
599 |
|
|
600 |
/**
|
|
601 |
* Returns a pseudorandomly chosen {@code int} value.
|
|
602 |
* <p>
|
|
603 |
* The default implementation uses the 32 high-order bits from a call to {@code nextLong()}.
|
|
604 |
*
|
|
605 |
* @return a pseudorandomly chosen {@code int} value
|
|
606 |
*/
|
|
607 |
default public int nextInt() {
|
|
608 |
return (int)(nextLong() >>> 32);
|
|
609 |
}
|
|
610 |
|
|
611 |
/**
|
|
612 |
* Returns a pseudorandomly chosen {@code int} value between
|
|
613 |
* zero (inclusive) and the specified bound (exclusive).
|
|
614 |
*
|
|
615 |
* @param bound the upper bound (exclusive) for the returned value. Must be positive.
|
|
616 |
*
|
|
617 |
* @return a pseudorandomly chosen {@code int} value between
|
|
618 |
* zero (inclusive) and the bound (exclusive)
|
|
619 |
*
|
|
620 |
* @throws IllegalArgumentException if {@code bound} is not positive
|
|
621 |
*
|
|
622 |
* @implNote The default implementation simply calls
|
|
623 |
* {@code RandomSupport.checkBound(bound)} and then
|
|
624 |
* {@code RandomSupport.boundedNextInt(this, bound)}.
|
|
625 |
*/
|
|
626 |
default int nextInt(int bound) {
|
|
627 |
RandomSupport.checkBound(bound);
|
|
628 |
return RandomSupport.boundedNextInt(this, bound);
|
|
629 |
}
|
|
630 |
|
|
631 |
/**
|
|
632 |
* Returns a pseudorandomly chosen {@code int} value between the
|
|
633 |
* specified origin (inclusive) and the specified bound (exclusive).
|
|
634 |
*
|
|
635 |
* @param origin the least value that can be returned
|
|
636 |
* @param bound the upper bound (exclusive) for the returned value
|
|
637 |
*
|
|
638 |
* @return a pseudorandomly chosen {@code int} value between the
|
|
639 |
* origin (inclusive) and the bound (exclusive)
|
|
640 |
*
|
|
641 |
* @throws IllegalArgumentException if {@code origin} is greater than
|
|
642 |
* or equal to {@code bound}
|
|
643 |
*
|
|
644 |
* @implNote The default implementation simply calls
|
|
645 |
* {@code RandomSupport.checkRange(origin, bound)} and then
|
|
646 |
* {@code RandomSupport.boundedNextInt(this, origin, bound)}.
|
|
647 |
*/
|
|
648 |
default int nextInt(int origin, int bound) {
|
|
649 |
RandomSupport.checkRange(origin, bound);
|
|
650 |
return RandomSupport.boundedNextInt(this, origin, bound);
|
|
651 |
}
|
|
652 |
|
|
653 |
/**
|
|
654 |
* Returns a pseudorandomly chosen {@code long} value.
|
|
655 |
*
|
|
656 |
* @return a pseudorandomly chosen {@code long} value
|
|
657 |
*/
|
|
658 |
long nextLong();
|
|
659 |
|
|
660 |
/**
|
|
661 |
* Returns a pseudorandomly chosen {@code long} value between
|
|
662 |
* zero (inclusive) and the specified bound (exclusive).
|
|
663 |
*
|
|
664 |
* @param bound the upper bound (exclusive) for the returned value. Must be positive.
|
|
665 |
*
|
|
666 |
* @return a pseudorandomly chosen {@code long} value between
|
|
667 |
* zero (inclusive) and the bound (exclusive)
|
|
668 |
*
|
|
669 |
* @throws IllegalArgumentException if {@code bound} is not positive
|
|
670 |
*
|
|
671 |
* @implNote The default implementation simply calls
|
|
672 |
* {@code RandomSupport.checkBound(bound)} and then
|
|
673 |
* {@code RandomSupport.boundedNextLong(this, bound)}.
|
|
674 |
*/
|
|
675 |
default long nextLong(long bound) {
|
|
676 |
RandomSupport.checkBound(bound);
|
|
677 |
return RandomSupport.boundedNextLong(this, bound);
|
|
678 |
}
|
|
679 |
|
|
680 |
/**
|
|
681 |
* Returns a pseudorandomly chosen {@code long} value between the
|
|
682 |
* specified origin (inclusive) and the specified bound (exclusive).
|
|
683 |
*
|
|
684 |
* @param origin the least value that can be returned
|
|
685 |
* @param bound the upper bound (exclusive) for the returned value
|
|
686 |
*
|
|
687 |
* @return a pseudorandomly chosen {@code long} value between the
|
|
688 |
* origin (inclusive) and the bound (exclusive)
|
|
689 |
*
|
|
690 |
* @throws IllegalArgumentException if {@code origin} is greater than
|
|
691 |
* or equal to {@code bound}
|
|
692 |
*
|
|
693 |
* @implNote The default implementation simply calls
|
|
694 |
* {@code RandomSupport.checkRange(origin, bound)} and then
|
|
695 |
* {@code RandomSupport.boundedNextInt(this, origin, bound)}.
|
|
696 |
*
|
|
697 |
*/
|
|
698 |
default long nextLong(long origin, long bound) {
|
|
699 |
RandomSupport.checkRange(origin, bound);
|
|
700 |
return RandomSupport.boundedNextLong(this, origin, bound);
|
|
701 |
}
|
|
702 |
|
|
703 |
/**
|
|
704 |
* Returns a {@code double} value pseudorandomly chosen from
|
|
705 |
* a Gaussian (normal) distribution whose mean is 0 and whose
|
|
706 |
* standard deviation is 1.
|
|
707 |
*
|
|
708 |
* @return a {@code double} value pseudorandomly chosen from a
|
|
709 |
* Gaussian distribution
|
|
710 |
*/
|
|
711 |
default double nextGaussian() {
|
|
712 |
return RandomSupport.computeNextGaussian(this);
|
|
713 |
}
|
|
714 |
|
|
715 |
/**
|
|
716 |
* Returns a {@code double} value pseudorandomly chosen from
|
|
717 |
* a Gaussian (normal) distribution with a mean and
|
|
718 |
* standard deviation specified by the arguments.
|
|
719 |
*
|
|
720 |
* @param mean the mean of the Gaussian distribution to be drawn from
|
|
721 |
* @param stddev the standard deviation (square root of the variance)
|
|
722 |
* of the Gaussian distribution to be drawn from
|
|
723 |
*
|
|
724 |
* @return a {@code double} value pseudorandomly chosen from the
|
|
725 |
* specified Gaussian distribution
|
|
726 |
*
|
|
727 |
* @throws IllegalArgumentException if {@code stddev} is negative
|
|
728 |
*/
|
|
729 |
default double nextGaussian(double mean, double stddev) {
|
|
730 |
if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative");
|
|
731 |
return mean + stddev * RandomSupport.computeNextGaussian(this);
|
|
732 |
}
|
|
733 |
|
|
734 |
/**
|
|
735 |
* Returns a nonnegative {@code double} value pseudorandomly chosen
|
|
736 |
* from an exponential distribution whose mean is 1.
|
|
737 |
*
|
|
738 |
* @return a nonnegative {@code double} value pseudorandomly chosen from an
|
|
739 |
* exponential distribution
|
|
740 |
*/
|
|
741 |
default double nextExponential() {
|
|
742 |
return RandomSupport.computeNextExponential(this);
|
|
743 |
}
|
|
744 |
|
|
745 |
/**
|
|
746 |
* Returns the period of this {@link RandomGenerator} object.
|
|
747 |
*
|
|
748 |
* @return a {@link BigInteger} whose value is the number of distinct possible states of this
|
|
749 |
* {@link RandomGenerator} object, or 0 if unknown, or negative if extremely
|
|
750 |
* large.
|
|
751 |
*/
|
|
752 |
BigInteger period();
|
|
753 |
|
|
754 |
/**
|
|
755 |
* The value (0) returned by the {@code period()} method if the period is unknown.
|
|
756 |
*/
|
|
757 |
static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
|
|
758 |
|
|
759 |
/**
|
|
760 |
* The (negative) value returned by the {@code period()} method if this generator
|
|
761 |
* has no period because it is truly random rather than just pseudorandom.
|
|
762 |
*/
|
|
763 |
static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
|
|
764 |
|
|
765 |
/**
|
|
766 |
* The (negative) value that may be returned by the {@code period()} method
|
|
767 |
* if this generator has a huge period (larger than 2**(2**16)).
|
|
768 |
*/
|
|
769 |
static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
|
|
770 |
|
|
771 |
/**
|
|
772 |
* The {@link StreamableGenerator} interface augments the {@link RandomGenerator} interface
|
|
773 |
* to provide methods that return streams of {@link RandomGenerator} objects.
|
|
774 |
* Ideally, such a stream of objects would have the property that the
|
|
775 |
* behavior of each object is statistically independent of all the others.
|
|
776 |
* In practice, one may have to settle for some approximation to this property.
|
|
777 |
*
|
|
778 |
* A generator that implements interface {@link SplittableGenerator}
|
|
779 |
* may choose to use its {@code splits} method to implement the {@code rngs}
|
|
780 |
* method required by this interface.
|
|
781 |
*
|
|
782 |
* A generator that implements interface {@link JumpableGenerator}
|
|
783 |
* may choose to use its {@code jumps} method to implement the {@code rngs}
|
|
784 |
* method required by this interface.
|
|
785 |
*
|
|
786 |
* A generator that implements interface {@link LeapableGenerator}
|
|
787 |
* may choose to use its {@code leaps} method to implement the {@code rngs}
|
|
788 |
* method required by this interface.
|
|
789 |
* <p>
|
|
790 |
* An implementation of the {@link StreamableGenerator} interface must provide
|
|
791 |
* concrete definitions for the methods {@code nextInt()}, {@code nextLong},
|
|
792 |
* {@code period()}, and {@code rngs()}.
|
|
793 |
* Default implementations are provided for all other methods.
|
|
794 |
* <p>
|
|
795 |
* Objects that implement {@link StreamableGenerator} are typically
|
|
796 |
* not cryptographically secure. Consider instead using
|
|
797 |
* {@link java.security.SecureRandom} to get a cryptographically
|
|
798 |
* secure pseudo-random number generator for use by
|
|
799 |
* security-sensitive applications.
|
|
800 |
*
|
|
801 |
* @since 14
|
|
802 |
*/
|
|
803 |
public interface StreamableGenerator extends RandomGenerator {
|
|
804 |
|
|
805 |
/**
|
|
806 |
* Returns an instance of {@link StreamableGenerator} that utilizes the
|
|
807 |
* {@code name} algorithm.
|
|
808 |
*
|
|
809 |
* @param name Name of random number generator algorithm
|
|
810 |
*
|
|
811 |
* @return An instance of {@link StreamableGenerator}
|
|
812 |
*/
|
|
813 |
public static StreamableGenerator of(String name) {
|
|
814 |
Objects.requireNonNull(name);
|
|
815 |
return RandomGeneratorFactory.of(name, StreamableGenerator.class);
|
|
816 |
}
|
|
817 |
|
|
818 |
/**
|
|
819 |
* Returns an instance of {@link StreamableGenerator} that utilizes the
|
|
820 |
* specified {@code algorithm}.
|
|
821 |
*
|
|
822 |
* @param algorithm Random number generator algorithm
|
|
823 |
*
|
|
824 |
* @return An instance of {@link StreamableGenerator}
|
|
825 |
*/
|
|
826 |
public static StreamableGenerator of(Algorithm algorithm) {
|
|
827 |
Objects.requireNonNull(algorithm);
|
|
828 |
return RandomGeneratorFactory.of(algorithm.toString(), StreamableGenerator.class);
|
|
829 |
}
|
|
830 |
|
|
831 |
/**
|
|
832 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
833 |
* of {@link StreamableGenerator} that utilizes the {@code name} algorithm.
|
|
834 |
*
|
|
835 |
* @param name Name of random number generator algorithm
|
|
836 |
*
|
|
837 |
* @return {@link RandomGeneratorFactory} of {@link StreamableGenerator}
|
|
838 |
*/
|
|
839 |
public static RandomGeneratorFactory<StreamableGenerator> factoryOf(String name) {
|
|
840 |
Objects.requireNonNull(name);
|
|
841 |
return RandomGeneratorFactory.factoryOf(name, StreamableGenerator.class);
|
|
842 |
}
|
|
843 |
|
|
844 |
/**
|
|
845 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
846 |
* of {@link StreamableGenerator} that utilizes the specified {@code algorithm}.
|
|
847 |
*
|
|
848 |
* @param algorithm Random number generator algorithm
|
|
849 |
*
|
|
850 |
* @return {@link RandomGeneratorFactory} of {@link StreamableGenerator}
|
|
851 |
*/
|
|
852 |
public static RandomGeneratorFactory<StreamableGenerator> factoryOf(Algorithm algorithm) {
|
|
853 |
Objects.requireNonNull(algorithm);
|
|
854 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), StreamableGenerator.class);
|
|
855 |
}
|
|
856 |
|
|
857 |
/**
|
|
858 |
* Returns an effectively unlimited stream of objects, each of
|
|
859 |
* which implements the {@link RandomGenerator} interface. Ideally the
|
|
860 |
* generators in the stream will appear to be statistically
|
|
861 |
* independent. The new generators should be of the same kind
|
|
862 |
* as this generator.
|
|
863 |
*
|
|
864 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
865 |
*
|
|
866 |
* @implNote It is permitted to implement this method in a manner
|
|
867 |
* equivalent to {@code rngs(Long.MAX_VALUE)}.
|
|
868 |
*/
|
|
869 |
Stream<RandomGenerator> rngs();
|
|
870 |
|
|
871 |
/**
|
|
872 |
* Returns an effectively unlimited stream of objects, each of
|
|
873 |
* which implements the {@link RandomGenerator} interface. Ideally the
|
|
874 |
* generators in the stream will appear to be statistically
|
|
875 |
* independent. The new generators should be of the same kind
|
|
876 |
* as this generator.
|
|
877 |
*
|
|
878 |
* @param streamSize the number of generators to generate
|
|
879 |
*
|
|
880 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
881 |
*
|
|
882 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
883 |
* less than zero
|
|
884 |
*
|
|
885 |
* @implNote The default implementation calls {@code rngs()} and
|
|
886 |
* then limits its length to {@code streamSize}.
|
|
887 |
*/
|
|
888 |
default Stream<RandomGenerator> rngs(long streamSize) {
|
|
889 |
RandomSupport.checkStreamSize(streamSize);
|
|
890 |
return rngs().limit(streamSize);
|
|
891 |
}
|
|
892 |
}
|
|
893 |
|
|
894 |
/**
|
|
895 |
* This interface is designed to provide a common protocol for objects
|
|
896 |
* that generate sequences of pseudorandom numbers (or Boolean values)
|
|
897 |
* and furthermore can be <i>split</i> into two objects (the original
|
|
898 |
* one and a new one) each of which obey that same protocol (and therefore
|
|
899 |
* can be recursively split indefinitely).
|
|
900 |
* <p>
|
|
901 |
* Ideally, all {@link SplittableGenerator} objects produced by recursive
|
|
902 |
* splitting from a single original {@link SplittableGenerator} object are
|
|
903 |
* statistically independent of one another and individually uniform.
|
|
904 |
* Therefore we would expect the set of values collectively generated
|
|
905 |
* by a set of such objects to have the same statistical properties as
|
|
906 |
* if the same quantity of values were generated by a single thread
|
|
907 |
* using a single {@link SplittableGenerator} object. In practice, one must
|
|
908 |
* settle for some approximation to independence and uniformity.
|
|
909 |
* <p>
|
|
910 |
* Methods are provided to perform a single splitting operation and
|
|
911 |
* also to produce a stream of generators split off from the original
|
|
912 |
* (by either iterative or recursive splitting, or a combination).
|
|
913 |
* <p>
|
|
914 |
* An implementation of the {@link SplittableGenerator} interface must provide
|
|
915 |
* concrete definitions for the methods {@code nextInt()}, {@code nextLong},
|
|
916 |
* {@code period()}, {@code split()}, {@code split(SplittableGenerator)},
|
|
917 |
* {@code splits()}, {@code splits(long)}, {@code splits(SplittableGenerator)},
|
|
918 |
* and {@code splits(long, SplittableGenerator)}. Perhaps the most convenient
|
|
919 |
* way to implement this interface is to extend the abstract class
|
|
920 |
* {@link AbstractSplittableGenerator}.
|
|
921 |
* <p>
|
|
922 |
* Objects that implement {@link SplittableGenerator} are
|
|
923 |
* typically not cryptographically secure. Consider instead using
|
|
924 |
* {@link java.security.SecureRandom} to get a cryptographically
|
|
925 |
* secure pseudo-random number generator for use by
|
|
926 |
* security-sensitive applications.
|
|
927 |
*
|
|
928 |
* @since 14
|
|
929 |
*/
|
|
930 |
public interface SplittableGenerator extends StreamableGenerator {
|
|
931 |
|
|
932 |
/**
|
|
933 |
* Returns an instance of {@link SplittableGenerator} that utilizes the
|
|
934 |
* {@code name} algorithm.
|
|
935 |
*
|
|
936 |
* @param name Name of random number generator algorithm
|
|
937 |
*
|
|
938 |
* @return An instance of {@link SplittableGenerator}
|
|
939 |
*/
|
|
940 |
public static SplittableGenerator of(String name) {
|
|
941 |
Objects.requireNonNull(name);
|
|
942 |
return RandomGeneratorFactory.of(name, SplittableGenerator.class);
|
|
943 |
}
|
|
944 |
|
|
945 |
/**
|
|
946 |
* Returns an instance of {@link SplittableGenerator} that utilizes the
|
|
947 |
* specified {@code algorithm}.
|
|
948 |
*
|
|
949 |
* @param algorithm Random number generator algorithm
|
|
950 |
*
|
|
951 |
* @return An instance of {@link SplittableGenerator}
|
|
952 |
*/
|
|
953 |
public static SplittableGenerator of(Algorithm algorithm) {
|
|
954 |
Objects.requireNonNull(algorithm);
|
|
955 |
return RandomGeneratorFactory.of(algorithm.toString(), SplittableGenerator.class);
|
|
956 |
}
|
|
957 |
|
|
958 |
/**
|
|
959 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
960 |
* of {@link SplittableGenerator} that utilizes the {@code name} algorithm.
|
|
961 |
*
|
|
962 |
* @param name Name of random number generator algorithm
|
|
963 |
*
|
|
964 |
* @return {@link RandomGeneratorFactory} of {@link SplittableGenerator}
|
|
965 |
*/
|
|
966 |
public static RandomGeneratorFactory<SplittableGenerator> factoryOf(String name) {
|
|
967 |
Objects.requireNonNull(name);
|
|
968 |
return RandomGeneratorFactory.factoryOf(name, SplittableGenerator.class);
|
|
969 |
}
|
|
970 |
|
|
971 |
/**
|
|
972 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
973 |
* of {@link SplittableGenerator} that utilizes the specified {@code algorithm}.
|
|
974 |
*
|
|
975 |
* @param algorithm Random number generator algorithm
|
|
976 |
*
|
|
977 |
* @return {@link RandomGeneratorFactory} of {@link SplittableGenerator}
|
|
978 |
*/
|
|
979 |
public static RandomGeneratorFactory<SplittableGenerator> factoryOf(Algorithm algorithm) {
|
|
980 |
Objects.requireNonNull(algorithm);
|
|
981 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), SplittableGenerator.class);
|
|
982 |
}
|
|
983 |
|
|
984 |
/**
|
|
985 |
* Returns a new pseudorandom number generator, split off from
|
|
986 |
* this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
|
|
987 |
* interfaces.
|
|
988 |
*
|
|
989 |
* This pseudorandom number generator may be used as a source of
|
|
990 |
* pseudorandom bits used to initialize the state the new one.
|
|
991 |
*
|
|
992 |
* @return a new object that implements the {@link RandomGenerator} and
|
|
993 |
* {@link SplittableGenerator} interfaces
|
|
994 |
*/
|
|
995 |
SplittableGenerator split();
|
|
996 |
|
|
997 |
/**
|
|
998 |
* Returns a new pseudorandom number generator, split off from
|
|
999 |
* this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
|
|
1000 |
* interfaces.
|
|
1001 |
*
|
|
1002 |
* @param source a {@link SplittableGenerator} instance to be used instead
|
|
1003 |
* of this one as a source of pseudorandom bits used to
|
|
1004 |
* initialize the state of the new ones.
|
|
1005 |
*
|
|
1006 |
* @return an object that implements the {@link RandomGenerator} and
|
|
1007 |
* {@link SplittableGenerator} interfaces
|
|
1008 |
*/
|
|
1009 |
SplittableGenerator split(SplittableGenerator source);
|
|
1010 |
|
|
1011 |
/**
|
|
1012 |
* Returns an effectively unlimited stream of new pseudorandom
|
|
1013 |
* number generators, each of which implements the {@link SplittableGenerator}
|
|
1014 |
* interface.
|
|
1015 |
*
|
|
1016 |
* This pseudorandom number generator may be used as a source of
|
|
1017 |
* pseudorandom bits used to initialize the state the new ones.
|
|
1018 |
*
|
|
1019 |
* @implNote It is permitted to implement this method in a manner
|
|
1020 |
* equivalent to {@code splits(Long.MAX_VALUE)}.
|
|
1021 |
*
|
|
1022 |
* @return a stream of {@link SplittableGenerator} objects
|
|
1023 |
*/
|
|
1024 |
default Stream<SplittableGenerator> splits() {
|
|
1025 |
return this.splits(this);
|
|
1026 |
}
|
|
1027 |
|
|
1028 |
/**
|
|
1029 |
* Returns a stream producing the given {@code streamSize} number of
|
|
1030 |
* new pseudorandom number generators, each of which implements the
|
|
1031 |
* {@link SplittableGenerator} interface.
|
|
1032 |
*
|
|
1033 |
* This pseudorandom number generator may be used as a source of
|
|
1034 |
* pseudorandom bits used to initialize the state the new ones.
|
|
1035 |
*
|
|
1036 |
* @param streamSize the number of values to generate
|
|
1037 |
*
|
|
1038 |
* @return a stream of {@link SplittableGenerator} objects
|
|
1039 |
*
|
|
1040 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
1041 |
* less than zero
|
|
1042 |
*/
|
|
1043 |
Stream<SplittableGenerator> splits(long streamSize);
|
|
1044 |
|
|
1045 |
/**
|
|
1046 |
* Returns an effectively unlimited stream of new pseudorandom
|
|
1047 |
* number generators, each of which implements the {@link SplittableGenerator}
|
|
1048 |
* interface.
|
|
1049 |
*
|
|
1050 |
* @param source a {@link SplittableGenerator} instance to be used instead
|
|
1051 |
* of this one as a source of pseudorandom bits used to
|
|
1052 |
* initialize the state of the new ones.
|
|
1053 |
*
|
|
1054 |
* @return a stream of {@link SplittableGenerator} objects
|
|
1055 |
*
|
|
1056 |
* @implNote It is permitted to implement this method in a manner
|
|
1057 |
* equivalent to {@code splits(Long.MAX_VALUE, source)}.
|
|
1058 |
*/
|
|
1059 |
Stream<SplittableGenerator> splits(SplittableGenerator source);
|
|
1060 |
|
|
1061 |
/**
|
|
1062 |
* Returns a stream producing the given {@code streamSize} number of
|
|
1063 |
* new pseudorandom number generators, each of which implements the
|
|
1064 |
* {@link SplittableGenerator} interface.
|
|
1065 |
*
|
|
1066 |
* @param streamSize the number of values to generate
|
|
1067 |
* @param source a {@link SplittableGenerator} instance to be used instead
|
|
1068 |
* of this one as a source of pseudorandom bits used to
|
|
1069 |
* initialize the state of the new ones.
|
|
1070 |
*
|
|
1071 |
* @return a stream of {@link SplittableGenerator} objects
|
|
1072 |
*
|
|
1073 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
1074 |
* less than zero
|
|
1075 |
*/
|
|
1076 |
Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source);
|
|
1077 |
|
|
1078 |
/**
|
|
1079 |
* Returns an effectively unlimited stream of new pseudorandom
|
|
1080 |
* number generators, each of which implements the {@link RandomGenerator}
|
|
1081 |
* interface. Ideally the generators in the stream will appear
|
|
1082 |
* to be statistically independent.
|
|
1083 |
*
|
|
1084 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1085 |
*
|
|
1086 |
* @implNote The default implementation calls {@code splits()}.
|
|
1087 |
*/
|
|
1088 |
default Stream<RandomGenerator> rngs() {
|
|
1089 |
return this.splits().map(x -> (RandomGenerator)x);
|
|
1090 |
}
|
|
1091 |
|
|
1092 |
/**
|
|
1093 |
* Returns a stream producing the given {@code streamSize} number of
|
|
1094 |
* new pseudorandom number generators, each of which implements the
|
|
1095 |
* {@link RandomGenerator} interface. Ideally the generators in the stream will
|
|
1096 |
* appear to be statistically independent.
|
|
1097 |
*
|
|
1098 |
* @param streamSize the number of generators to generate
|
|
1099 |
*
|
|
1100 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1101 |
*
|
|
1102 |
* @throws IllegalArgumentException if {@code streamSize} is
|
|
1103 |
* less than zero
|
|
1104 |
*
|
|
1105 |
* @implNote The default implementation calls {@code splits(streamSize)}.
|
|
1106 |
*/
|
|
1107 |
default Stream<RandomGenerator> rngs(long streamSize) {
|
|
1108 |
return this.splits(streamSize).map(x -> (RandomGenerator)x);
|
|
1109 |
}
|
|
1110 |
}
|
|
1111 |
|
|
1112 |
/**
|
|
1113 |
* This interface is designed to provide a common protocol for objects that generate
|
|
1114 |
* pseudorandom sequences of numbers (or Boolean values) and furthermore can easily <i>jump</i>
|
|
1115 |
* forward (by a fixed amount) to a distant point in the state cycle.
|
|
1116 |
* <p>
|
|
1117 |
* Ideally, all {@link JumpableGenerator} objects produced by iterative jumping from a single
|
|
1118 |
* original {@link JumpableGenerator} object are statistically independent of one another and
|
|
1119 |
* individually uniform. In practice, one must settle for some approximation to independence and
|
|
1120 |
* uniformity. In particular, a specific implementation may assume that each generator in a
|
|
1121 |
* stream produced by the {@code jumps} method is used to produce a number of values no larger
|
|
1122 |
* than either 2<sup>64</sup> or the square root of its period. Implementors are advised to use
|
|
1123 |
* algorithms whose period is at least 2<sup>127</sup>.
|
|
1124 |
* <p>
|
|
1125 |
* Methods are provided to perform a single jump operation and also to produce a stream of
|
|
1126 |
* generators produced from the original by iterative copying and jumping of internal state. A
|
|
1127 |
* typical strategy for a multithreaded application is to create a single {@link
|
|
1128 |
* JumpableGenerator} object, calls its {@code jumps} method exactly once, and then parcel out
|
|
1129 |
* generators from the resulting stream, one to each thread. It is generally not a good idea to
|
|
1130 |
* call {@code jump} on a generator that was itself produced by the {@code jumps} method,
|
|
1131 |
* because the result may be a generator identical to another generator already produce by that
|
|
1132 |
* call to the {@code jumps} method. For this reason, the return type of the {@code jumps}
|
|
1133 |
* method is {@code Stream<RandomGenerator>} rather than {@code Stream<JumpableGenerator>}, even
|
|
1134 |
* though the actual generator objects in that stream likely do also implement the {@link
|
|
1135 |
* JumpableGenerator} interface.
|
|
1136 |
* <p>
|
|
1137 |
* An implementation of the {@link JumpableGenerator} interface must provide concrete
|
|
1138 |
* definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code
|
|
1139 |
* copy()}, {@code jump()}, and {@code defaultJumpDistance()}. Default implementations are
|
|
1140 |
* provided for all other methods.
|
|
1141 |
* <p>
|
|
1142 |
* Objects that implement {@link JumpableGenerator} are typically not cryptographically secure.
|
|
1143 |
* Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
|
|
1144 |
* pseudo-random number generator for use by security-sensitive applications.
|
|
1145 |
*
|
|
1146 |
* @since 14
|
|
1147 |
*/
|
|
1148 |
public interface JumpableGenerator extends StreamableGenerator {
|
|
1149 |
|
|
1150 |
/**
|
|
1151 |
* Returns an instance of {@link JumpableGenerator} that utilizes the
|
|
1152 |
* {@code name} algorithm.
|
|
1153 |
*
|
|
1154 |
* @param name Name of random number generator algorithm
|
|
1155 |
*
|
|
1156 |
* @return An instance of {@link JumpableGenerator}
|
|
1157 |
*/
|
|
1158 |
public static JumpableGenerator of(String name) {
|
|
1159 |
Objects.requireNonNull(name);
|
|
1160 |
return RandomGeneratorFactory.of(name, JumpableGenerator.class);
|
|
1161 |
}
|
|
1162 |
|
|
1163 |
/**
|
|
1164 |
* Returns an instance of {@link JumpableGenerator} that utilizes the
|
|
1165 |
* specified {@code algorithm}.
|
|
1166 |
*
|
|
1167 |
* @param algorithm Random number generator algorithm
|
|
1168 |
*
|
|
1169 |
* @return An instance of {@link JumpableGenerator}
|
|
1170 |
*/
|
|
1171 |
public static JumpableGenerator of(Algorithm algorithm) {
|
|
1172 |
Objects.requireNonNull(algorithm);
|
|
1173 |
return RandomGeneratorFactory.of(algorithm.toString(), JumpableGenerator.class);
|
|
1174 |
}
|
|
1175 |
|
|
1176 |
/**
|
|
1177 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1178 |
* of {@link JumpableGenerator} that utilizes the {@code name} algorithm.
|
|
1179 |
*
|
|
1180 |
* @param name Name of random number generator algorithm
|
|
1181 |
*
|
|
1182 |
* @return {@link RandomGeneratorFactory} of {@link JumpableGenerator}
|
|
1183 |
*/
|
|
1184 |
public static RandomGeneratorFactory<JumpableGenerator> factoryOf(String name) {
|
|
1185 |
Objects.requireNonNull(name);
|
|
1186 |
return RandomGeneratorFactory.factoryOf(name, JumpableGenerator.class);
|
|
1187 |
}
|
|
1188 |
|
|
1189 |
/**
|
|
1190 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1191 |
* of {@link JumpableGenerator} that utilizes the specified {@code algorithm}.
|
|
1192 |
*
|
|
1193 |
* @param algorithm Random number generator algorithm
|
|
1194 |
*
|
|
1195 |
* @return {@link RandomGeneratorFactory} of {@link JumpableGenerator}
|
|
1196 |
*/
|
|
1197 |
public static RandomGeneratorFactory<JumpableGenerator> factoryOf(Algorithm algorithm) {
|
|
1198 |
Objects.requireNonNull(algorithm);
|
|
1199 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), JumpableGenerator.class);
|
|
1200 |
}
|
|
1201 |
|
|
1202 |
/**
|
|
1203 |
* Returns a new generator whose internal state is an exact copy of this generator (therefore
|
|
1204 |
* their future behavior should be identical if subjected to the same series of operations).
|
|
1205 |
*
|
|
1206 |
* @return a new object that is a copy of this generator
|
|
1207 |
*/
|
|
1208 |
JumpableGenerator copy();
|
|
1209 |
|
|
1210 |
/**
|
|
1211 |
* Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
|
|
1212 |
* distance (typically 2<sup>64</sup> or more) within its state cycle.
|
|
1213 |
*/
|
|
1214 |
void jump();
|
|
1215 |
|
|
1216 |
/**
|
|
1217 |
* Returns the distance by which the {@code jump()} method will jump forward within the state
|
|
1218 |
* cycle of this generator object.
|
|
1219 |
*
|
|
1220 |
* @return the default jump distance (as a {@code double} value)
|
|
1221 |
*/
|
|
1222 |
double defaultJumpDistance();
|
|
1223 |
|
|
1224 |
/**
|
|
1225 |
* Returns an effectively unlimited stream of new pseudorandom number generators, each of which
|
|
1226 |
* implements the {@link RandomGenerator} interface.
|
|
1227 |
*
|
|
1228 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1229 |
*
|
|
1230 |
* @implNote It is permitted to implement this method in a manner equivalent to
|
|
1231 |
* {@code jumps(Long.MAX_VALUE)}.
|
|
1232 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
1233 |
* calls {@code copy()} and {@code jump()} on this generator, and the copies become the
|
|
1234 |
* generators produced by the stream.
|
|
1235 |
*/
|
|
1236 |
default Stream<RandomGenerator> jumps() {
|
|
1237 |
return Stream.generate(this::copyAndJump).sequential();
|
|
1238 |
}
|
|
1239 |
|
|
1240 |
/**
|
|
1241 |
* Returns a stream producing the given {@code streamSize} number of new pseudorandom number
|
|
1242 |
* generators, each of which implements the {@link RandomGenerator} interface.
|
|
1243 |
*
|
|
1244 |
* @param streamSize the number of generators to generate
|
|
1245 |
*
|
|
1246 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1247 |
*
|
|
1248 |
* @throws IllegalArgumentException if {@code streamSize} is less than zero
|
|
1249 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
1250 |
* calls {@code copy()} and {@code jump()} on this generator, and the copies become the
|
|
1251 |
* generators produced by the stream.
|
|
1252 |
*/
|
|
1253 |
default Stream<RandomGenerator> jumps(long streamSize) {
|
|
1254 |
return jumps().limit(streamSize);
|
|
1255 |
}
|
|
1256 |
|
|
1257 |
/**
|
|
1258 |
* Returns an effectively unlimited stream of new pseudorandom number generators, each of which
|
|
1259 |
* implements the {@link RandomGenerator} interface. Ideally the generators in the stream
|
|
1260 |
* will appear to be statistically independent.
|
|
1261 |
*
|
|
1262 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1263 |
*
|
|
1264 |
* @implNote The default implementation calls {@code jumps()}.
|
|
1265 |
*/
|
|
1266 |
default Stream<RandomGenerator> rngs() {
|
|
1267 |
return this.jumps();
|
|
1268 |
}
|
|
1269 |
|
|
1270 |
/**
|
|
1271 |
* Returns a stream producing the given {@code streamSize} number of new pseudorandom number
|
|
1272 |
* generators, each of which implements the {@link RandomGenerator} interface. Ideally
|
|
1273 |
* the generators in the stream will appear to be statistically independent.
|
|
1274 |
*
|
|
1275 |
* @param streamSize the number of generators to generate
|
|
1276 |
*
|
|
1277 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1278 |
*
|
|
1279 |
* @throws IllegalArgumentException if {@code streamSize} is less than zero
|
|
1280 |
* @implNote The default implementation calls {@code jumps(streamSize)}.
|
|
1281 |
*/
|
|
1282 |
default Stream<RandomGenerator> rngs(long streamSize) {
|
|
1283 |
return this.jumps(streamSize);
|
|
1284 |
}
|
|
1285 |
|
|
1286 |
/**
|
|
1287 |
* Copy this generator, jump this generator forward, then return the copy.
|
|
1288 |
*
|
|
1289 |
* @return a copy of this generator object before the jump occurred
|
|
1290 |
*/
|
|
1291 |
default RandomGenerator copyAndJump() {
|
|
1292 |
RandomGenerator result = copy();
|
|
1293 |
jump();
|
|
1294 |
return result;
|
|
1295 |
}
|
|
1296 |
|
|
1297 |
}
|
|
1298 |
|
|
1299 |
/**
|
|
1300 |
* This interface is designed to provide a common protocol for objects that generate sequences
|
|
1301 |
* of pseudorandom numbers (or Boolean values) and furthermore can easily not only jump but
|
|
1302 |
* also
|
|
1303 |
* <i>leap</i> to a very distant point in the state cycle.
|
|
1304 |
* <p>
|
|
1305 |
* Typically one will construct a series of {@link LeapableGenerator} objects by iterative
|
|
1306 |
* leaping from a single original {@link LeapableGenerator} object, and then for each such
|
|
1307 |
* object produce a subseries of objects by iterative jumping. There is little conceptual
|
|
1308 |
* difference between leaping and jumping, but typically a leap will be a very long jump in the
|
|
1309 |
* state cycle (perhaps distance 2<sup>128</sup> or so).
|
|
1310 |
* <p>
|
|
1311 |
* Ideally, all {@link LeapableGenerator} objects produced by iterative leaping and jumping from
|
|
1312 |
* a single original {@link LeapableGenerator} object are statistically independent of one
|
|
1313 |
* another and individually uniform. In practice, one must settle for some approximation to
|
|
1314 |
* independence and uniformity. In particular, a specific implementation may assume that each
|
|
1315 |
* generator in a stream produced by the {@code leaps} method is used to produce (by jumping) a
|
|
1316 |
* number of objects no larger than 2<sup>64</sup>. Implementors are advised to use algorithms
|
|
1317 |
* whose period is at least 2<sup>191</sup>.
|
|
1318 |
* <p>
|
|
1319 |
* Methods are provided to perform a single leap operation and also to produce a stream of
|
|
1320 |
* generators produced from the original by iterative copying and leaping of internal state.
|
|
1321 |
* The generators produced must implement the {@link JumpableGenerator} interface but need not
|
|
1322 |
* also implement the {@link LeapableGenerator} interface. A typical strategy for a
|
|
1323 |
* multithreaded application is to create a single {@link LeapableGenerator} object, calls its
|
|
1324 |
* {@code leaps} method exactly once, and then parcel out generators from the resulting stream,
|
|
1325 |
* one to each thread. Then the {@code jumps} method of each such generator be called to
|
|
1326 |
* produce a substream of generator objects.
|
|
1327 |
* <p>
|
|
1328 |
* An implementation of the {@link LeapableGenerator} interface must provide concrete
|
|
1329 |
* definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
|
|
1330 |
* {@code copy()}, {@code jump()}, {@code defaultJumpDistance()}, {@code leap()},
|
|
1331 |
* and {@code defaultLeapDistance()}. Default implementations are provided for all other
|
|
1332 |
* methods.
|
|
1333 |
* <p>
|
|
1334 |
* Objects that implement {@link LeapableGenerator} are typically not cryptographically secure.
|
|
1335 |
* Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
|
|
1336 |
* pseudo-random number generator for use by security-sensitive applications.
|
|
1337 |
*
|
|
1338 |
* @since 14
|
|
1339 |
*/
|
|
1340 |
public interface LeapableGenerator extends JumpableGenerator {
|
|
1341 |
|
|
1342 |
/**
|
|
1343 |
* Returns an instance of {@link LeapableGenerator} that utilizes the
|
|
1344 |
* {@code name} algorithm.
|
|
1345 |
*
|
|
1346 |
* @param name Name of random number generator algorithm
|
|
1347 |
*
|
|
1348 |
* @return An instance of {@link LeapableGenerator}
|
|
1349 |
*/
|
|
1350 |
public static LeapableGenerator of(String name) {
|
|
1351 |
Objects.requireNonNull(name);
|
|
1352 |
return RandomGeneratorFactory.of(name, LeapableGenerator.class);
|
|
1353 |
}
|
|
1354 |
|
|
1355 |
/**
|
|
1356 |
* Returns an instance of {@link LeapableGenerator} that utilizes the
|
|
1357 |
* specified {@code algorithm}.
|
|
1358 |
*
|
|
1359 |
* @param algorithm Random number generator algorithm
|
|
1360 |
*
|
|
1361 |
* @return An instance of {@link LeapableGenerator}
|
|
1362 |
*/
|
|
1363 |
public static LeapableGenerator of(Algorithm algorithm) {
|
|
1364 |
Objects.requireNonNull(algorithm);
|
|
1365 |
return RandomGeneratorFactory.of(algorithm.toString(), LeapableGenerator.class);
|
|
1366 |
}
|
|
1367 |
|
|
1368 |
/**
|
|
1369 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1370 |
* of {@link LeapableGenerator} that utilizes the {@code name} algorithm.
|
|
1371 |
*
|
|
1372 |
* @param name Name of random number generator algorithm
|
|
1373 |
*
|
|
1374 |
* @return {@link RandomGeneratorFactory} of {@link LeapableGenerator}
|
|
1375 |
*/
|
|
1376 |
public static RandomGeneratorFactory<LeapableGenerator> factoryOf(String name) {
|
|
1377 |
Objects.requireNonNull(name);
|
|
1378 |
return RandomGeneratorFactory.factoryOf(name, LeapableGenerator.class);
|
|
1379 |
}
|
|
1380 |
|
|
1381 |
/**
|
|
1382 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1383 |
* of {@link LeapableGenerator} that utilizes the specified {@code algorithm}.
|
|
1384 |
*
|
|
1385 |
* @param algorithm Random number generator algorithm
|
|
1386 |
*
|
|
1387 |
* @return {@link RandomGeneratorFactory} of {@link LeapableGenerator}
|
|
1388 |
*/
|
|
1389 |
public static RandomGeneratorFactory<LeapableGenerator> factoryOf(Algorithm algorithm) {
|
|
1390 |
Objects.requireNonNull(algorithm);
|
|
1391 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), LeapableGenerator.class);
|
|
1392 |
}
|
|
1393 |
|
|
1394 |
/**
|
|
1395 |
* Returns a new generator whose internal state is an exact copy of this generator (therefore
|
|
1396 |
* their future behavior should be identical if subjected to the same series of operations).
|
|
1397 |
*
|
|
1398 |
* @return a new object that is a copy of this generator
|
|
1399 |
*/
|
|
1400 |
LeapableGenerator copy();
|
|
1401 |
|
|
1402 |
/**
|
|
1403 |
* Alter the state of this pseudorandom number generator so as to leap forward a large, fixed
|
|
1404 |
* distance (typically 2<sup>96</sup> or more) within its state cycle.
|
|
1405 |
*/
|
|
1406 |
void leap();
|
|
1407 |
|
|
1408 |
/**
|
|
1409 |
* Returns the distance by which the {@code leap()} method will leap forward within the state
|
|
1410 |
* cycle of this generator object.
|
|
1411 |
*
|
|
1412 |
* @return the default leap distance (as a {@code double} value)
|
|
1413 |
*/
|
|
1414 |
double defaultLeapDistance();
|
|
1415 |
|
|
1416 |
/**
|
|
1417 |
* Returns an effectively unlimited stream of new pseudorandom number generators, each of which
|
|
1418 |
* implements the {@link JumpableGenerator} interface.
|
|
1419 |
*
|
|
1420 |
* @return a stream of objects that implement the {@link JumpableGenerator} interface
|
|
1421 |
*
|
|
1422 |
* @implNote It is permitted to implement this method in a manner equivalent to {@code
|
|
1423 |
* leaps(Long.MAX_VALUE)}.
|
|
1424 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
1425 |
* calls {@code copy()} and {@code leap()} on this generator, and the copies become the
|
|
1426 |
* generators produced by the stream.
|
|
1427 |
*/
|
|
1428 |
default Stream<JumpableGenerator> leaps() {
|
|
1429 |
return Stream.generate(this::copyAndLeap).sequential();
|
|
1430 |
}
|
|
1431 |
|
|
1432 |
/**
|
|
1433 |
* Returns a stream producing the given {@code streamSize} number of new pseudorandom number
|
|
1434 |
* generators, each of which implements the {@link JumpableGenerator} interface.
|
|
1435 |
*
|
|
1436 |
* @param streamSize the number of generators to generate
|
|
1437 |
*
|
|
1438 |
* @return a stream of objects that implement the {@link JumpableGenerator} interface
|
|
1439 |
*
|
|
1440 |
* @throws IllegalArgumentException if {@code streamSize} is less than zero
|
|
1441 |
* @implNote The default implementation produces a sequential stream that repeatedly
|
|
1442 |
* calls {@code copy()} and {@code leap()} on this generator, and the copies become the
|
|
1443 |
* generators produced by the stream.
|
|
1444 |
*/
|
|
1445 |
default Stream<JumpableGenerator> leaps(long streamSize) {
|
|
1446 |
return leaps().limit(streamSize);
|
|
1447 |
}
|
|
1448 |
|
|
1449 |
/**
|
|
1450 |
* Copy this generator, leap this generator forward, then return the copy.
|
|
1451 |
*
|
|
1452 |
* @return a copy of this generator object before the leap occurred
|
|
1453 |
*/
|
|
1454 |
default JumpableGenerator copyAndLeap() {
|
|
1455 |
JumpableGenerator result = copy();
|
|
1456 |
leap();
|
|
1457 |
return result;
|
|
1458 |
}
|
|
1459 |
|
|
1460 |
}
|
|
1461 |
|
|
1462 |
/**
|
|
1463 |
* This interface is designed to provide a common protocol for objects that generate sequences
|
|
1464 |
* of pseudorandom numbers (or Boolean values) and furthermore can easily <i>jump</i> to an
|
|
1465 |
* arbitrarily specified distant point in the state cycle.
|
|
1466 |
* <p>
|
|
1467 |
* Ideally, all {@link ArbitrarilyJumpableGenerator} objects produced by iterative jumping from
|
|
1468 |
* a single original {@link ArbitrarilyJumpableGenerator} object are statistically independent
|
|
1469 |
* of one another and individually uniform, provided that they do not traverse overlapping
|
|
1470 |
* portions of the state cycle. In practice, one must settle for some approximation to
|
|
1471 |
* independence and uniformity. In particular, a specific implementation may assume that each
|
|
1472 |
* generator in a stream produced by the {@code jumps} method is used to produce a number of
|
|
1473 |
* values no larger than the jump distance specified. Implementors are advised to use
|
|
1474 |
* algorithms whose period is at least 2<sup>127</sup>.
|
|
1475 |
* <p>
|
|
1476 |
* For many applications, it suffices to jump forward by a power of two or some small multiple
|
|
1477 |
* of a power of two, but this power of two may not be representable as a {@code long} value.
|
|
1478 |
* To avoid the use of {@link java.math.BigInteger} values as jump distances, {@code double}
|
|
1479 |
* values are used instead.
|
|
1480 |
* <p>
|
|
1481 |
* Methods are provided to perform a single jump operation and also to produce a stream of
|
|
1482 |
* generators produced from the original by iterative copying and jumping of internal state. A
|
|
1483 |
* typical strategy for a multithreaded application is to create a single
|
|
1484 |
* {@link ArbitrarilyJumpableGenerator} object, call its {@code jumps} method exactly once, and
|
|
1485 |
* then parcel out generators from the resulting stream, one to each thread. However, each
|
|
1486 |
* generator produced also has type {@link ArbitrarilyJumpableGenerator}; with care, different
|
|
1487 |
* jump distances can be used to traverse the entire state cycle in various ways.
|
|
1488 |
* <p>
|
|
1489 |
* An implementation of the {@link ArbitrarilyJumpableGenerator} interface must provide concrete
|
|
1490 |
* definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
|
|
1491 |
* {@code copy()}, {@code jump(double)}, {@code defaultJumpDistance()}, and
|
|
1492 |
* {@code defaultLeapDistance()}. Default implementations are provided for all other methods.
|
|
1493 |
* Perhaps the most convenient way to implement this interface is to extend the abstract class
|
|
1494 |
* {@link ArbitrarilyJumpableGenerator}, which provides spliterator-based implementations of the
|
|
1495 |
* methods {@code ints}, {@code longs}, {@code doubles}, {@code rngs}, {@code jumps}, and
|
|
1496 |
* {@code leaps}.
|
|
1497 |
* <p>
|
|
1498 |
* Objects that implement {@link ArbitrarilyJumpableGenerator} are typically not
|
|
1499 |
* cryptographically secure. Consider instead using {@link java.security.SecureRandom} to get a
|
|
1500 |
* cryptographically secure pseudo-random number generator for use by security-sensitive
|
|
1501 |
* applications.
|
|
1502 |
*
|
|
1503 |
* @since 14
|
|
1504 |
*/
|
|
1505 |
public interface ArbitrarilyJumpableGenerator extends LeapableGenerator {
|
|
1506 |
|
|
1507 |
/**
|
|
1508 |
* Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
|
|
1509 |
* {@code name} algorithm.
|
|
1510 |
*
|
|
1511 |
* @param name Name of random number generator algorithm
|
|
1512 |
*
|
|
1513 |
* @return An instance of {@link ArbitrarilyJumpableGenerator}
|
|
1514 |
*/
|
|
1515 |
public static ArbitrarilyJumpableGenerator of(String name) {
|
|
1516 |
Objects.requireNonNull(name);
|
|
1517 |
return RandomGeneratorFactory.of(name, ArbitrarilyJumpableGenerator.class);
|
|
1518 |
}
|
|
1519 |
|
|
1520 |
/**
|
|
1521 |
* Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
|
|
1522 |
* specified {@code algorithm}.
|
|
1523 |
*
|
|
1524 |
* @param algorithm Random number generator algorithm
|
|
1525 |
*
|
|
1526 |
* @return An instance of {@link ArbitrarilyJumpableGenerator}
|
|
1527 |
*/
|
|
1528 |
public static ArbitrarilyJumpableGenerator of(Algorithm algorithm) {
|
|
1529 |
Objects.requireNonNull(algorithm);
|
|
1530 |
return RandomGeneratorFactory.of(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
|
|
1531 |
}
|
|
1532 |
|
|
1533 |
/**
|
|
1534 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1535 |
* of {@link ArbitrarilyJumpableGenerator} that utilizes the {@code name} algorithm.
|
|
1536 |
*
|
|
1537 |
* @param name Name of random number generator algorithm
|
|
1538 |
*
|
|
1539 |
* @return {@link RandomGeneratorFactory} of {@link ArbitrarilyJumpableGenerator}
|
|
1540 |
*/
|
|
1541 |
public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(String name) {
|
|
1542 |
Objects.requireNonNull(name);
|
|
1543 |
return RandomGeneratorFactory.factoryOf(name, ArbitrarilyJumpableGenerator.class);
|
|
1544 |
}
|
|
1545 |
|
|
1546 |
/**
|
|
1547 |
* Returns a {@link RandomGeneratorFactory} that can produce instances
|
|
1548 |
* of {@link ArbitrarilyJumpableGenerator} that utilizes the specified {@code algorithm}.
|
|
1549 |
*
|
|
1550 |
* @param algorithm Random number generator algorithm
|
|
1551 |
*
|
|
1552 |
* @return {@link RandomGeneratorFactory} of {@link ArbitrarilyJumpableGenerator}
|
|
1553 |
*/
|
|
1554 |
public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(Algorithm algorithm) {
|
|
1555 |
Objects.requireNonNull(algorithm);
|
|
1556 |
return RandomGeneratorFactory.factoryOf(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
|
|
1557 |
}
|
|
1558 |
|
|
1559 |
/**
|
|
1560 |
* Returns a new generator whose internal state is an exact copy of this generator (therefore
|
|
1561 |
* their future behavior should be identical if subjected to the same series of operations).
|
|
1562 |
*
|
|
1563 |
* @return a new object that is a copy of this generator
|
|
1564 |
*/
|
|
1565 |
ArbitrarilyJumpableGenerator copy();
|
|
1566 |
|
|
1567 |
/**
|
|
1568 |
* Alter the state of this pseudorandom number generator so as to jump forward a distance equal
|
|
1569 |
* to 2<sup>{@code logDistance}</sup> within its state cycle.
|
|
1570 |
*
|
|
1571 |
* @param logDistance the base-2 logarithm of the distance to jump forward within the state
|
|
1572 |
* cycle
|
|
1573 |
*
|
|
1574 |
* @throws IllegalArgumentException if {@code logDistance} is NaN or negative, or if
|
|
1575 |
* 2<sup>{@code logDistance}</sup> is greater than the period
|
|
1576 |
* of this generator
|
|
1577 |
*/
|
|
1578 |
void jumpPowerOfTwo(int logDistance);
|
|
1579 |
|
|
1580 |
/**
|
|
1581 |
* Alter the state of this pseudorandom number generator so as to jump forward a specified
|
|
1582 |
* distance within its state cycle.
|
|
1583 |
*
|
|
1584 |
* @param distance the distance to jump forward within the state cycle
|
|
1585 |
*
|
|
1586 |
* @throws IllegalArgumentException if {@code distance} is Nan, negative, or greater than the
|
|
1587 |
* period of this generator
|
|
1588 |
*/
|
|
1589 |
void jump(double distance);
|
|
1590 |
|
|
1591 |
/**
|
|
1592 |
* Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
|
|
1593 |
* distance (typically 2<sup>64</sup> or more) within its state cycle. The distance used is
|
|
1594 |
* that returned by method {@code defaultJumpDistance()}.
|
|
1595 |
*/
|
|
1596 |
default void jump() { jump(defaultJumpDistance()); }
|
|
1597 |
|
|
1598 |
/**
|
|
1599 |
* Returns an effectively unlimited stream of new pseudorandom number generators, each of
|
|
1600 |
* which implements the {@link ArbitrarilyJumpableGenerator} interface, produced by jumping
|
|
1601 |
* copies of this generator by different integer multiples of the specified jump distance.
|
|
1602 |
*
|
|
1603 |
* @param distance a distance to jump forward within the state cycle
|
|
1604 |
*
|
|
1605 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1606 |
*
|
|
1607 |
* @implNote This method is implemented to be equivalent to {@code jumps(Long.MAX_VALUE)}.
|
|
1608 |
*/
|
|
1609 |
default Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
|
|
1610 |
return Stream.generate(() -> copyAndJump(distance)).sequential();
|
|
1611 |
}
|
|
1612 |
|
|
1613 |
/**
|
|
1614 |
* Returns a stream producing the given {@code streamSize} number of new pseudorandom number
|
|
1615 |
* generators, each of which implements the {@link ArbitrarilyJumpableGenerator} interface,
|
|
1616 |
* produced by jumping copies of this generator by different integer multiples of the
|
|
1617 |
* specified jump distance.
|
|
1618 |
*
|
|
1619 |
* @param streamSize the number of generators to generate
|
|
1620 |
* @param distance a distance to jump forward within the state cycle
|
|
1621 |
*
|
|
1622 |
* @return a stream of objects that implement the {@link RandomGenerator} interface
|
|
1623 |
*
|
|
1624 |
* @throws IllegalArgumentException if {@code streamSize} is less than zero
|
|
1625 |
*/
|
|
1626 |
default Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
|
|
1627 |
return jumps(distance).limit(streamSize);
|
|
1628 |
}
|
|
1629 |
|
|
1630 |
/**
|
|
1631 |
* Alter the state of this pseudorandom number generator so as to jump forward a very large,
|
|
1632 |
* fixed distance (typically 2<sup>128</sup> or more) within its state cycle. The distance
|
|
1633 |
* used is that returned by method {@code defaultJLeapDistance()}.
|
|
1634 |
*/
|
|
1635 |
default void leap() { jump(defaultLeapDistance()); }
|
|
1636 |
|
|
1637 |
/**
|
|
1638 |
* Copy this generator, jump this generator forward, then return the copy.
|
|
1639 |
*
|
|
1640 |
* @param distance a distance to jump forward within the state cycle
|
|
1641 |
*
|
|
1642 |
* @return a copy of this generator object before the jump occurred
|
|
1643 |
*/
|
|
1644 |
default ArbitrarilyJumpableGenerator copyAndJump(double distance) {
|
|
1645 |
ArbitrarilyJumpableGenerator result = copy();
|
|
1646 |
jump(distance);
|
|
1647 |
return result;
|
|
1648 |
}
|
|
1649 |
|
|
1650 |
}
|
|
1651 |
}
|