You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Alex Herbert (Jira)" <ji...@apache.org> on 2022/09/02 19:21:00 UTC

[jira] [Commented] (RNG-180) New SplittableUniformRandomProvider interface

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

Alex Herbert commented on RNG-180:
----------------------------------

I have created an initial implementation for this but noticed a place for a minor API change.
h2. Implementation Note

The JDK interface defines an equivalent to this method:
{code:java}
/**
 * Creates a new random generator, split off from this one, that implements
 * the {@link SplittableUniformRandomProvider} interface.
 *
 * @param source A source of randomness used to initialise the new instance.
 * @return A new instance.
 * @throws NullPointerException if {@code source} is null
 */
SplittableUniformRandomProvider split(SplittableUniformRandomProvider source); {code}
I do not understand why the source is splittable. The source is to be used to seed the next instance. There appears to be no requirement during seeding a RNG to have the input source of random bits be splittable.

I understand for the streaming methods it makes sense for the source to be splittable, e.g.
{code:java}
Stream<SplittableUniformRandomProvider> splits(SplittableUniformRandomProvider source) {code}
Here the source can be split for use in a parallel stream. Each split instance can be the source of bits for generators created on each thread. However for a single one-time split it seems that a more generic method would be to accept a UniformRandomProvider:
{code:java}
SplittableUniformRandomProvider split(UniformRandomProvider source); {code}
This allows any RNG from the Commons library to be used as the source of bits to seed a split. This can even use Random instances from the JDK via a wrapper:
{code:java}
SplittableUniformRandomProvider g1 = ...;
SplittableUniformRandomProvider g2 = g1.split(new JDKRandomWrapper(new SecureRandom())); {code}

> New SplittableUniformRandomProvider interface
> ---------------------------------------------
>
>                 Key: RNG-180
>                 URL: https://issues.apache.org/jira/browse/RNG-180
>             Project: Commons RNG
>          Issue Type: New Feature
>          Components: client-api, core
>    Affects Versions: 1.5
>            Reporter: Alex Herbert
>            Assignee: Alex Herbert
>            Priority: Major
>             Fix For: 1.5
>
>
> The minimum java version for RNG is now 1.8. Stream support has been added for the UniformRandomProvider and Sampler interfaces. These all operate using a sequential stream. To use a parallel stream requires the concept of splitting the source of randomness.
> I propose to add a Splittable interface. This can be modelled on the interface in the JDK 17 random package [SplittableGenerator (javadoc)|https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/random/RandomGenerator.SplittableGenerator.html]:
> {code:java}
> public interface SplittableUniformRandomProvider 
>     extends UniformRandomProvider {
>     SplittableUniformRandomProvider split();
>     SplittableUniformRandomProvider split(SplittableUniformRandomProvider source);
>     Stream<SplittableUniformRandomProvider> splits();
>     Stream<SplittableUniformRandomProvider> splits(SplittableUniformRandomProvider source);
>     Stream<SplittableUniformRandomProvider> splits(long streamSize);
>     Stream<SplittableUniformRandomProvider> splits(long streamSize,
>         SplittableUniformRandomProvider source);
> {code}
> The JDK interface has both a split and split(source) method, and similar for the stream created by repeat splitting. The source is to provide the random bits to initialise the new instances. In most cases this will just be the current instance. However it provides a means to provide a small state splittable generator for the random source of bits and use a larger state generator to provide new instances from those bits, or vice versa. This allows more flexibility to control the source of random bits, and the instance type of the new split generators.
> Note: It is possible to implement the entire interface using default methods except:
> {code:java}
>     SplittableUniformRandomProvider split(SplittableUniformRandomProvider source);
> {code}
> The stream can be created by recursively splitting the current instance via a custom Spliterator<SplittableUniformRandomProvider>.
> Also note that the stream methods in UniformRandomProvider can be overridden to support parallel streams. This requires for example a custom Spliterator.OfInt to split the generator for parallel generation.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)