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

Alex D Herbert commented on RNG-97:
-----------------------------------

Following a discussion on the dev mailing list the following changes have been 
made:
 # The jump returns a copy of the *current* state
 # The returned copy is demoted to the UniformRandomProvider interface

The demotion to UniformRandomProvider is to suggest that the returned instance 
is not to be used for more jumps. If the returned copy was jumped it would then 
match the state of the parent and output would overlap.

This effectively turns the jump() method into a generator of RNGs that are 
uniformly spaced along the parent generator's output sequence.
{code:java}
/**
 * Applies to generators that can be advanced a large number of 
 * steps of the output sequence in a single operation.
 */
public interface JumpableUniformRandomProvider
    extends UniformRandomProvider {
    /**
     * Creates a copy of the UniformRandomProvider and then advances the
     * state of the current instance. The copy is returned.
     *
     * <p>The current state will be advanced in a single operation by the 
equivalent of a
     * number of sequential calls to a method that updates the state of the 
provider. The
     * size of the jump is implementation-dependent.</p>
     *
     * <p>Repeat invocations of this method will create a series of generators
     * that are uniformly spaced at intervals of the output sequence. Each 
generator provides
     * non-overlapping output for the length of the jump for use in parallel 
computations.</p>
     *
     * @return A copy of the current state.
     */
    UniformRandomProvider jump();
}
{code}
Implementing class with a period of 2^256^ and a jump size of 2^128^:
{code:java}
public class JumpableRNG implements JumpableUniformRandomProvider {
    /**
     * {@inheritDoc}
     *
     * <p>The jump size is the equivalent of 2<sup>128</sup>
     * calls to {@link UniformRandomProvider#nextLong() nextLong()}. It can 
provide
     * up to 2<sup>128</sup> non-overlapping subsequences.</p>
     */
    @Override
    public UniformRandomProvider jump() {
        UniformRandomProvider copy = copy(this);
        // Do the jump ...
        return copy;
    }

    // etc.
}
{code}

> JumpableUniformRandomProvider
> -----------------------------
>
>                 Key: RNG-97
>                 URL: https://issues.apache.org/jira/browse/RNG-97
>             Project: Commons RNG
>          Issue Type: New Feature
>          Components: client-api, core
>    Affects Versions: 1.3
>            Reporter: Alex D Herbert
>            Assignee: Alex D Herbert
>            Priority: Major
>             Fix For: 1.3
>
>
> A feature of random number generators is their internal state is updated for 
> every generation of a new random number. This is a single step. Some 
> generators have the ability to compute the update to the state that is 
> required to advance *{{n}}* steps. This is a jump. This can be supported 
> using a new interface:
> {code:java}
> /**
>  * Applies to generators that can be advanced a large number of 
>  * steps of the output sequence in a single operation.
>  */
> public interface JumpableUniformRandomProvider
>     extends UniformRandomProvider {
>     /**
>      * Creates a copy of the UniformRandomProvider and advances the
>      * state of the copy. The state of the current instance is not altered. 
>      * The state of the copy will be advanced an equivalent of {@code n}
>      * sequential calls to a method that updates the state of the provider.
>      *
>      * @return the copy with an advanced state
>      */
>     JumpableUniformRandomProvider jump();
> }
> {code}
> A suggestion for how to document an implementation is:
> {code:java}
> public class JumpableRNG implements JumpableUniformRandomProvider {
>     /**
>      * {@inheritDoc}
>      *
>      * <p>The jump size {@code n} is the equivalent of 
> <pre>2<sup>32</sup></pre>
>      * calls to {@link UniformRandomProvider#nextLong() nextLong()}.</p>
>      */
>     @Override
>     public JumpableUniformRandomProvider jump() {
>         return ...;
>     }
>     // etc.
> }
> {code}
> Notes on the interface:
>  * A copy is returned
>  * The original is not altered and so multiple calls to jump will return the 
> same generator with an advanced state
> The intended use case is to create multiple copies of a RNG that will not 
> overlap in sequence for use in parallel computations. A helper method can be 
> added to {{RandomSource}} to facilitate this:
> {code:java}
> /**
>  * Create a series of {@code n} generators by jumping from the source 
> generator
>  * {@code n} times. The resulting set of generators can be used in parallel
>  * computations with a guarantee of no sequence overlap for at least the
>  * length of the jump distance.
>  *
>  * <p>Note: The source generator state is not affected. Reuse of this
>  * generator may overlap with output from the jump series.</p>
>  *
>  * @param source The source generator.
>  * @param n The size of the series.
>  */
> public static UniformRandomProvider[] createJumpSeries(
>         JumpableUniformRandomProvider source, int n) {
>     if (n <= 0) {
>         throw new IllegalArgumentException("Size must be strictly positive");
>     }
>     final UniformRandomProvider[] rngs = new UniformRandomProvider[n];
>     for (int i = 0; i < n; i++) {
>         source = source.jump();
>         // Option to wrap the JumpableUniformRandomProvider to
>         // restrict to the functionality of UniformRandomProvider
>         rngs[i] = source;
>     }
>     return rngs;
> }
> {code}
> Note: There is the possibility to wrap the jumped RNGs to restrict their 
> functionality to UniformRandomProvider (or RestorableUniformRandomProvider). 
> This prevents any of the series from being jumped again.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to