Hello Alex.

Le mer. 13 mars 2019 à 15:37, Alex Herbert <alex.d.herb...@gmail.com> a écrit :
>
> On 13/03/2019 02:20, Gilles Sadowski wrote:
> > Le mar. 12 mars 2019 à 22:34, Alex Herbert <alex.d.herb...@gmail.com> a 
> > écrit :
> >>
> >>
> >>> On 12 Mar 2019, at 17:12, Gilles Sadowski <gillese...@gmail.com> wrote:
> >>>
> >>> [Replying to list.]
> >>>
> >>> Le mar. 12 mars 2019 à 15:39, Alex Herbert <alex.d.herb...@gmail.com 
> >>> <mailto:alex.d.herb...@gmail.com>> a écrit :
> >>>>
> >>>> On 12/03/2019 15:33, Gilles Sadowski wrote:
> >>>>
> >>>> Hi Alex.
> >>>>
> >>>> Le mar. 12 mars 2019 à 12:53, Alex Herbert <alex.d.herb...@gmail.com> a 
> >>>> écrit :
> >>>>
> >>>> On 11/03/2019 23:44, Gilles Sadowski wrote:
> >>>>
> >>>> Hello.
> >>>>
> >>>> Le jeu. 7 mars 2019 à 00:44, Alex Herbert <alex.d.herb...@gmail.com> a 
> >>>> écrit :
> >>>>
> >>>> On 6 Mar 2019, at 22:57, Gilles Sadowski <gillese...@gmail.com> wrote:
> >>>>
> >>>> However I will test if XorShift1024Star and XorShift1024StarPhi are 
> >>>> correlated just for completeness.
> >>>>
> >>>> Did a test of 100 repeats of a correlation of 50 longs from the 
> >>>> XorShift1024Star and XorShift1024StarPhi, new seed each time:
> >>>>
> >>>> SummaryStatistics:
> >>>> n: 100
> >>>> min: -0.30893547071559685
> >>>> max: 0.37616626218398586
> >>>> sum: 3.300079237520435
> >>>> mean: 0.033000792375204355
> >>>> geometric mean: NaN
> >>>> variance: 0.022258533475114764
> >>>> population variance: 0.022035948140363616
> >>>> second moment: 2.2035948140363617
> >>>> sum of squares: 2.312500043775496
> >>>> standard deviation: 0.14919294043323486
> >>>> sum of logs: NaN
> >>>>
> >>>> Note that the algorithm is the same except the final step when the 
> >>>> multiplier is used to scale the final output long:
> >>>>
> >>>>    return state[index] * multiplier;
> >>>>
> >>>> So if it was outputting a double the correlation would be 1. But it is a 
> >>>> long generator so the long arithmetic wraps to negative on large 
> >>>> multiplications. The result is that the mean correlation is close to 0.
> >>>>
> >>>> A single repeat using 1,000,000 numbers has a correlation of 0.002.
> >>>>
> >>>> Am I missing something here with this type of test?
> >>>>
> >>>> I'm afraid I don't follow: If the state is the same then I'd assume that
> >>>> the two generators are the same (i.e. totally correlated).
> >>>>
> >>>> The state is totally correlated (it is identical). The output sequence 
> >>>> is not due to wrapping in long arithmetic. Here’s a mock example:
> >>>>
> >>>> positive number * medium positive number = big positive number (close to 
> >>>> Long.MAX_VALUE)
> >>>>
> >>>> Vs
> >>>>
> >>>> positive number * bigger positive number = negative number (due to 
> >>>> wrapping)
> >>>>
> >>>> So by changing the multiplier this wrapping causes the output bits to be 
> >>>> different. This is why the new variant "eliminates linear dependencies 
> >>>> from one of the lowest bits” (quoted from the authors c code).
> >>>>
> >>>> The multiplier was changed from 1181783497276652981L to 
> >>>> 0x9e3779b97f4a7c13L. These numbers are big:
> >>>>
> >>>> Long.MAX_VALUE / 1181783497276652981L = 7.8046207770792755
> >>>> Long.MAX_VALUE / 0x9e3779b97f4a7c13L = -1.3090169943749475
> >>>>
> >>>> Big enough such that wrapping will occur on every multiplication unless 
> >>>> the positive number is <8, or now <2. So basically all the time.
> >>>>
> >>>> So, IIUC, the output is thus a truncated product formed by the wrapping 
> >>>> long arithmetic and not correlated.
> >>>>
> >>>> I wonder: Would that mean that any choice of a "big" number creates a 
> >>>> new RNG?
> >>>> IOW, if we create a composite one from such generators (i.e. pick one
> >>>> number from
> >>>> each in order to compose the composite source), will it be as good as
> >>>> any of them
> >>>> on the stress test suites?
> >>>>
> >>>> I don't know. These are the numbers that the authors have come up with
> >>>> after testing.
> >>>>
> >>>> Sure. The "TWO_CMRES" variants also results from the author's
> >>>> experiments.
> >>>> Some numbers make "good" generators, others not; but that still
> >>>> does not say whether any two RNGs from the same family are
> >>>> correlated.  In the case of "TWO_CMRES", the states differ by the
> >>>> choice of *2* numbers, whereas here we change only one.
> >>>> So the question is whether it is sufficient.
> >>>>
> >>>> Perhaps other large numbers are worse.
> >>>>
> >>>> These numbers are not prime but they are odd:
> >>>>
> >>>> 1181783497276652981L % 769 == 0
> >>>>
> >>>> 0x9e3779b97f4a7c13L == -7046029254386353133
> >>>>
> >>>> 7046029254386353133 % 3 == 0
> >>>>
> >>>>
> >>>> In the code for SplittableRandom after a split the large value that is
> >>>> used to add to the state to get the next state is created by a mixing
> >>>> operation on the current state. Then the bit count is checked to ensure
> >>>> enough transitions are present:
> >>>>
> >>>> /**
> >>>>   * Returns the gamma value to use for a new split instance.
> >>>>   */
> >>>> private static long mixGamma(long z) {
> >>>>      z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix
> >>>> constants
> >>>>      z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
> >>>>      z = (z ^ (z >>> 33)) | 1L;                  // force to be odd
> >>>>      int n = Long.bitCount(z ^ (z >>> 1));       // ensure enough
> >>>> transitions
> >>>>      return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
> >>>> }
> >>>>
> >>>>
> >>>> So the requirements for a big number may be that it is odd, close to
> >>>> Long.MAX_VALUE (such that Long.MAX_VALUE / number < 2), and has a lot of
> >>>> transitions.
> >>>>
> >>>> What is a "transition"?
> >>>>
> >>>> A change in the bits from 1 to 0 or 0 to 1 as you move across the binary 
> >>>> representation.
> >>>>
> >>>> So for example this has 3 transitions:
> >>>>
> >>>> 0101
> >>>>
> >>>> I think the point is to avoid numbers that look like this in binary:
> >>>>
> >>>> 0000000011111111110000000001111111
> >>>>
> >>>> (still 3 transitions)
> >>>>
> >>>> Instead preferring a number that has lots of 0 to 1 flips. Here are the 
> >>>> numbers we are discussing using Long.toBinaryString(long):
> >>>>
> >>>> 1181783497276652981  
> >>>> 0x1000001100110100010011101010001010100100101111111110110110101 = 35
> >>>> -7046029254386353131  
> >>>> 0x1001111000110111011110011011100101111111010010100111110000010101 = 31
> >>>> -7046029254386353133  
> >>>> 0x1001111000110111011110011011100101111111010010100111110000010011 = 29
> >>>>
> >>>> Transitions:
> >>>>
> >>>> 1181783497276652981 = 35
> >>>> -7046029254386353131 = 31
> >>>> -7046029254386353133 = 29
> >>>>
> >>>> Note: -7046029254386353131 is the 0x9e3779b97f4a7c15L factor used in the
> >>>> SplitMix64 algorithm. This is a variant of the new Phi factor for the
> >>>> XorShift1024StarPhi algorithm and it has more transitions.
> >>>>
> >>>>
> >>>> Anyway the new code for the XorShift1024StarPhi algorithm is a variant
> >>>> of the original. The question is should we update the original or add
> >>>> the alternative?
> >>>>
> >>>> Modifying "XOR_SHIFT_1024_S" would breach the contract: the
> >>>> source will return a different sequence.  This should be done only
> >>>> in a major version.
> >>>>
> >>>> We should certainly add the newer/better version (under a different
> >>>> "enum").
> >>>>
> >>>> My question was indeed whether we should deprecate the
> >>>> "XOR_SHIFT_1024_S" generator.
> >>>> Not because it is not good enough (judging from its score on
> >>>> the stress tests[1], it is still one of the best even if the new
> >>>> "XOR_SHIFT_1024_STAR_PHI" is supposedly better).
> >>>> The issue is whether we want "RandomSource" to only provide
> >>>> independent generators (so that e.g. that can be safely used in a
> >>>> multi-threaded application -- i.e. using a different implementation
> >>>> in each thread is sufficient to ensure uncorrelated output[2]).
> >>>>
> >>>> Does that make sense?
> >>>> If so, one way would be to make the experiment of creating a
> >>>> composite RNG (with the current and new variants) and pass it
> >>>> through the test suites.
> >>>>
> >>>> I don't think there is anything to composite. The code is exactly the 
> >>>> same except for a final multiplier:
> >>>>
> >>>> XorShift1024Star.java L109
> >>>>
> >>>> The method for producing the internal state is the same. So a composite 
> >>>> of internal states (ala TwoCmres) is not possible.
> >>>
> >>> What I mean by "composite" is a new RNG class (code untested):
> >>>
> >>> public class Composite implements RandomLongSource {
> >>>     private final UniformRandomProvider rng[] = new 
> >>> UniformRandomProvider[2];
> >>>     private int flip = 0;
> >>>
> >>>     public Composite(long[] seed) {
> >>>         rng[0] = new XorShiftStar1024Star(seed);
> >>>         rng[1] = new XorShiftStar1024StarPhi(seed);
> >>>     }
> >>>
> >>>     public long nextLong() {
> >>>         return rng[flip++ % 2].nextLong();
> >>>     }
> >>> }
> >>>
> >>>
> >>>> So your concern is that a user may use a XOR_SHIFT_1024_S and 
> >>>> XOR_SHIFT_1024_S_PHI with possibly the same seed in different threads 
> >>>> and experience correlated sequences producing biased results?
> >>> Yes.
> >>>
> >>>> This possibility should be documented if it exists. But how to test that?
> >>> By submitting the "Composite" to BigCrush.
> >>>
> >>>> Do you mean a bitwise xor of the output from each generator, then passed 
> >>>> through the test suites?
> >>> No just using the output of each alternatively (cf. above).
> >> OK. I’ll do that next.
> > Thanks.
> >
> >> I’ve just checked how the xor composite is progressing. It is not happy. 
> >> 82 PASSED and 766 FAILED from 8 incomplete runs. It seems to be stuck in 
> >> an infinite loop in the rgb_kstest_test. The whole suite usually takes 100 
> >> minutes and they have all been running just that test for 5 hours. Reading 
> >> the summary info (dieharder -d 204 -h)I cannot tell what is it about this 
> >> test that has stalled.
> > Strange, but I have no idea about the internals of the test suites...
>
> Dieharder did eventually finish the first 8 runs. Perhaps the test took
> a long time to determine if it was a pass/fail since it was borderline.
> Anyway they all eventually failed that test.
>
>
> I tried the following:
>
> XorComposite: A composite of two rngs using the xor operation:
>
> return new IntProvider() {
>      @Override
>      public int next() {
>          return rng1.nextInt() ^ rng2.nextInt();
>      }
> };
>
> SerialComposite: A composite of two rngs using alternating output:
>
> return new IntProvider() {
>      int flip;
>      @Override
>      public int next() {
>          return ((flip++ & 1) == 0) ? rng1.nextInt() : rng2.nextInt();
>      }
> };
>
>
> I ran:
>
> XorShiftXorComposite: XorComposite using XorShift1024Star +
> XorShift1024StarPhi with the same seed
>
> XorShiftSerialComposite: SerialComposite using XorShift1024Star +
> XorShift1024StarPhi with the same seed
>
> SplitXorComposite: XorComposite using XorShift1024Star + TwoCmres (this
> is a control)
>
>
> FAILURE counts for Dieharder:
>
> XorShiftXorComposite : 89, 105, 104, 104, 105, 106, 105, 104
> XorShiftSerialComposite : 27, 23, 22
> SplitXorComposite : 0, 0, 0

