math.java
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  */
020 package org.jenetics.util;
021 
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 
025 import 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  */
034 public 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      * [code]
255      * double a = 0.0;
256      * for (int i = 0; i < 10; ++i) {
257      *     a = Math.nextAfter(a, Double.POSITIVE_INFINITY);
258      * }
259      *
260      * for (int i = 0; i < 19; ++i) {
261      *     a = Math.nextAfter(a, Double.NEGATIVE_INFINITY);
262      *     System.out.println(
263      *          a + "\t" + ulpPosition(a) + "\t" + ulpDistance(0.0, a)
264      *     );
265      * }
266      * [/code]
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[l1;
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[i0;
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 + - i;
473             l = (sub[ip - 1]*k - 1)/n;
474             ids = sub[ip - 1((l - 1)*n)/k;
475             sub[ip - 10;
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 + - ll;
484 
485             if (sub[l - 1!= 0) {
486                 ir = l;
487                 m0 = ((sub[l - 11)*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                 subi- 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 - : 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 - min1;
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 - 10);
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          * [code]
797          * public static long seed() {
798          *     return seed(System.nanoTime());
799          * }
800          * [/code]
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          * [code]
823          * public static long seed(final long base) {
824          *     final long objectHashSeed = ((long)(new Object().hashCode()) << 32) |
825          *                                         new Object().hashCode();
826          *     long seed = base ^ objectHashSeed;
827          *     seed ^= seed << 17;
828          *     seed ^= seed >>> 31;
829          *     seed ^= seed << 8;
830          *     return seed;
831          * }
832          * [/code]
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 }