Alex Herbert created RNG-176:
--------------------------------

             Summary: Enhance the UniformRandomProvider interface with extra 
methods and default implementations
                 Key: RNG-176
                 URL: https://issues.apache.org/jira/browse/RNG-176
             Project: Commons RNG
          Issue Type: New Feature
    Affects Versions: 1.4
            Reporter: Alex Herbert
            Assignee: Alex Herbert


JDK 17 introduced the {{RandomGenerator}} interface with the following methods:
{code:java}
DoubleStream doubles();
DoubleStream doubles(double randomNumberOrigin, double randomNumberBound);
DoubleStream doubles(long streamSize);
DoubleStream doubles(long streamSize, double randomNumberOrigin,
                     double randomNumberBound);

IntStream ints();
IntStream ints(int randomNumberOrigin, int randomNumberBound);
IntStream ints(long streamSize);
IntStream ints(long streamSize, int randomNumberOrigin,
               int randomNumberBound);

LongStream longs();
LongStream longs(long randomNumberOrigin, long randomNumberBound);
LongStream longs(long streamSize);
LongStream longs(long streamSize, long randomNumberOrigin,
                 long randomNumberBound);

boolean nextBoolean();

void nextBytes(byte[] bytes);

float nextFloat();
float nextFloat(float bound);
float nextFloat(float origin, float bound);

double nextDouble();
double nextDouble(double bound);
double nextDouble(double origin, double bound);

int nextInt();
int nextInt(int bound);
int nextInt(int origin, int bound);

long nextLong();
long nextLong(long bound);
long nextLong(long origin, long bound);

double nextGaussian();
double nextGaussian(double mean, double stddev);

double nextExponential();
{code}
The only method that is *non-default* is {{{}nextLong{}}}. This allows a new 
generator to be simply implemented by providing the source of randomness as 
64-bit longs.

The {{UniformRandomProvider}} interface can be expanded to include these 
generation methods. Using Java 8 default interface methods will not require any 
changes to generators currently implementing the interface.

I propose to:
 # Add the new methods for streams and numbers in a range.
 # Add default implementations of the current API. These can be extracted from 
the  o.a.c.rng.core.BaseProvider implementations.
 # Remove the implementations in o.a.c.rng.core.BaseProvider. This change would 
be binary compatible.

The base classes in commons core for 32-bit and 64-bit sources of randomness, 
IntProvider and LongProvider, can be updated suitably to only override the 
default interface methods where they can be more efficiently implemented given 
the source of randomness. This applies to:
||Source||Update||Details||
|int|nextBytes|Use nextInt() for the source of bytes|
| |nextBoolean|Use a cached int for the randomness|
| |nextInt|Directly supply the int rather than using 32-bits from nextLong()|
| |nextDouble|Optimise the bits used from two ints for the 53-bits required for 
the double.|
|long|nextInt; nextBoolean|Use a cached long for the randomness|
h3. Note 1

The UniformRandomProvider also has the method:
{code:java}
void nextBytes(byte[] bytes,
               int start,
               int len);
{code}
This can also have a default implementation using the output from nextLong().
h3. Note 2

The methods to generate an exponential and Gaussian are already implemented in 
the {{commons-rng-sampling}} module.

java.util.Random has a nextGaussian() method and so this method appears to be 
for backward compatibility with legacy Java code. The method is implemented 
using a modified Ziggurat sampler which uses an exponential sampler for the 
long tail. The API has thus exposed the exponential sampling method that is 
used internally in the nextGaussian implementation.

With no backward compatibility requirements the Commons RNG interface can avoid 
the distribution sampling methods. Users should select an appropriate sampler 
from the sampling module.

 



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to