Thanks for doing the experiment.

>
> This shows that a combined generator using two different variants of
> XorShift1024 is not good. So the two XorShift1024 generators are
> correlated.

No miracle then. :-}

> Evidence for deprecation.

Seems so.

Best,
Gilles

>
>
> BigCrush takes longer so I'll try that next. It may just be a whole load
> of failures. I'll add the results to the Jira ticket.
>
>
> >
> >> I’ll let it go until the morning and then kill it. I think this xor 
> >> composite generator is bad. I’ll check if it even works for two unrelated 
> >> generators.
> >>
> >> I think the serial composite (chained together output) should be an 
> >> IntProvider instead given that the test suites use nextInt()? If you use a 
> >> LongProvider then you will get 2 ints from one then 2 from the other.
> > Yes, although that should not impact the ability of BigCrush to
> > provide a verdict.
> >
> >> Note that % 2 will break if it overflows to negative.
> > Right.  What I intended was something like:
> >
> >     public long nextLong() {
> >         flip = (flip + 1) % 2;
> >         return rng[flip].nextLong();
> >     }
> >
> > Gilles
> >
> >> This works with negatives: [flip++ & 0x1]. I read somewhere that BigCrush 
> >> consumes about 2^32 ints so it would be far into the test before you found 
> >> that one.
> >>
> >>
> >>>> IIUC if the bits are more similar than not then the xor will make them 
> >>>> zero more often than not. This should fail the tests.
> >>>>
> >>>> Maybe one to think about before deprecating a good generator. So I would 
> >>>> vote for putting the new XOR_SHIFT_1024_S_PHI along side the 
> >>>> XOR_SHIFT_1024_S. Then perhaps a Jira ticket to do some investigation of 
> >>>> the properties of them run side by side as a composite.
> >>> That's the point, if they are independent, no need to deprecate;
> >>> if they are not, then the better version should be advertised as
> >>> a replacement (as done on the author's web site IIUC).
> >>>
> >>> Regards,
> >>> Gilles
> >>>
> >>>> WDYT?
> >>>>
> >>>> Alex
> >>>>
> >>>>
> >>>>
> >>>> Regards,
> >>>> Gilles
> >>>>
> >>>> [1] 
> >>>> http://commons.apache.org/proper/commons-rng/userguide/rng.html#a5._Quality
> >>>>  
> >>>> <http://commons.apache.org/proper/commons-rng/userguide/rng.html#a5._Quality>
> >>>> [2] Provided the seed is good enough, but that's a different issue.

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

Reply via email to