Le jeu. 9 mai 2019 à 17:07, Alex Herbert <alex.d.herb...@gmail.com> a écrit :
>
>
> On 09/05/2019 15:46, Gilles Sadowski wrote:
> > Le jeu. 9 mai 2019 à 14:30, Alex Herbert <alex.d.herb...@gmail.com> a écrit 
> > :
> >>
> >>
> >>> On 9 May 2019, at 12:58, Gilles Sadowski <gillese...@gmail.com> wrote:
> >>>
> >>> Hi.
> >>>
> >>> Le jeu. 9 mai 2019 à 13:31, Alex Herbert <alex.d.herb...@gmail.com 
> >>> <mailto:alex.d.herb...@gmail.com>> a écrit :
> >>>> The Middle Square Weyl Sequence (MSWS) generator uses an internal Weyl 
> >>>> sequence [1] to create randomness. This is basically a linear increment 
> >>>> added to a sum that will eventually wrap (due to overflow) to restart at 
> >>>> the beginning. The MSWS paper recommends an increment with a high number 
> >>>> of different bits set in a random pattern across the 64-bit of the long. 
> >>>> The paper recommends using a permutation of 8 from the 16 hex digits for 
> >>>> the upper and lower 32-bits.
> >>>>
> >>>> The source code for the MSWS provides a routine that generates a 
> >>>> permutation. Unfortunately:
> >>>>
> >>>> - The code is GPL 3 so restricting it from use under the Apache licence 
> >>>> (without jumping through some hoops)
> >>>> - The algorithm is a simple rejection method that suffers from high 
> >>>> rejection probability when approaching 8 digits already chosen
> >>>>
> >>>> I have created an alternative faster implementation for use when seeding 
> >>>> the MSWS generator. However it may be a function to be reused in other 
> >>>> places.
> >>>>
> >>>> The question is where to put this utility function. It requires a source 
> >>>> of randomness to create the permutation. It has the following signature:
> >>>>
> >>>> /**
> >>>> * Creates an {@code int} containing a permutation of 8 hex digits chosen 
> >>>> from 16.
> >>>> *
> >>>> * @param rng Source of randomness.
> >>>> * @return Hex digit permutation.
> >>>> */
> >>>> public static int createIntHexPermutation(UniformRandomProvider rng);
> >>>>
> >>>> Likewise:
> >>>>
> >>>> /**
> >>>> * Creates a {@code long} containing a permutation of 8 hex digits chosen 
> >>>> from 16 in
> >>>> * the upper and lower 32-bits.
> >>>> *
> >>>> * @param rng Source of randomness.
> >>>> * @return Hex digit permutation.
> >>>> */
> >>>> public static long createLongHexPermutation(UniformRandomProvider rng);
> >>>>
> >>>> Options:
> >>>>
> >>>> - Put it as a package private function inside the MSWS generator to be 
> >>>> used only when creating this generator. Package private allows unit 
> >>>> testing the algorithm does provides the random permutation 16-choose-8
> >>>> - Put it as a helper function in org.apache.commons.rng.core.util
> >>> - In "SeedFactory" (?).
> >>>
> >>> For MSWS ("core" module), the increment would be an argument to the 
> >>> constructor
> >>> (allowing the user to shoot himself in the foot, like when passing a
> >>> bad seed), and
> >>> "RandomSource" ("simple" module) would offer to provide an instance
> >>> for which the
> >>> increment was computed according to the recommendation.
> >>
> >> OK. That makes it easier to build the reference implementation in Core as 
> >> it just matches the C reference code. I can add the seeding function to 
> >> SeedFactory in the Simple module. So if a user passes anything to be used 
> >> as the seed then it passes through unchanged (or converted). But if they 
> >> do not provide a seed then it should be generated appropriately.
> >>
> >> This means I should really get on with updating the RandomSourceInternal 
> >> and ProviderBuilder (RNG 75 [1]). It currently does not support creating 
> >> seeds based on the exact RandomSource. It just uses the native seed type 
> >> of the RandomSource. Here are the current use cases that should be handled:
> >>
> >> - MSWS recommends a seed with a permutation of hex digits.
> >> - XorShiRo family of generators all require seeds with at least some 
> >> non-zero elements.
> >>
> >> My idea was to target this part of the ProviderBuilder createSeed method:
> >>
> >> if (seed == null) {
> >>      // Create a random seed of the appropriate native type.
> >>
> >>      if (source.getSeed().equals(Integer.class)) {
> >>          nativeSeed = SeedFactory.createInt();
> >>      } else if (source.getSeed().equals(Long.class)) {
> >>          nativeSeed = SeedFactory.createLong();
> >>
> >>
> >> To change it to:
> >>
> >> if (seed == null) {
> >>      // Delegate to the source to create an appropriate seed (since it 
> >> knows best)
> >>      return source.createSeed()
> > But IIUC, that would mean that the code for computing the seed
> > is in "core", not "simple" (where "SeedFactory" is defined).
>
> Sorry, my code snippet was not fully qualified. This is from
>
> org.apache.commons.rng.simple.internal.ProviderBuilder.createSeed
>
> This is the place where a seed is currently made so your point is
> satisfied.

All fine then. :-)

> The current process for the seed creation is a bit limited. It just
> builds int, long, int[], or long[]. It is not currently able to build
> arrays of the correct length or build seeds with specific requirements
> based on the source. That is what I would like to change. So if the
> source was a MSWS then it would build the seed using the hex digit
> permutation method. If the source was a XorShiRo family it would build
> seeds with no zeros.
>
> My idea was to move the null seed creation pathway into
> RandomSourceInternal. So if the RandomSource has specific needs for the
> seed then the internal enum can override the default method to create
> the seed.

+1

Gilles

>
> > My point was that, even though the designer of the algorithm indeed
> > "knows best", the user should be allowed to pass any seed/increment
> > (even if it is "not recommended").
> > The "simple" API's role is to provide recommended values as defaults.
> >
> > Gilles
> >
> >> The RandomSourceInternal which already has knowledge of the native type of 
> >> the seed for the generator will be extended to know the length for array 
> >> seeds, and a default implementation of create for each native seed type 
> >> allowing override for generators with specific requirements.
> >>
> >> [1] https://issues.apache.org/jira/browse/RNG-75 
> >> <https://issues.apache.org/jira/browse/RNG-75>
> >>
> >>> Regards,
> >>> Gilles
> >>>
> >>>> Note that the function is an alternative to that used by the 
> >>>> SplittableRandom to create an increment for its own Weyl sequence. That 
> >>>> uses a fast method that is prone to weak randomness in potential output.
> >>>>
> >>>> If other methods will potentially be added to the helper class a more 
> >>>> generic name should be used. Possibilities are:
> >>>>
> >>>> PermutationUtils
> >>>> SequenceUtils
> >>>> IncrementUtils
> >>>> SeedUtils
> >>>>
> >>>> Given that the method is for seeding Weyl sequences then I am favouring 
> >>>> SeedUtils.
> >>>>
> >>>>
> >>>> [1] https://en.wikipedia.org/wiki/Weyl_sequence 
> >>>> <https://en.wikipedia.org/wiki/Weyl_sequence> 
> >>>> <https://en.wikipedia.org/wiki/Weyl_sequence 
> >>>> <https://en.wikipedia.org/wiki/Weyl_sequence>>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to