[ 
https://issues.apache.org/jira/browse/RNG-127?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17314804#comment-17314804
 ] 

Alex Herbert commented on RNG-127:
----------------------------------

A brief overview of the new JDK API obtained using the specification downloaded 
from JDK-8255395.

The main RandomGenerator interface is specified using default methods. An 
implementation need only provide the nextLong method. This method is used as 
the random bits to provide all other method implementations for byte[], 
boolean, int, float, double and long with and without bounds; Streams of 
double, int or long; and Gaussian and exponential samples.
{code:java}
public interface RandomGenerator {
    long nextLong();
}{code}
Specialisations are sub-interfaces of RandomGenerator. The following is not a 
complete API specification as some default methods have been omitted for 
brevity:
{code:java}
public interface RandomGenerator.StreamableGenerator extends
        RandomGenerator {
    Stream<RandomGenerator> rngs();
}
public interface RandomGenerator.SplittableGenerator extends
        RandomGenerator.StreamableGenerator {
    RandomGenerator.SplittableGenerator split();
    RandomGenerator.SplittableGenerator 
split​(RandomGenerator.SplittableGenerator source);
    default Stream<RandomGenerator.SplittableGenerator> splits​();
    Stream<RandomGenerator.SplittableGenerator> splits​(long streamSize);
    Stream<RandomGenerator.SplittableGenerator> 
splits​(RandomGenerator.SplittableGenerator source)
    Stream<RandomGenerator.SplittableGenerator> splits​(long streamSize,
        RandomGenerator.SplittableGenerator source)
}
public interface RandomGenerator.JumpableGenerator extends
        RandomGenerator.StreamableGenerator {
    RandomGenerator.JumpableGenerator copy();
    /** Alter the state of this pseudorandom number generator so as to jump 
forward a large,
    /* fixed distance (typically 2^64 or more) within its state cycle. */
    void jump();
    double jumpDistance();
    default RandomGenerator.RandomGenerator copyAndJump();
    default Stream<RandomGenerator.RandomGenerator> jumps();
    default Stream<RandomGenerator.RandomGenerator> jumps​(long streamSize);
}
public interface RandomGenerator.LeapableGenerator extends
        RandomGenerator.JumpableGenerator, RandomGenerator.StreamableGenerator {
    RandomGenerator.LeapableGenerator copy();
    /** Alter the state of this pseudorandom number generator so as to jump 
forward a large,
    /* fixed distance (typically 2^96 or more) within its state cycle. */
    void leap();
    double leapDistance();
    default RandomGenerator.JumpableGenerator copyAndLeap();
    default Stream<RandomGenerator.JumpableGenerator> leaps();
    default Stream<RandomGenerator.JumpableGenerator> leaps​(long streamSize);
}
public interface RandomGenerator.ArbitrarilyJumpableGenerator extends
        RandomGenerator.JumpableGenerator, RandomGenerator.LeapableGenerator, 
        RandomGenerator.StreamableGenerator {
    RandomGenerator.ArbitrarilyJumpableGenerator copy();
    /** Alter the state of this pseudorandom number generator so as to jump 
forward a large,
    /* fixed distance (typically 2^64 or more) within its state cycle. */
    void jump();
    void jump​(double distance);
    void jumpPowerOfTwo​(int logDistance);
    /** Alter the state of this pseudorandom number generator so as to jump 
forward a large,
    /* fixed distance (typically 2^128 or more) within its state cycle. */
    void leap();
    default RandomGenerator.ArbitrarilyJumpableGenerator copyAndJump();
    default Stream<RandomGenerator.ArbitrarilyJumpableGenerator> jumps​(double 
distance);
    default Stream<RandomGenerator.ArbitrarilyJumpableGenerator> jumps​(long 
streamSize,
        double distance);
}
{code}
The SplittableGenerator is not covered by the commons API. A previous 
discussion on the mailing list concluded that this functionality is suitable 
for occasions where you may want to use multi-threading but are not sure of the 
number of threads and how many random numbers will be used by each thread. Thus 
you require a RNG that can arbitrarily create new RNGs that should not overlap 
within their period. The main use is within parallel streams created by 
splitting which is a Java 8 feature and not applicable to commons RNG (which is 
Java 6).

The jumpable interfaces seem to be an approximate match to our current 
functionality:
{code:java}
public interface JumpableUniformRandomProvider extends UniformRandomProvider {
    UniformRandomProvider jump();
}
public interface LongJumpableUniformRandomProvider extends 
JumpableUniformRandomProvider {
    JumpableUniformRandomProvider longJump();
}
{code}
The difference is that Commons RNG has deliberately avoided the provision of a 
copy method and specifies that a jump return a provider capable of smaller 
jumps but not the same size jumps, thus avoiding child generators being able to 
jump into part of the period that has been allocated to another child generator 
from a subsequent jump. The JDK API has copy, jump and copyAndJump (or leap) 
returning a RNG of the same type. This is more flexible but can lead to 
generators being created and used to jump into the same period interval as 
others:
{noformat}
Leaps: |=================|=================|=================|
Jumps: |--------|--------|--------|--------|--------|--------|

Leap-Jump:
       |=================|
                          --------|
Leap-Leap-Jump:
       |=================|=================|
                                            --------| 
Leap-Jump-Leap:
       |=================|
                          --------|
                                   =================|

{noformat}

> Assess future compatibility with JEP 356: Enhanced Pseudo-Random Number 
> Generators 
> -----------------------------------------------------------------------------------
>
>                 Key: RNG-127
>                 URL: https://issues.apache.org/jira/browse/RNG-127
>             Project: Commons RNG
>          Issue Type: Task
>          Components: client-api
>    Affects Versions: 1.3
>            Reporter: Alex Herbert
>            Priority: Minor
>
> JEP 356 specifies an enhancement to the random number generators. This is 
> targeted to JDK 17.
> [JEP 356: Enhanced Pseudo-Random Number 
> Generators|https://openjdk.java.net/jeps/356]
> The enhancement will add interfaces to the JDK for random number generation:
>  * SplittableRandomGenerator extends RandomGenerator and also provides
>  methods named split and splits. Splittability allows the user to spawn a new 
> RandomGenerator from an existing RandomGenerator that will generally produce 
> statistically independent results.
>  * JumpableRandomGenerator extends RandomGenerator and also provides
>  methods named jump and jumps. Jumpability allows a user to jump ahead a 
> moderate number of draws.
>  * LeapableRandomGenerator extends RandomGenerator and also provides
>  methods named leap and leaps. Leapability allows a user to jump ahead a 
> large number of draws.
>  * ArbitrarilyJumpableRandomGenerator extends LeapableRandomGenerator and 
> also provides additional variations of jump and jumps that allow an arbitrary 
> jump distance to be specified.
> The specification describes the development of abstract classes that would 
> allow different algorithms to be easily implemented by developers and used 
> with a Java application through a common interface. This would replicate the 
> functionality of the Common RNG API and core modules within the JDK.
> The JDK interfaces should be compared with the current client API in Commons 
> RNG with the aim to assess:
>  # Compatibility
>  # Potential to back-port functionality
> JEP 356 also mentions the implementation of the LXM family of RNGs and a 
> change to the algorithm used by SplittableRandom to address two weaknesses 
> identified in 2016. These could be included in the current codebase pending 
> license compatibility checks.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to