newrandom/Xoroshiro128StarStar.java
branchbriangoetz-test-branch
changeset 57369 6d87e9f7a1ec
equal deleted inserted replaced
57366:c646b256fbcc 57369:6d87e9f7a1ec
       
     1 /*
       
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
       
     4  *
       
     5  *
       
     6  *
       
     7  *
       
     8  *
       
     9  *
       
    10  *
       
    11  *
       
    12  *
       
    13  *
       
    14  *
       
    15  *
       
    16  *
       
    17  *
       
    18  *
       
    19  *
       
    20  *
       
    21  *
       
    22  *
       
    23  *
       
    24  */
       
    25 
       
    26 // package java.util;
       
    27 
       
    28 import java.math.BigInteger;
       
    29 import java.util.concurrent.atomic.AtomicLong;
       
    30 
       
    31 /**
       
    32  * A generator of uniform pseudorandom values applicable for use in
       
    33  * (among other contexts) isolated parallel computations that may
       
    34  * generate subtasks.  Class {@code Xoroshiro128StarStar} implements
       
    35  * interfaces {@link java.util.Rng} and {@link java.util.LeapableRng},
       
    36  * and therefore supports methods for producing pseudorandomly chosen
       
    37  * numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
       
    38  * as well as creating new {@code Xoroshiro128StarStar} objects
       
    39  * by "jumping" or "leaping".
       
    40  *
       
    41  * <p>Series of generated values pass the TestU01 BigCrush and PractRand test suites
       
    42  * that measure independence and uniformity properties of random number generators.
       
    43  *
       
    44  * <p>The class {@code Xoroshiro128StarStar} uses the {@code xoroshiro128} algorithm,
       
    45  * version 1.0 (parameters 24, 16, 37), with the "**" scrambler (a mixing function).
       
    46  * Its state consists of two {@code long} fields {@code x0} and {@code x1},
       
    47  * which can take on any values provided that they are not both zero.
       
    48  * The period of this generator is 2<sup>128</sup>-1.
       
    49  *
       
    50  * <p>The 64-bit values produced by the {@code nextLong()} method are equidistributed.
       
    51  * To be precise, over the course of the cycle of length 2<sup>128</sup>-1,
       
    52  * each nonzero {@code long} value is generated 2<sup>64</sup> times,
       
    53  * but the value 0 is generated only 2<sup>64</sup>-1 times.
       
    54  * The values produced by the {@code nextInt()}, {@code nextFloat()}, and {@code nextDouble()}
       
    55  * methods are likewise equidistributed.
       
    56  *
       
    57  * <p>In fact, the 64-bit values produced by the {@code nextLong()} method are 2-equidistributed.
       
    58  * To be precise: consider the (overlapping) length-2 subsequences of the cycle of 64-bit
       
    59  * values produced by {@code nextLong()} (assuming no other methods are called that would
       
    60  * affect the state).  There are 2<sup>128</sup>-1 such subsequences, and each subsequence,
       
    61  * which consists of 2 64-bit values, can have one of 2<sup>128</sup> values.  Of those
       
    62  * 2<sup>128</sup> subsequence values, each one is generated exactly once over the course
       
    63  * of the entire cycle, except that the subsequence (0, 0) never appears.
       
    64  * The values produced by the {@code nextInt()}, {@code nextFloat()}, and {@code nextDouble()}
       
    65  * methods are likewise 2-equidistributed, but note that that the subsequence (0, 0)
       
    66  * can also appear (but occurring somewhat less frequently than all other subsequences),
       
    67  * because the values produced by those methods have fewer than 64 randomly chosen bits.
       
    68  *
       
    69  * <p>Instances {@code Xoroshiro128StarStar} are <em>not</em> thread-safe.
       
    70  * They are designed to be used so that each thread as its own instance.
       
    71  * The methods {@link #jump} and {@link #leap} and {@link #jumps} and {@link #leaps}
       
    72  * can be used to construct new instances of {@code Xoroshiro128StarStar} that traverse
       
    73  * other parts of the state cycle.
       
    74  *
       
    75  * <p>Instances of {@code Xoroshiro128StarStar} are not cryptographically
       
    76  * secure.  Consider instead using {@link java.security.SecureRandom}
       
    77  * in security-sensitive applications. Additionally,
       
    78  * default-constructed instances do not use a cryptographically random
       
    79  * seed unless the {@linkplain System#getProperty system property}
       
    80  * {@code java.util.secureRandomSeed} is set to {@code true}.
       
    81  *
       
    82  * @author  Guy Steele
       
    83  * @author  Doug Lea
       
    84  * @since   1.8
       
    85  */
       
    86 public final class Xoroshiro128StarStar implements LeapableRng {
       
    87 
       
    88     /*
       
    89      * Implementation Overview.
       
    90      *
       
    91      * This is an implementation of the xoroshiro128** algorithm written
       
    92      * in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org),
       
    93      * and updated with improved parameters in 2018.
       
    94      * See http://xoshiro.di.unimi.it and these two papers:
       
    95      *
       
    96      *    Sebastiano Vigna. 2016. An Experimental Exploration of Marsaglia's
       
    97      *    xorshift Generators, Scrambled. ACM Transactions on Mathematical
       
    98      *    Software 42, 4, Article 30 (June 2016), 23 pages.
       
    99      *    https://doi.org/10.1145/2845077
       
   100      *
       
   101      *    David Blackman and Sebastiano Vigna.  2018.  Scrambled Linear
       
   102      *    Pseudorandom Number Generators.  Computing Research Repository (CoRR).
       
   103      *    http://arxiv.org/abs/1805.01407
       
   104      *
       
   105      * The jump operation moves the current generator forward by 2*64
       
   106      * steps; this has the same effect as calling nextLong() 2**64
       
   107      * times, but is much faster.  Similarly, the leap operation moves
       
   108      * the current generator forward by 2*96 steps; this has the same
       
   109      * effect as calling nextLong() 2**96 times, but is much faster.
       
   110      * The copy method may be used to make a copy of the current
       
   111      * generator.  Thus one may repeatedly and cumulatively copy and
       
   112      * jump to produce a sequence of generators whose states are well
       
   113      * spaced apart along the overall state cycle (indeed, the jumps()
       
   114      * and leaps() methods each produce a stream of such generators).
       
   115      * The generators can then be parceled out to other threads.
       
   116      *
       
   117      * File organization: First the non-public methods that constitute the
       
   118      * main algorithm, then the public methods.  Note that many methods are
       
   119      * defined by classes {@code AbstractJumpableRng} and {@code AbstractRng}.
       
   120      */
       
   121 
       
   122     /* ---------------- static fields ---------------- */
       
   123 
       
   124     /**
       
   125      * The seed generator for default constructors.
       
   126      */
       
   127     private static final AtomicLong defaultGen = new AtomicLong(RngSupport.initialSeed());
       
   128 
       
   129     /*
       
   130      * The period of this generator, which is 2**128 - 1.
       
   131      */
       
   132     private static final BigInteger thePeriod =
       
   133 	BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
       
   134 
       
   135     /* ---------------- instance fields ---------------- */
       
   136 
       
   137     /**
       
   138      * The per-instance state.
       
   139      * At least one of the two fields x0 and x1 must be nonzero.
       
   140      */
       
   141     private long x0, x1;
       
   142 
       
   143     /* ---------------- constructors ---------------- */
       
   144 
       
   145     /**
       
   146      * Basic constructor that initializes all fields from parameters.
       
   147      * It then adjusts the field values if necessary to ensure that
       
   148      * all constraints on the values of fields are met.
       
   149      */
       
   150     public Xoroshiro128StarStar(long x0, long x1) {
       
   151 	this.x0 = x0;
       
   152         this.x1 = x1;
       
   153 	// If x0 and x1 are both zero, we must choose nonzero values.
       
   154         if ((x0 | x1) == 0) {
       
   155 	    // At least one of the two values generated here will be nonzero.
       
   156 	    this.x0 = RngSupport.mixStafford13(x0 += RngSupport.GOLDEN_RATIO_64);
       
   157 	    this.x1 = (x0 += RngSupport.GOLDEN_RATIO_64);
       
   158 	}
       
   159     }
       
   160 
       
   161     /**
       
   162      * Creates a new instance of {@code Xoroshiro128StarStar} using the
       
   163      * specified {@code long} value as the initial seed. Instances of
       
   164      * {@code Xoroshiro128StarStar} created with the same seed in the same
       
   165      * program generate identical sequences of values.
       
   166      *
       
   167      * @param seed the initial seed
       
   168      */
       
   169     public Xoroshiro128StarStar(long seed) {
       
   170 	// Using a value with irregularly spaced 1-bits to xor the seed
       
   171 	// argument tends to improve "pedestrian" seeds such as 0 or
       
   172 	// other small integers.  We may as well use SILVER_RATIO_64.
       
   173 	//
       
   174 	// The x values are then filled in as if by a SplitMix PRNG with
       
   175 	// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
       
   176         this(RngSupport.mixStafford13(seed ^= RngSupport.SILVER_RATIO_64),
       
   177 	     RngSupport.mixStafford13(seed + RngSupport.GOLDEN_RATIO_64));
       
   178     }
       
   179 
       
   180     /**
       
   181      * Creates a new instance of {@code Xoroshiro128StarStar} that is likely to
       
   182      * generate sequences of values that are statistically independent
       
   183      * of those of any other instances in the current program execution,
       
   184      * but may, and typically does, vary across program invocations.
       
   185      */
       
   186     public Xoroshiro128StarStar() {
       
   187 	// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
       
   188         this(defaultGen.getAndAdd(RngSupport.GOLDEN_RATIO_64));
       
   189     }
       
   190 
       
   191     /**
       
   192      * Creates a new instance of {@code Xoroshiro128StarStar} using the specified array of
       
   193      * initial seed bytes. Instances of {@code Xoroshiro128StarStar} created with the same
       
   194      * seed array in the same program execution generate identical sequences of values.
       
   195      *
       
   196      * @param seed the initial seed
       
   197      */
       
   198     public Xoroshiro128StarStar(byte[] seed) {
       
   199 	// Convert the seed to 2 long values, which are not both zero.
       
   200 	long[] data = RngSupport.convertSeedBytesToLongs(seed, 2, 2);
       
   201 	long x0 = data[0], x1 = data[1];
       
   202         this.x0 = x0;
       
   203         this.x1 = x1;
       
   204     }
       
   205     
       
   206     /* ---------------- public methods ---------------- */
       
   207 
       
   208     public Xoroshiro128StarStar copy() { return new Xoroshiro128StarStar(x0, x1); }
       
   209 
       
   210 /*  
       
   211 
       
   212 To the extent possible under law, the author has dedicated all copyright
       
   213 and related and neighboring rights to this software to the public domain
       
   214 worldwide. This software is distributed without any warranty.
       
   215 
       
   216 See <http://creativecommons.org/publicdomain/zero/1.0/>. */
       
   217 
       
   218 /* This is the successor to xorshift128+. It is the fastest full-period
       
   219    generator passing BigCrush without systematic failures, but due to the
       
   220    relatively short period it is acceptable only for applications with a
       
   221    mild amount of parallelism; otherwise, use a xorshift1024* generator.
       
   222 
       
   223    Beside passing BigCrush, this generator passes the PractRand test suite
       
   224    up to (and included) 16TB, with the exception of binary rank tests,
       
   225    which fail due to the lowest bit being an LFSR; all other bits pass all
       
   226    tests. We suggest to use a sign test to extract a random Boolean value.
       
   227    
       
   228    Note that the generator uses a simulated rotate operation, which most C
       
   229    compilers will turn into a single instruction. In Java, you can use
       
   230    Long.rotateLeft(). In languages that do not make low-level rotation
       
   231    instructions accessible xorshift128+ could be faster.
       
   232 
       
   233    The state must be seeded so that it is not everywhere zero. If you have
       
   234    a 64-bit seed, we suggest to seed a splitmix64 generator and use its
       
   235    output to fill s. */
       
   236 
       
   237 
       
   238     /**
       
   239      * Returns a pseudorandom {@code long} value.
       
   240      *
       
   241      * @return a pseudorandom {@code long} value
       
   242      */
       
   243     public long nextLong() {
       
   244 	final long s0 = x0;
       
   245 	long s1 = x1;
       
   246 	final long z = s0;
       
   247 
       
   248 	s1 ^= s0;
       
   249 	x0 = Long.rotateLeft(s0, 24) ^ s1 ^ (s1 << 16); // a, b
       
   250 	x1 = Long.rotateLeft(s1, 37); // c
       
   251 	
       
   252 	return Long.rotateLeft(z * 5, 7) * 9;  // "starstar" mixing function
       
   253     }
       
   254 
       
   255     public BigInteger period() { return thePeriod; }
       
   256 
       
   257     public double defaultJumpDistance() { return 0x1.0p64; }
       
   258 
       
   259     public double defaultLeapDistance() { return 0x1.0p96; }
       
   260 
       
   261     private static final long[] JUMP_TABLE = { 0xdf900294d8f554a5L, 0x170865df4b3201fcL };
       
   262     
       
   263     private static final long[] LEAP_TABLE = { 0xd2a98b26625eee7bL, 0xdddf9b1090aa7ac1L };
       
   264    
       
   265 /* This is the jump function for the generator. It is equivalent
       
   266    to 2**64 calls to nextLong(); it can be used to generate 2**64
       
   267    non-overlapping subsequences for parallel computations. */
       
   268 
       
   269     public void jump() { jumpAlgorithm(JUMP_TABLE); }
       
   270     
       
   271 /* This is the long-jump function for the generator. It is equivalent to
       
   272    2**96 calls to next(); it can be used to generate 2**32 starting points,
       
   273    from each of which jump() will generate 2**32 non-overlapping
       
   274    subsequences for parallel distributed computations. */
       
   275 
       
   276     public void leap() { jumpAlgorithm(LEAP_TABLE); }
       
   277 
       
   278     private void jumpAlgorithm(long[] table) {
       
   279 	long s0 = 0, s1 = 0;
       
   280 	for (int i = 0; i < table.length; i++) {
       
   281 	    for (int b = 0; b < 64; b++) {
       
   282 		if ((table[i] & (1L << b)) != 0) {
       
   283 		    s0 ^= x0;
       
   284 		    s1 ^= x1;
       
   285 		}
       
   286 		nextLong();
       
   287 	    }
       
   288 	    x0 = s0;
       
   289 	    x1 = s1;
       
   290 	}
       
   291     }
       
   292 }