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...

>
> 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 
> > <mailto:dev-unsubscr...@commons.apache.org>
> > For additional commands, e-mail: dev-h...@commons.apache.org 
> > <mailto:dev-h...@commons.apache.org>

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

Reply via email to