001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.rng; 018 019import java.util.stream.DoubleStream; 020import java.util.stream.IntStream; 021import java.util.stream.LongStream; 022 023/** 024 * Applies to generators of random number sequences that follow a uniform 025 * distribution. 026 * 027 * @since 1.0 028 */ 029public interface UniformRandomProvider { 030 /** 031 * Generates {@code byte} values and places them into a user-supplied array. 032 * 033 * <p>The number of random bytes produced is equal to the length of the byte array. 034 * 035 * @param bytes Byte array in which to put the random bytes. 036 * Cannot be {@code null}. 037 */ 038 default void nextBytes(byte[] bytes) { 039 UniformRandomProviderSupport.nextBytes(this, bytes, 0, bytes.length); 040 } 041 042 /** 043 * Generates {@code byte} values and places them into a user-supplied array. 044 * 045 * <p>The array is filled with bytes extracted from random integers. 046 * This implies that the number of random bytes generated may be larger than 047 * the length of the byte array. 048 * 049 * @param bytes Array in which to put the generated bytes. 050 * Cannot be {@code null}. 051 * @param start Index at which to start inserting the generated bytes. 052 * @param len Number of bytes to insert. 053 * @throws IndexOutOfBoundsException if {@code start < 0} or 054 * {@code start >= bytes.length}. 055 * @throws IndexOutOfBoundsException if {@code len < 0} or 056 * {@code len > bytes.length - start}. 057 */ 058 default void nextBytes(byte[] bytes, int start, int len) { 059 UniformRandomProviderSupport.validateFromIndexSize(start, len, bytes.length); 060 UniformRandomProviderSupport.nextBytes(this, bytes, start, len); 061 } 062 063 /** 064 * Generates an {@code int} value. 065 * 066 * @return the next random value. 067 */ 068 default int nextInt() { 069 return (int) (nextLong() >>> 32); 070 } 071 072 /** 073 * Generates an {@code int} value between 0 (inclusive) and the 074 * specified value (exclusive). 075 * 076 * @param n Bound on the random number to be returned. Must be positive. 077 * @return a random {@code int} value between 0 (inclusive) and {@code n} 078 * (exclusive). 079 * @throws IllegalArgumentException if {@code n} is not above zero. 080 */ 081 default int nextInt(int n) { 082 UniformRandomProviderSupport.validateUpperBound(n); 083 return UniformRandomProviderSupport.nextInt(this, n); 084 } 085 086 /** 087 * Generates an {@code int} value between the specified {@code origin} (inclusive) and 088 * the specified {@code bound} (exclusive). 089 * 090 * @param origin Lower bound on the random number to be returned. 091 * @param bound Upper bound (exclusive) on the random number to be returned. 092 * @return a random {@code int} value between {@code origin} (inclusive) and 093 * {@code bound} (exclusive). 094 * @throws IllegalArgumentException if {@code origin} is greater than or equal to 095 * {@code bound}. 096 * @since 1.5 097 */ 098 default int nextInt(int origin, int bound) { 099 UniformRandomProviderSupport.validateRange(origin, bound); 100 return UniformRandomProviderSupport.nextInt(this, origin, bound); 101 } 102 103 /** 104 * Generates a {@code long} value. 105 * 106 * @return the next random value. 107 */ 108 long nextLong(); 109 110 /** 111 * Generates a {@code long} value between 0 (inclusive) and the specified 112 * value (exclusive). 113 * 114 * @param n Bound on the random number to be returned. Must be positive. 115 * @return a random {@code long} value between 0 (inclusive) and {@code n} 116 * (exclusive). 117 * @throws IllegalArgumentException if {@code n} is not greater than 0. 118 */ 119 default long nextLong(long n) { 120 UniformRandomProviderSupport.validateUpperBound(n); 121 return UniformRandomProviderSupport.nextLong(this, n); 122 } 123 124 /** 125 * Generates a {@code long} value between the specified {@code origin} (inclusive) and 126 * the specified {@code bound} (exclusive). 127 * 128 * @param origin Lower bound on the random number to be returned. 129 * @param bound Upper bound (exclusive) on the random number to be returned. 130 * @return a random {@code long} value between {@code origin} (inclusive) and 131 * {@code bound} (exclusive). 132 * @throws IllegalArgumentException if {@code origin} is greater than or equal to 133 * {@code bound}. 134 * @since 1.5 135 */ 136 default long nextLong(long origin, long bound) { 137 UniformRandomProviderSupport.validateRange(origin, bound); 138 return UniformRandomProviderSupport.nextLong(this, origin, bound); 139 } 140 141 /** 142 * Generates a {@code boolean} value. 143 * 144 * @return the next random value. 145 */ 146 default boolean nextBoolean() { 147 return nextInt() < 0; 148 } 149 150 /** 151 * Generates a {@code float} value between 0 (inclusive) and 1 (exclusive). 152 * 153 * @return the next random value between 0 (inclusive) and 1 (exclusive). 154 */ 155 default float nextFloat() { 156 return (nextInt() >>> 8) * 0x1.0p-24f; 157 } 158 159 /** 160 * Generates a {@code float} value between 0 (inclusive) and the 161 * specified {@code bound} (exclusive). 162 * 163 * @param bound Upper bound (exclusive) on the random number to be returned. 164 * @return a random {@code float} value between 0 (inclusive) and {@code bound} 165 * (exclusive). 166 * @throws IllegalArgumentException if {@code bound} is not both finite and greater than 0. 167 * @since 1.5 168 */ 169 default float nextFloat(float bound) { 170 UniformRandomProviderSupport.validateUpperBound(bound); 171 return UniformRandomProviderSupport.nextFloat(this, bound); 172 } 173 174 /** 175 * Generates a {@code float} value between the specified {@code origin} (inclusive) 176 * and the specified {@code bound} (exclusive). 177 * 178 * @param origin Lower bound on the random number to be returned. 179 * @param bound Upper bound (exclusive) on the random number to be returned. 180 * @return a random {@code float} value between {@code origin} (inclusive) and 181 * {@code bound} (exclusive). 182 * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound} 183 * is not finite, or {@code origin} is greater than or equal to {@code bound}. 184 * @since 1.5 185 */ 186 default float nextFloat(float origin, float bound) { 187 UniformRandomProviderSupport.validateRange(origin, bound); 188 return UniformRandomProviderSupport.nextFloat(this, origin, bound); 189 } 190 191 /** 192 * Generates a {@code double} value between 0 (inclusive) and 1 (exclusive). 193 * 194 * @return the next random value between 0 (inclusive) and 1 (exclusive). 195 */ 196 default double nextDouble() { 197 return (nextLong() >>> 11) * 0x1.0p-53; 198 } 199 200 /** 201 * Generates a {@code double} value between 0 (inclusive) and the 202 * specified {@code bound} (exclusive). 203 * 204 * @param bound Upper bound (exclusive) on the random number to be returned. 205 * @return a random {@code double} value between 0 (inclusive) and {@code bound} 206 * (exclusive). 207 * @throws IllegalArgumentException if {@code bound} is not both finite and greater than 0. 208 * @since 1.5 209 */ 210 default double nextDouble(double bound) { 211 UniformRandomProviderSupport.validateUpperBound(bound); 212 return UniformRandomProviderSupport.nextDouble(this, bound); 213 } 214 215 /** 216 * Generates a {@code double} value between the specified {@code origin} (inclusive) 217 * and the specified {@code bound} (exclusive). 218 * 219 * @param origin Lower bound on the random number to be returned. 220 * @param bound Upper bound (exclusive) on the random number to be returned. 221 * @return a random {@code double} value between {@code origin} (inclusive) and 222 * {@code bound} (exclusive). 223 * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound} 224 * is not finite, or {@code origin} is greater than or equal to {@code bound}. 225 * @since 1.5 226 */ 227 default double nextDouble(double origin, double bound) { 228 UniformRandomProviderSupport.validateRange(origin, bound); 229 return UniformRandomProviderSupport.nextDouble(this, origin, bound); 230 } 231 232 /** 233 * Returns an effectively unlimited stream of {@code int} values. 234 * 235 * @return a stream of random {@code int} values. 236 * @since 1.5 237 */ 238 default IntStream ints() { 239 return IntStream.generate(this::nextInt).sequential(); 240 } 241 242 /** 243 * Returns an effectively unlimited stream of {@code int} values between the specified 244 * {@code origin} (inclusive) and the specified {@code bound} (exclusive). 245 * 246 * @param origin Lower bound on the random number to be returned. 247 * @param bound Upper bound (exclusive) on the random number to be returned. 248 * @return a stream of random values between the specified {@code origin} (inclusive) 249 * and the specified {@code bound} (exclusive). 250 * @throws IllegalArgumentException if {@code origin} is greater than or equal to 251 * {@code bound}. 252 * @since 1.5 253 */ 254 default IntStream ints(int origin, int bound) { 255 UniformRandomProviderSupport.validateRange(origin, bound); 256 return IntStream.generate(() -> nextInt(origin, bound)).sequential(); 257 } 258 259 /** 260 * Returns a stream producing the given {@code streamSize} number of {@code int} 261 * values. 262 * 263 * @param streamSize Number of values to generate. 264 * @return a stream of random {@code int} values; the stream is limited to the given 265 * {@code streamSize}. 266 * @throws IllegalArgumentException if {@code streamSize} is negative. 267 * @since 1.5 268 */ 269 default IntStream ints(long streamSize) { 270 UniformRandomProviderSupport.validateStreamSize(streamSize); 271 return ints().limit(streamSize); 272 } 273 274 /** 275 * Returns a stream producing the given {@code streamSize} number of {@code int} 276 * values between the specified {@code origin} (inclusive) and the specified 277 * {@code bound} (exclusive). 278 * 279 * @param streamSize Number of values to generate. 280 * @param origin Lower bound on the random number to be returned. 281 * @param bound Upper bound (exclusive) on the random number to be returned. 282 * @return a stream of random values between the specified {@code origin} (inclusive) 283 * and the specified {@code bound} (exclusive); the stream is limited to the given 284 * {@code streamSize}. 285 * @throws IllegalArgumentException if {@code streamSize} is negative, or if 286 * {@code origin} is greater than or equal to {@code bound}. 287 * @since 1.5 288 */ 289 default IntStream ints(long streamSize, int origin, int bound) { 290 UniformRandomProviderSupport.validateStreamSize(streamSize); 291 UniformRandomProviderSupport.validateRange(origin, bound); 292 return ints(origin, bound).limit(streamSize); 293 } 294 295 /** 296 * Returns an effectively unlimited stream of {@code long} values. 297 * 298 * @return a stream of random {@code long} values. 299 * @since 1.5 300 */ 301 default LongStream longs() { 302 return LongStream.generate(this::nextLong).sequential(); 303 } 304 305 /** 306 * Returns an effectively unlimited stream of {@code long} values between the 307 * specified {@code origin} (inclusive) and the specified {@code bound} (exclusive). 308 * 309 * @param origin Lower bound on the random number to be returned. 310 * @param bound Upper bound (exclusive) on the random number to be returned. 311 * @return a stream of random values between the specified {@code origin} (inclusive) 312 * and the specified {@code bound} (exclusive). 313 * @throws IllegalArgumentException if {@code origin} is greater than or equal to 314 * {@code bound}. 315 * @since 1.5 316 */ 317 default LongStream longs(long origin, long bound) { 318 UniformRandomProviderSupport.validateRange(origin, bound); 319 return LongStream.generate(() -> nextLong(origin, bound)).sequential(); 320 } 321 322 /** 323 * Returns a stream producing the given {@code streamSize} number of {@code long} 324 * values. 325 * 326 * @param streamSize Number of values to generate. 327 * @return a stream of random {@code long} values; the stream is limited to the given 328 * {@code streamSize}. 329 * @throws IllegalArgumentException if {@code streamSize} is negative. 330 * @since 1.5 331 */ 332 default LongStream longs(long streamSize) { 333 UniformRandomProviderSupport.validateStreamSize(streamSize); 334 return longs().limit(streamSize); 335 } 336 337 /** 338 * Returns a stream producing the given {@code streamSize} number of {@code long} 339 * values between the specified {@code origin} (inclusive) and the specified 340 * {@code bound} (exclusive). 341 * 342 * @param streamSize Number of values to generate. 343 * @param origin Lower bound on the random number to be returned. 344 * @param bound Upper bound (exclusive) on the random number to be returned. 345 * @return a stream of random values between the specified {@code origin} (inclusive) 346 * and the specified {@code bound} (exclusive); the stream is limited to the given 347 * {@code streamSize}. 348 * @throws IllegalArgumentException if {@code streamSize} is negative, or if 349 * {@code origin} is greater than or equal to {@code bound}. 350 * @since 1.5 351 */ 352 default LongStream longs(long streamSize, long origin, long bound) { 353 UniformRandomProviderSupport.validateStreamSize(streamSize); 354 UniformRandomProviderSupport.validateRange(origin, bound); 355 return longs(origin, bound).limit(streamSize); 356 } 357 358 /** 359 * Returns an effectively unlimited stream of {@code double} values between 0 360 * (inclusive) and 1 (exclusive). 361 * 362 * @return a stream of random values between 0 (inclusive) and 1 (exclusive). 363 * @since 1.5 364 */ 365 default DoubleStream doubles() { 366 return DoubleStream.generate(this::nextDouble).sequential(); 367 } 368 369 /** 370 * Returns an effectively unlimited stream of {@code double} values between the 371 * specified {@code origin} (inclusive) and the specified {@code bound} (exclusive). 372 * 373 * @param origin Lower bound on the random number to be returned. 374 * @param bound Upper bound (exclusive) on the random number to be returned. 375 * @return a stream of random values between the specified {@code origin} (inclusive) 376 * and the specified {@code bound} (exclusive). 377 * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound} 378 * is not finite, or {@code origin} is greater than or equal to {@code bound}. 379 * @since 1.5 380 */ 381 default DoubleStream doubles(double origin, double bound) { 382 UniformRandomProviderSupport.validateRange(origin, bound); 383 return DoubleStream.generate(() -> nextDouble(origin, bound)).sequential(); 384 } 385 386 /** 387 * Returns a stream producing the given {@code streamSize} number of {@code double} 388 * values between 0 (inclusive) and 1 (exclusive). 389 * 390 * @param streamSize Number of values to generate. 391 * @return a stream of random values between 0 (inclusive) and 1 (exclusive); 392 * the stream is limited to the given {@code streamSize}. 393 * @throws IllegalArgumentException if {@code streamSize} is negative. 394 * @since 1.5 395 */ 396 default DoubleStream doubles(long streamSize) { 397 UniformRandomProviderSupport.validateStreamSize(streamSize); 398 return doubles().limit(streamSize); 399 } 400 401 /** 402 * Returns a stream producing the given {@code streamSize} number of {@code double} 403 * values between the specified {@code origin} (inclusive) and the specified 404 * {@code bound} (exclusive). 405 * 406 * @param streamSize Number of values to generate. 407 * @param origin Lower bound on the random number to be returned. 408 * @param bound Upper bound (exclusive) on the random number to be returned. 409 * @return a stream of random values between the specified {@code origin} (inclusive) 410 * and the specified {@code bound} (exclusive); the stream is limited to the given 411 * {@code streamSize}. 412 * @throws IllegalArgumentException if {@code streamSize} is negative, or if 413 * {@code origin} is not finite, or {@code bound} is not finite, or {@code origin} is 414 * greater than or equal to {@code bound}. 415 * @since 1.5 416 */ 417 default DoubleStream doubles(long streamSize, double origin, double bound) { 418 UniformRandomProviderSupport.validateStreamSize(streamSize); 419 UniformRandomProviderSupport.validateRange(origin, bound); 420 return doubles(origin, bound).limit(streamSize); 421 } 422}