src/java.base/share/classes/java/util/random/L64X1024MixRandom.java
branchJDK-8193209-branch
changeset 59080 1b314be4feb2
parent 57684 7cb325557832
equal deleted inserted replaced
57940:7e791393cc4d 59080:1b314be4feb2
    26 package java.util.random;
    26 package java.util.random;
    27 
    27 
    28 import java.math.BigInteger;
    28 import java.math.BigInteger;
    29 import java.util.concurrent.atomic.AtomicLong;
    29 import java.util.concurrent.atomic.AtomicLong;
    30 import java.util.random.RandomGenerator.SplittableGenerator;
    30 import java.util.random.RandomGenerator.SplittableGenerator;
    31 import java.util.random.RandomSupport.AbstractSplittableGenerator;
    31 import java.util.random.RandomSupport.AbstractSplittableWithBrineGenerator;
    32 
    32 
    33 /**
    33 /**
    34  * A generator of uniform pseudorandom values applicable for use in
    34  * A generator of uniform pseudorandom values applicable for use in
    35  * (among other contexts) isolated parallel computations that may
    35  * (among other contexts) isolated parallel computations that may
    36  * generate subtasks.  Class {@link L64X1024MixRandom} implements
    36  * generate subtasks.  Class {@link L64X1024MixRandom} implements
    52  * least approximately, for others as well.
    52  * least approximately, for others as well.
    53  * <p>
    53  * <p>
    54  * {@link L64X1024MixRandom} is a specific member of the LXM family of algorithms
    54  * {@link L64X1024MixRandom} is a specific member of the LXM family of algorithms
    55  * for pseudorandom number generators.  Every LXM generator consists of two
    55  * for pseudorandom number generators.  Every LXM generator consists of two
    56  * subgenerators; one is an LCG (Linear Congruential Generator) and the other is
    56  * subgenerators; one is an LCG (Linear Congruential Generator) and the other is
    57  * an Xorshift generator.  Each output of an LXM generator is the sum of one
    57  * an Xorshift generator.  Each output of an LXM generator is the result of
    58  * output from each subgenerator, possibly processed by a final mixing function
    58  * combining state from the LCG with state from the Xorshift generator by
    59  * (and {@link L64X1024MixRandom} does use a mixing function).
    59  * using a Mixing function (and then the state of the LCG and the state of the
       
    60  * Xorshift generator are advanced).
    60  * <p>
    61  * <p>
    61  * The LCG subgenerator for {@link L64X1024MixRandom} has an update step of the
    62  * The LCG subgenerator for {@link L64X1024MixRandom} has an update step of the
    62  * form {@code s = m * s + a}, where {@code s}, {@code m}, and {@code a} are all
    63  * form {@code s = m * s + a}, where {@code s}, {@code m}, and {@code a} are all
    63  * of type {@code long}; {@code s} is the mutable state, the multiplier {@code m}
    64  * of type {@code long}; {@code s} is the mutable state, the multiplier {@code m}
    64  * is fixed (the same for all instances of {@link L64X1024MixRandom}) and the addend
    65  * is fixed (the same for all instances of {@link L64X1024MixRandom}) and the addend
    71  * algorithm (parameters 25, 27, and 36), without any final scrambler such as "+" or "**".
    72  * algorithm (parameters 25, 27, and 36), without any final scrambler such as "+" or "**".
    72  * Its state consists of an array {@code x} of sixteen {@code long} values,
    73  * Its state consists of an array {@code x} of sixteen {@code long} values,
    73  * which can take on any values provided that they are not all zero.
    74  * which can take on any values provided that they are not all zero.
    74  * The period of this subgenerator is 2<sup>1024</sup>-1.
    75  * The period of this subgenerator is 2<sup>1024</sup>-1.
    75  * <p>
    76  * <p>
    76  * The mixing function for {@link L64X256MixRandom} is the 64-bit MurmurHash3 finalizer.
    77  * The mixing function for {@link L64X1024MixRandom} is {@link RandomSupport.mixLea64}
       
    78  * applied to the argument {@code (s + s0)}, where {@code s0} is the most recently computed
       
    79  * element of {@code x}.
    77  * <p>
    80  * <p>
    78  * Because the periods 2<sup>64</sup> and 2<sup>1024</sup>-1 of the two subgenerators
    81  * Because the periods 2<sup>64</sup> and 2<sup>1024</sup>-1 of the two subgenerators
    79  * are relatively prime, the <em>period</em> of any single {@link L64X1024MixRandom} object
    82  * are relatively prime, the <em>period</em> of any single {@link L64X1024MixRandom} object
    80  * (the length of the series of generated 64-bit values before it repeats) is the product
    83  * (the length of the series of generated 64-bit values before it repeats) is the product
    81  * of the periods of the subgenerators, that is, 2<sup>64</sup>(2<sup>1024</sup>-1),
    84  * of the periods of the subgenerators, that is, 2<sup>64</sup>(2<sup>1024</sup>-1),
    96  * There are 2<sup>64</sup>(2<sup>1024</sup>-1) such subsequences, and each subsequence,
    99  * There are 2<sup>64</sup>(2<sup>1024</sup>-1) such subsequences, and each subsequence,
    97  * which consists of 16 64-bit values, can have one of 2<sup>1024</sup> values. Of those
   100  * which consists of 16 64-bit values, can have one of 2<sup>1024</sup> values. Of those
    98  * 2<sup>1024</sup> subsequence values, nearly all of them (2<sup>1024</sup>-2<sup>64</sup>)
   101  * 2<sup>1024</sup> subsequence values, nearly all of them (2<sup>1024</sup>-2<sup>64</sup>)
    99  * occur 2<sup>64</sup> times over the course of the entire cycle, and the other
   102  * occur 2<sup>64</sup> times over the course of the entire cycle, and the other
   100  * 2<sup>64</sup> subsequence values occur only 2<sup>64</sup>-1 times.  So the ratio
   103  * 2<sup>64</sup> subsequence values occur only 2<sup>64</sup>-1 times.  So the ratio
   101  * of the probability of getting one of the less common subsequence values and the
   104  * of the probability of getting any specific one of the less common subsequence values and the
   102  * probability of getting one of the more common subsequence values is 1-2<sup>-64</sup>.
   105  * probability of getting any specific one of the more common subsequence values is 1-2<sup>-64</sup>.
   103  * (Note that the set of 2<sup>64</sup> less-common subsequence values will differ from
   106  * (Note that the set of 2<sup>64</sup> less-common subsequence values will differ from
   104  * one instance of {@link L64X1024MixRandom} to another, as a function of the additive
   107  * one instance of {@link L64X1024MixRandom} to another, as a function of the additive
   105  * parameter of the LCG.)  The values produced by the {@code nextInt()}, {@code nextFloat()},
   108  * parameter of the LCG.)  The values produced by the {@code nextInt()}, {@code nextFloat()},
   106  * and {@code nextDouble()} methods are likewise 16-equidistributed.
   109  * and {@code nextDouble()} methods are likewise 16-equidistributed.
   107  * <p>
   110  * <p>
   134  * seed unless the {@linkplain System#getProperty system property}
   137  * seed unless the {@linkplain System#getProperty system property}
   135  * {@code java.util.secureRandomSeed} is set to {@code true}.
   138  * {@code java.util.secureRandomSeed} is set to {@code true}.
   136  *
   139  *
   137  * @since 14
   140  * @since 14
   138  */
   141  */
   139 public final class L64X1024MixRandom extends AbstractSplittableGenerator {
   142 public final class L64X1024MixRandom extends AbstractSplittableWithBrineGenerator {
   140 
   143 
   141     /*
   144     /*
   142      * Implementation Overview.
   145      * Implementation Overview.
   143      *
   146      *
   144      * The split() operation uses the current generator to choose 18 new 64-bit
   147      * The split() operation uses the current generator to choose 18 new 64-bit
   183      */
   186      */
   184     private static final BigInteger PERIOD =
   187     private static final BigInteger PERIOD =
   185         BigInteger.ONE.shiftLeft(N*64).subtract(BigInteger.ONE).shiftLeft(64);
   188         BigInteger.ONE.shiftLeft(N*64).subtract(BigInteger.ONE).shiftLeft(64);
   186 
   189 
   187     /*
   190     /*
   188      * Multiplier used in the LCG portion of the algorithm, taken from
   191      * Multiplier used in the LCG portion of the algorithm.
   189      * Pierre L'Ecuyer, Tables of linear congruential generators of
   192      * Chosen based on research by Sebastiano Vigna and Guy Steele (2019).
   190      * different sizes and good lattice structure, <em>Mathematics of
   193      * The spectral scores for dimensions 2 through 8 for the multiplier 0xd1342543de82ef95
   191      * Computation</em> 68, 225 (January 1999), pages 249-260,
   194      * are [0.958602, 0.937479, 0.870757, 0.822326, 0.820405, 0.813065, 0.760215].
   192      * Table 4 (first multiplier for size 2<sup>64</sup>).
   195      */
   193      */
   196 
   194 
   197     private static final long M = 0xd1342543de82ef95L;
   195     private static final long M = 2862933555777941757L;
       
   196 
   198 
   197     /* ---------------- instance fields ---------------- */
   199     /* ---------------- instance fields ---------------- */
   198 
   200 
   199     /**
   201     /**
   200      * The parameter that is used as an additive constant for the LCG.
   202      * The parameter that is used as an additive constant for the LCG.
   262         this.x[13] = x13;
   264         this.x[13] = x13;
   263         this.x[14] = x14;
   265         this.x[14] = x14;
   264         this.x[15] = x15;
   266         this.x[15] = x15;
   265         // If x0, x1, ..., x15 are all zero (very unlikely), we must choose nonzero values.
   267         // If x0, x1, ..., x15 are all zero (very unlikely), we must choose nonzero values.
   266         if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0) {
   268         if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0) {
       
   269 	    long v = s;
   267             // At least fifteen of the sixteen values generated here will be nonzero.
   270             // At least fifteen of the sixteen values generated here will be nonzero.
   268             for (int j = 0; j < N; j++) {
   271             for (int j = 0; j < N; j++) {
   269                 this.x[j] = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
   272                 this.x[j] = RandomSupport.mixStafford13(v += RandomSupport.GOLDEN_RATIO_64);
   270             }
   273             }
   271         }
   274         }
   272     }
   275     }
   273 
   276 
   274     /**
   277     /**
   286         //
   289         //
   287         // The seed is hashed by mixMurmur64 to produce the `a` parameter.
   290         // The seed is hashed by mixMurmur64 to produce the `a` parameter.
   288         // The seed is hashed by mixStafford13 to produce the initial `x[0]`,
   291         // The seed is hashed by mixStafford13 to produce the initial `x[0]`,
   289         // which will then be used to produce the first generated value.
   292         // which will then be used to produce the first generated value.
   290         // The other x values are filled in as if by a SplitMix PRNG with
   293         // The other x values are filled in as if by a SplitMix PRNG with
   291         // GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
   294         // GOLDEN_RATIO_64 as the gamma value and mixStafford13 as the mixer.
   292         this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
   295         this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
   293              1,
   296              1,
   294              RandomSupport.mixStafford13(seed),
   297              RandomSupport.mixStafford13(seed),
   295              RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
   298              RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
   296              RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
   299              RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
   339             this.x[j] = data[2+j];
   342             this.x[j] = data[2+j];
   340         }
   343         }
   341     }
   344     }
   342 
   345 
   343     /* ---------------- public methods ---------------- */
   346     /* ---------------- public methods ---------------- */
   344 
   347     /**
   345     /**
   348      * Given 63 bits of "brine", constructs and returns a new instance of
   346      * Constructs and returns a new instance of {@link L64X1024MixRandom}
   349      * {@code L64X1024MixRandom} that shares no mutable state with this instance.
   347      * that shares no mutable state with this instance.
       
   348      * However, with very high probability, the set of values collectively
   350      * However, with very high probability, the set of values collectively
   349      * generated by the two objects has the same statistical properties as if
   351      * generated by the two objects has the same statistical properties as if
   350      * same the quantity of values were generated by a single thread using
   352      * same the quantity of values were generated by a single thread using
   351      * a single {@link L64X1024MixRandom} object.  Either or both of the two
   353      * a single {@code L64X1024MixRandom} object.  Either or both of the two
   352      * objects may be further split using the {@code split} method,
   354      * objects may be further split using the {@code split} method,
   353      * and the same expected statistical properties apply to the
   355      * and the same expected statistical properties apply to the
   354      * entire set of generators constructed by such recursive splitting.
   356      * entire set of generators constructed by such recursive splitting.
   355      *
   357      *
   356      * @param source a {@link SplittableGenerator} instance to be used instead
   358      * @param source a {@code SplittableGenerator} instance to be used instead
   357      *               of this one as a source of pseudorandom bits used to
   359      *               of this one as a source of pseudorandom bits used to
   358      *               initialize the state of the new ones.
   360      *               initialize the state of the new ones.
   359      * @return a new instance of {@link L64X1024MixRandom}
   361      * @param brine a long value, of which the low 63 bits are used to choose
   360      */
   362      *              the {@code a} parameter for the new instance.
   361     public L64X1024MixRandom split(SplittableGenerator source) {
   363      * @return a new instance of {@code L64X1024MixRandom}
   362         // Literally pick a new instance "at random".
   364      */
   363         return new L64X1024MixRandom(source.nextLong(), source.nextLong(),
   365     public SplittableGenerator split(SplittableGenerator source, long brine) {
   364                                      source.nextLong(), source.nextLong(),
   366 	// Pick a new instance "at random", but use the brine for `a`.
       
   367         return new L64X1024MixRandom(brine << 1, source.nextLong(),
       
   368 				     source.nextLong(), source.nextLong(),
   365                                      source.nextLong(), source.nextLong(),
   369                                      source.nextLong(), source.nextLong(),
   366                                      source.nextLong(), source.nextLong(),
   370                                      source.nextLong(), source.nextLong(),
   367                                      source.nextLong(), source.nextLong(),
   371                                      source.nextLong(), source.nextLong(),
   368                                      source.nextLong(), source.nextLong(),
   372                                      source.nextLong(), source.nextLong(),
   369                                      source.nextLong(), source.nextLong(),
   373                                      source.nextLong(), source.nextLong(),
   380         // First part of xoroshiro1024: fetch array data
   384         // First part of xoroshiro1024: fetch array data
   381         final int q = p;
   385         final int q = p;
   382         final long s0 = x[p = (p + 1) & (N - 1)];
   386         final long s0 = x[p = (p + 1) & (N - 1)];
   383         long s15 = x[q];
   387         long s15 = x[q];
   384 
   388 
   385         final long z = s + s0;
   389 	// Compute the result based on current state information
       
   390 	// (this allows the computation to be overlapped with state update).
       
   391 
       
   392 	final long result = RandomSupport.mixLea64(s + s0);
       
   393 	
       
   394 	// Update the LCG subgenerator
   386         s = M * s + a;  // LCG
   395         s = M * s + a;  // LCG
   387 
   396 
   388         // Second part of xoroshiro1024: update array data
   397         // Second part of xoroshiro1024: update array data
   389         s15 ^= s0;
   398         s15 ^= s0;
   390         x[q] = Long.rotateLeft(s0, 25) ^ s15 ^ (s15 << 27);
   399         x[q] = Long.rotateLeft(s0, 25) ^ s15 ^ (s15 << 27);
   391         x[p] = Long.rotateLeft(s15, 36);
   400         x[p] = Long.rotateLeft(s15, 36);
   392 
   401 
   393         return RandomSupport.mixLea64(z);  // mixing function
   402         return result;
   394     }
   403     }
   395 
   404 
       
   405     /**
       
   406      * Returns the period of this random generator.
       
   407      *
       
   408      * @return a {@link BigInteger} whose value is the number of distinct possible states of this
       
   409      *         {@link RandomGenerator} object (2<sup>64</sup>(2<sup>1024</sup>-1)).
       
   410      */
   396     public BigInteger period() {
   411     public BigInteger period() {
   397         return PERIOD;
   412         return PERIOD;
   398     }
   413     }
   399 }
   414 }