001/*
002 * Java Genetic Algorithm Library (jenetics-1.6.0).
003 * Copyright (c) 2007-2014 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019 */
020package org.jenetics.util;
021
022import static java.lang.String.format;
023import static java.util.Objects.requireNonNull;
024
025import java.util.Random;
026
027/**
028 * This object contains mathematical helper functions.
029 *
030 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
031 * @since 1.0
032 * @version 1.4 &mdash; <em>$Date: 2014-02-15 $</em>
033 */
034public final class math extends StaticObject {
035        private math() {}
036
037        /**
038         * Add to long values and throws an ArithmeticException in the case of an
039         * overflow.
040         *
041         * @param a the first summand.
042         * @param b the second summand.
043         * @return the sum of the given values.
044         * @throws ArithmeticException if the summation would lead to an overflow.
045         */
046        public static long plus(final long a, final long b) {
047                final long z = a + b;
048                if (((a^z) & (b^z)) < 0) {
049                        throw new ArithmeticException(format("Overflow: %d + %d", a, b));
050                }
051
052                return z;
053        }
054
055        /**
056         * Subtracts to long values and throws an ArithmeticException in the case of
057         * an overflow.
058         *
059         * @param a the minuend.
060         * @param b the subtrahend.
061         * @return the difference of the given values.
062         * @throws ArithmeticException if the subtraction would lead to an overflow.
063         */
064        public static long minus(final long a, final long b) {
065                final long z = a - b;
066                if (((a^b) & (a^z)) < 0) {
067                        throw new ArithmeticException(format("Overflow: %d - %d", a, b));
068                }
069
070                return z;
071        }
072
073        /**
074         * Implementation of the <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm">
075         * Kahan summation algorithm</a>.
076         *
077         * @param values the values to sum up.
078         * @return the sum of the given {@code values}.
079         * @throws NullPointerException if the given array is {@code null}.
080         *
081         * @deprecated Use {@link math.statistics#sum(double[])} instead.
082         */
083        @Deprecated
084        public static double sum(final double[] values) {
085                return statistics.sum(values);
086        }
087
088        /**
089         * Add the values of the given array.
090         *
091         * @param values the values to add.
092         * @return the values sum.
093         * @throws NullPointerException if the values are null;
094         *
095         * @deprecated Use {@link math.statistics#sum(long[])} instead.
096         */
097        @Deprecated
098        public static long sum(final long[] values) {
099                return statistics.sum(values);
100        }
101
102        /**
103         * Normalize the given double array, so that it sum to one. The
104         * normalization is performed in place and the same {@code values} are
105         * returned.
106         *
107         * @param values the values to normalize.
108         * @return the {@code values} array.
109         * @throws NullPointerException if the given double array is {@code null}.
110         */
111        public static double[] normalize(final double[] values) {
112                final double sum = 1.0/statistics.sum(values);
113                for (int i = values.length; --i >= 0;) {
114                        values[i] = values[i]*sum;
115                }
116
117                return values;
118        }
119
120        /**
121         * Return the minimum value of the given double array.
122         *
123         * @param values the double array.
124         * @return the minimum value or {@link Double#NaN} if the given array is
125         *         empty.
126         * @throws NullPointerException if the given array is {@code null}.
127         *
128         * @deprecated Use {@link math.statistics#min(double[])} instead.
129         */
130        @Deprecated
131        public static double min(final double[] values) {
132                return statistics.min(values);
133        }
134
135        /**
136         * Return the maximum value of the given double array.
137         *
138         * @param values the double array.
139         * @return the maximum value or {@link Double#NaN} if the given array is
140         *         empty.
141         * @throws NullPointerException if the given array is {@code null}.
142         *
143         * @deprecated Use {@link math.statistics#max(double[])} instead.
144         */
145        @Deprecated
146        public static double max(final double[] values) {
147                return statistics.max(values);
148        }
149
150        /**
151         * <i>Clamping</i> a value between a pair of boundary values.
152         * <i>Note: using clamp with floating point numbers may give unexpected
153         * results if one of the values is {@code NaN}.</i>
154         *
155         * @param v the value to <i>clamp</i>
156         * @param lo the lower bound.
157         * @param hi the upper bound.
158         * @return The clamped value:
159         *        <ul>
160         *            <li>{@code lo if v < lo}</li>
161         *            <li>{@code hi if hi < v}</li>
162         *            <li>{@code otherwise, v}</li>
163         *        </ul>
164         */
165        public static double clamp(final double v, final double lo, final double hi) {
166                return v < lo ? lo : (v > hi ? hi : v);
167        }
168
169        /**
170         * Component wise multiplication of the given double array.
171         *
172         * @param values the double values to multiply.
173         * @param multiplier the multiplier.
174         * @throws NullPointerException if the given double array is {@code null}.
175         */
176        public static void times(final double[] values, final double multiplier) {
177                for (int i = values.length; --i >= 0;) {
178                        values[i] *= multiplier;
179                }
180        }
181
182        /**
183         * Component wise division of the given double array.
184         *
185         * @param values the double values to divide.
186         * @param divisor the divisor.
187         * @throws NullPointerException if the given double array is {@code null}.
188         */
189        public static void divide(final double[] values, final double divisor) {
190                for (int i = values.length; --i >= 0;) {
191                        values[i] /= divisor;
192                }
193        }
194
195        /**
196         * Binary exponentiation algorithm.
197         *
198         * @param b the base number.
199         * @param e the exponent.
200         * @return {@code b^e}.
201         */
202        public static long pow(final long b, final long e) {
203                long base = b;
204                long exp = e;
205                long result = 1;
206
207                while (exp != 0) {
208                        if ((exp & 1) != 0) {
209                                result *= base;
210                        }
211                        exp >>>= 1;
212                        base *= base;
213                }
214
215                return result;
216        }
217
218        static int gcd(final int a, final int b) {
219                int x = a;
220                int y = b;
221                int mod = x%y;
222
223                while (mod != 0) {
224                        x = y;
225                        y = mod;
226                        mod = x%y;
227                }
228
229                return y;
230        }
231
232        static boolean isMultiplicationSave(final int a, final int b) {
233                final long m = (long)a*(long)b;
234                return ((int)m) == m;
235        }
236
237        /**
238         * Return the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a>
239         * distance of the given two double values.
240         *
241         * @param a first double.
242         * @param b second double.
243         * @return the ULP distance.
244         * @throws ArithmeticException if the distance doesn't fit in a long value.
245         */
246        public static long ulpDistance(final double a, final double b) {
247                return minus(ulpPosition(a), ulpPosition(b));
248        }
249
250        /**
251         * Calculating the <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place">ULP</a>
252         * position of a double number.
253         *
254         * 
<a name="line.254"></a> <span class="sourceLineNo">255</span> * double a = 0.0;<a name="line.255"></a> <span class="sourceLineNo">256</span> * for (int i = 0; i &lt; 10; ++i) {<a name="line.256"></a> <span class="sourceLineNo">257</span> * a = Math.nextAfter(a, Double.POSITIVE_INFINITY);<a name="line.257"></a> <span class="sourceLineNo">258</span> * }<a name="line.258"></a> <span class="sourceLineNo">259</span> *<a name="line.259"></a> <span class="sourceLineNo">260</span> * for (int i = 0; i &lt; 19; ++i) {<a name="line.260"></a> <span class="sourceLineNo">261</span> * a = Math.nextAfter(a, Double.NEGATIVE_INFINITY);<a name="line.261"></a> <span class="sourceLineNo">262</span> * System.out.println(<a name="line.262"></a> <span class="sourceLineNo">263</span> * a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a)<a name="line.263"></a> <span class="sourceLineNo">264</span> * );<a name="line.264"></a> <span class="sourceLineNo">265</span> * }<a name="line.265"></a>
267 * 268 * The code fragment above will create the following output: 269 * <pre> 270 * 4.4E-323 9 9 271 * 4.0E-323 8 8 272 * 3.5E-323 7 7 273 * 3.0E-323 6 6 274 * 2.5E-323 5 5 275 * 2.0E-323 4 4 276 * 1.5E-323 3 3 277 * 1.0E-323 2 2 278 * 4.9E-324 1 1 279 * 0.0 0 0 280 * -4.9E-324 -1 1 281 * -1.0E-323 -2 2 282 * -1.5E-323 -3 3 283 * -2.0E-323 -4 4 284 * -2.5E-323 -5 5 285 * -3.0E-323 -6 6 286 * -3.5E-323 -7 7 287 * -4.0E-323 -8 8 288 * -4.4E-323 -9 9 289 * </pre> 290 * 291 * @param a the double number. 292 * @return the ULP position. 293 */ 294 public static long ulpPosition(final double a) { 295 long t = Double.doubleToLongBits(a); 296 if (t < 0) { 297 t = Long.MIN_VALUE - t; 298 } 299 return t; 300 } 301 302 /** 303 * Selects a random subset of size {@code k} from a set of size {@code n}. 304 * 305 * @see #subset(int, int[]) 306 * 307 * @param n the size of the set. 308 * @param k the size of the subset. 309 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if 310 * {@code n*k} will cause an integer overflow. 311 * @return the subset array. 312 */ 313 public static int[] subset(final int n, final int k) { 314 return subset(n, k, RandomRegistry.getRandom()); 315 } 316 317 /** 318 * Selects a random subset of size {@code k} from a set of size {@code n}. 319 * 320 * @see #subset(int, int[], Random) 321 * 322 * @param n the size of the set. 323 * @param k the size of the subset. 324 * @param random the random number generator used. 325 * @throws NullPointerException if {@code random} is {@code null}. 326 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if 327 * {@code n*k} will cause an integer overflow. 328 * @return the subset array. 329 */ 330 public static int[] subset(final int n, final int k, final Random random) { 331 requireNonNull(random, "Random"); 332 if (k <= 0) { 333 throw new IllegalArgumentException(format( 334 "Subset size smaller or equal zero: %s", k 335 )); 336 } 337 if (n < k) { 338 throw new IllegalArgumentException(format( 339 "n smaller than k: %s < %s.", n, k 340 )); 341 } 342 343 final int[] sub = new int[k]; 344 subset(n, sub,random); 345 return sub; 346 } 347 348 /** 349 * <p> 350 * Selects a random subset of size {@code sub.length} from a set of size 351 * {@code n}. 352 * </p> 353 * 354 * <p> 355 * <em>Authors:</em> 356 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This 357 * version based on the C++ version by John Burkardt. 358 * </p> 359 * 360 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html"> 361 * Reference:</a></em> 362 * Albert Nijenhuis, Herbert Wilf, 363 * Combinatorial Algorithms for Computers and Calculators, 364 * Second Edition, 365 * Academic Press, 1978, 366 * ISBN: 0-12-519260-6, 367 * LC: QA164.N54. 368 * </p> 369 * 370 * @param n the size of the set. 371 * @param sub the sub set array. 372 * @throws NullPointerException if {@code sub} is {@code null}. 373 * @throws IllegalArgumentException if {@code n < sub.length}, 374 * {@code sub.length == 0} or {@code n*sub.length} will cause an 375 * integer overflow. 376 */ 377 public static void subset(final int n, final int sub[]) { 378 subset(n, sub, RandomRegistry.getRandom()); 379 } 380 381 /** 382 * <p> 383 * Selects a random subset of size {@code sub.length} from a set of size 384 * {@code n}. 385 * </p> 386 * 387 * <p> 388 * <em>Authors:</em> 389 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This 390 * version based on the C++ version by John Burkardt. 391 * </p> 392 * 393 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html"> 394 * Reference:</a></em> 395 * Albert Nijenhuis, Herbert Wilf, 396 * Combinatorial Algorithms for Computers and Calculators, 397 * Second Edition, 398 * Academic Press, 1978, 399 * ISBN: 0-12-519260-6, 400 * LC: QA164.N54. 401 * </p> 402 * 403 * @param n the size of the set. 404 * @param sub the sub set array. 405 * @param random the random number generator used. 406 * @throws NullPointerException if {@code sub} or {@code random} is 407 * {@code null}. 408 * @throws IllegalArgumentException if {@code n < sub.length}, 409 * {@code sub.length == 0} or {@code n*sub.length} will cause an 410 * integer overflow. 411 */ 412 public static int[] subset(final int n, final int sub[], final Random random) { 413 requireNonNull(random, "Random"); 414 requireNonNull(sub, "Sub set array"); 415 416 final int k = sub.length; 417 if (k <= 0) { 418 throw new IllegalArgumentException(format( 419 "Subset size smaller or equal zero: %s", k 420 )); 421 } 422 if (n < k) { 423 throw new IllegalArgumentException(format( 424 "n smaller than k: %s < %s.", n, k 425 )); 426 } 427 if (!math.isMultiplicationSave(n, k)) { 428 throw new IllegalArgumentException(format( 429 "n*sub.length > Integer.MAX_VALUE (%s*%s = %s > %s)", 430 n, sub.length, (long)n*(long)k, Integer.MAX_VALUE 431 )); 432 } 433 434 if (sub.length == n) { 435 for (int i = 0; i < sub.length; ++i) { 436 sub[i] = i; 437 } 438 return sub; 439 } 440 441 for (int i = 0; i < k; ++i) { 442 sub[i] = (i*n)/k; 443 } 444 445 int l = 0; 446 int ix = 0; 447 for (int i = 0; i < k; ++i) { 448 do { 449 ix = nextInt(random, 1, n); 450 l = (ix*k - 1)/n; 451 } while (sub[l] >= ix); 452 453 sub[l] = sub[l] + 1; 454 } 455 456 int m = 0; 457 int ip = 0; 458 int is = k; 459 for (int i = 0; i < k; ++i) { 460 m = sub[i]; 461 sub[i] = 0; 462 463 if (m != (i*n)/k) { 464 ip = ip + 1; 465 sub[ip - 1] = m; 466 } 467 } 468 469 int ihi = ip; 470 int ids = 0; 471 for (int i = 1; i <= ihi; ++i) { 472 ip = ihi + 1 - i; 473 l = 1 + (sub[ip - 1]*k - 1)/n; 474 ids = sub[ip - 1] - ((l - 1)*n)/k; 475 sub[ip - 1] = 0; 476 sub[is - 1] = l; 477 is = is - ids; 478 } 479 480 int ir = 0; 481 int m0 = 0; 482 for (int ll = 1; ll <= k; ++ll) { 483 l = k + 1 - ll; 484 485 if (sub[l - 1] != 0) { 486 ir = l; 487 m0 = 1 + ((sub[l - 1] - 1)*n)/k; 488 m = (sub[l-1]*n)/k - m0 + 1; 489 } 490 491 ix = nextInt(random, m0, m0 + m - 1); 492 493 int i = l + 1; 494 while (i <= ir && ix >= sub[i - 1]) { 495 ix = ix + 1; 496 sub[ i- 2] = sub[i - 1]; 497 i = i + 1; 498 } 499 500 sub[i - 2] = ix; 501 --m; 502 } 503 504 return sub; 505 } 506 507 private static int nextInt(final Random random, final int a, final int b) { 508 return a == b ? a - 1 : random.nextInt(b - a) + a; 509 } 510 511 /** 512 * Some helper method concerning statistics. 513 * 514 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 515 * @since 1.3 516 * @version 1.3 &mdash; <em>$Date: 2014-02-15 $</em> 517 */ 518 public static final class statistics extends StaticObject { 519 private statistics() {} 520 521 /** 522 * Return the minimum value of the given double array. 523 * 524 * @param values the double array. 525 * @return the minimum value or {@link Double#NaN} if the given array is 526 * empty. 527 * @throws NullPointerException if the given array is {@code null}. 528 */ 529 public static double min(final double[] values) { 530 double min = Double.NaN; 531 if (values.length > 0) { 532 min = values[0]; 533 534 for (int i = values.length; --i >= 1;) { 535 if (values[i] < min) { 536 min = values[i]; 537 } 538 } 539 } 540 541 return min; 542 } 543 544 /** 545 * Return the maximum value of the given double array. 546 * 547 * @param values the double array. 548 * @return the maximum value or {@link Double#NaN} if the given array is 549 * empty. 550 * @throws NullPointerException if the given array is {@code null}. 551 */ 552 public static double max(final double[] values) { 553 double max = Double.NaN; 554 if (values.length > 0) { 555 max = values[0]; 556 557 for (int i = values.length; --i >= 1;) { 558 if (values[i] > max) { 559 max = values[i]; 560 } 561 } 562 } 563 564 return max; 565 } 566 567 /** 568 * Implementation of the <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm"> 569 * Kahan summation algorithm</a>. 570 * 571 * @param values the values to sum up. 572 * @return the sum of the given {@code values}. 573 * @throws NullPointerException if the given array is {@code null}. 574 */ 575 public static double sum(final double[] values) { 576 double sum = 0.0; 577 double c = 0.0; 578 double y = 0.0; 579 double t = 0.0; 580 581 for (int i = values.length; --i >= 0;) { 582 y = values[i] - c; 583 t = sum + y; 584 c = t - sum - y; 585 sum = t; 586 } 587 588 return sum; 589 } 590 591 /** 592 * Add the values of the given array. 593 * 594 * @param values the values to add. 595 * @return the values sum. 596 * @throws NullPointerException if the values are null; 597 */ 598 public static long sum(final long[] values) { 599 long sum = 0; 600 for (int i = values.length; --i >= 0;) { 601 sum += values[i]; 602 } 603 return sum; 604 } 605 606 } 607 608 /** 609 * Some helper method concerning random numbers and random seed generation. 610 * 611 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 612 * @since 1.1 613 * @version 1.2 &mdash; <em>$Date: 2014-02-15 $</em> 614 */ 615 public static final class random extends StaticObject { 616 private random() {} 617 618 /** 619 * Returns a pseudorandom, uniformly distributed int value between min 620 * and max (min and max included). 621 * 622 * @param min lower bound for generated integer 623 * @param max upper bound for generated integer 624 * @return a random integer greater than or equal to {@code min} and 625 * less than or equal to {@code max} 626 * @throws IllegalArgumentException if {@code min >= max} 627 */ 628 public static int nextInt( 629 final Random random, 630 final int min, final int max 631 ) { 632 if (min >= max) { 633 throw new IllegalArgumentException(format( 634 "Min >= max: %d >= %d", min, max 635 )); 636 } 637 638 final int diff = max - min + 1; 639 int result = 0; 640 641 if (diff <= 0) { 642 do { 643 result = random.nextInt(); 644 } while (result < min || result > max); 645 } else { 646 result = random.nextInt(diff) + min; 647 } 648 649 return result; 650 } 651 652 /** 653 * Returns a pseudorandom, uniformly distributed int value between min 654 * and max (min and max included). 655 * 656 * @param min lower bound for generated long integer 657 * @param max upper bound for generated long integer 658 * @return a random long integer greater than or equal to {@code min} 659 * and less than or equal to {@code max} 660 * @throws IllegalArgumentException if {@code min >= max} 661 */ 662 public static long nextLong( 663 final Random random, 664 final long min, final long max 665 ) { 666 if (min >= max) { 667 throw new IllegalArgumentException(format( 668 "min >= max: %d >= %d.", min, max 669 )); 670 } 671 672 final long diff = (max - min) + 1; 673 long result = 0; 674 675 if (diff <= 0) { 676 do { 677 result = random.nextLong(); 678 } while (result < min || result > max); 679 } else if (diff < Integer.MAX_VALUE) { 680 result = random.nextInt((int)diff) + min; 681 } else { 682 result = nextLong(random, diff) + min; 683 } 684 685 return result; 686 } 687 688 /** 689 * Returns a pseudorandom, uniformly distributed int value between 0 690 * (inclusive) and the specified value (exclusive), drawn from the given 691 * random number generator's sequence. 692 * 693 * @param random the random engine used for creating the random number. 694 * @param n the bound on the random number to be returned. Must be 695 * positive. 696 * @return the next pseudorandom, uniformly distributed int value 697 * between 0 (inclusive) and n (exclusive) from the given random 698 * number generator's sequence 699 * @throws IllegalArgumentException if n is smaller than 1. 700 */ 701 public static long nextLong(final Random random, final long n) { 702 if (n <= 0) { 703 throw new IllegalArgumentException(format( 704 "n is smaller than one: %d", n 705 )); 706 } 707 708 long bits; 709 long result; 710 do { 711 bits = random.nextLong() & 0x7fffffffffffffffL; 712 result = bits%n; 713 } while (bits - result + (n - 1) < 0); 714 715 return result; 716 } 717 718 /** 719 * Returns a pseudorandom, uniformly distributed double value between 720 * min (inclusively) and max (exclusively). 721 * 722 * @param random the random engine used for creating the random number. 723 * @param min lower bound for generated float value 724 * @param max upper bound for generated float value 725 * @return a random float greater than or equal to {@code min} and less 726 * than to {@code max} 727 */ 728 public static float nextFloat( 729 final Random random, 730 final float min, final float max 731 ) { 732 return random.nextFloat()*(max - min) + min; 733 } 734 735 /** 736 * Returns a pseudorandom, uniformly distributed double value between 737 * min (inclusively) and max (exclusively). 738 * 739 * @param random the random engine used for creating the random number. 740 * @param min lower bound for generated double value 741 * @param max upper bound for generated double value 742 * @return a random double greater than or equal to {@code min} and less 743 * than to {@code max} 744 */ 745 public static double nextDouble( 746 final Random random, 747 final double min, final double max 748 ) { 749 return random.nextDouble()*(max - min) + min; 750 } 751 752 /** 753 * Create a new <em>seed</em> byte array of the given length. 754 * 755 * @see #seed(byte[]) 756 * @see #seed() 757 * 758 * @param length the length of the returned byte array. 759 * @return a new <em>seed</em> byte array of the given length 760 * @throws NegativeArraySizeException if the given length is smaller 761 * than zero. 762 */ 763 public static byte[] seedBytes(final int length) { 764 return seed(new byte[length]); 765 } 766 767 /** 768 * Fills the given byte array with random bytes, created by successive 769 * calls of the {@link #seed()} method. 770 * 771 * @see #seed() 772 * 773 * @param seed the byte array seed to fill with random bytes. 774 * @return the given byte array, for method chaining. 775 * @throws NullPointerException if the {@code seed} array is 776 * {@code null}. 777 */ 778 public static byte[] seed(final byte[] seed) { 779 for (int i = 0, len = seed.length; i < len;) { 780 int n = Math.min(len - i, Long.SIZE/Byte.SIZE); 781 782 for (long x = seed(); n-- > 0; x >>= Byte.SIZE) { 783 seed[i++] = (byte)x; 784 } 785 } 786 787 return seed; 788 } 789 790 /** 791 * Calculating a 64 bit seed value which can be used for initializing 792 * PRNGs. This method uses a combination of {@code System.nanoTime()} 793 * and {@code new Object().hashCode()} calls to create a reasonable safe 794 * seed value: 795 * <p/> 796 *
<a name="line.796"></a> <span class="sourceLineNo">797</span> * public static long seed() {<a name="line.797"></a> <span class="sourceLineNo">798</span> * return seed(System.nanoTime());<a name="line.798"></a> <span class="sourceLineNo">799</span> * }<a name="line.799"></a>
801 * <p/> 802 * This method passes all of the statistical tests of the 803 * <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> 804 * dieharder</a> test suite&mdash;executed on a linux machine with 805 * JDK version 1.7. <em>Since there is no prove that this will the case 806 * for every Java version and OS, it is recommended to only use this 807 * method for seeding other PRNGs.</em> 808 * 809 * @see #seed(long) 810 * 811 * @return the random seed value. 812 */ 813 public static long seed() { 814 return seed(System.nanoTime()); 815 } 816 817 /** 818 * Uses the given {@code base} value to create a reasonable safe seed 819 * value. This is done by combining it with values of 820 * {@code new Object().hashCode()}: 821 * <p/> 822 *
<a name="line.822"></a> <span class="sourceLineNo">823</span> * public static long seed(final long base) {<a name="line.823"></a> <span class="sourceLineNo">824</span> * final long objectHashSeed = ((long)(new Object().hashCode()) &lt;&lt; 32) |<a name="line.824"></a> <span class="sourceLineNo">825</span> * new Object().hashCode();<a name="line.825"></a> <span class="sourceLineNo">826</span> * long seed = base ^ objectHashSeed;<a name="line.826"></a> <span class="sourceLineNo">827</span> * seed ^= seed &lt;&lt; 17;<a name="line.827"></a> <span class="sourceLineNo">828</span> * seed ^= seed &gt;&gt;&gt; 31;<a name="line.828"></a> <span class="sourceLineNo">829</span> * seed ^= seed &lt;&lt; 8;<a name="line.829"></a> <span class="sourceLineNo">830</span> * return seed;<a name="line.830"></a> <span class="sourceLineNo">831</span> * }<a name="line.831"></a>
833 * 834 * @param base the base value of the seed to create 835 * @return the created seed value. 836 */ 837 public static long seed(final long base) { 838 return mix(base, objectHashSeed()); 839 } 840 841 private static long mix(final long a, final long b) { 842 long c = a^b; 843 c ^= c << 17; 844 c ^= c >>> 31; 845 c ^= c << 8; 846 return c; 847 } 848 849 private static long objectHashSeed() { 850 return ((long)(new Object().hashCode()) << 32) | 851 new Object().hashCode(); 852 } 853 854 } 855 856}