001/*
002 * Java Genetic Algorithm Library (jenetics-3.7.0).
003 * Copyright (c) 2007-2016 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;
024import static org.jenetics.internal.util.Equality.eq;
025
026import java.io.Serializable;
027
028import org.jenetics.internal.math.arithmetic;
029import org.jenetics.internal.math.random;
030import org.jenetics.internal.util.Equality;
031import org.jenetics.internal.util.Hash;
032
033/**
034 * This class implements a linear congruential PRNG with additional bit-shift
035 * transition. The base recursion
036 * <p>
037 * <img
038 *     alt="r_{i+1} = (a\cdot r_i + b) \mod 2^{64}"
039 *     src="doc-files/lcg-recursion.gif"
040 * >
041 * </p>
042 * is followed by a non-linear transformation
043 * <p>
044 * <img
045 *     alt="\begin{eqnarray*}
046 *           t &=& r_i                \\
047 *           t &=& t \oplus (t >> 17) \\
048 *           t &=& t \oplus (t << 31) \\
049 *           t &=& t \oplus (t >> 8)
050 *         \end{eqnarray*}"
051 *     src="doc-files/lcg-non-linear.gif"
052 * >
053 * </p>
054 * which destroys the lattice structure introduced by the recursion. The period
055 * of this PRNG is 2<sup>64</sup>, {@code iff} <i>b</i> is odd and <i>a</i>
056 * {@code mod} 4 = 1.
057 * <p>
058 *
059 * <em>
060 * This is an re-implementation of the
061 * <a href="https://github.com/rabauke/trng4/blob/master/src/lcg64_shift.hpp">
062 * trng::lcg64_shift</a> PRNG class of the
063 * <a href="http://numbercrunch.de/trng/">TRNG</a> library created by Heiko
064 * Bauke.</em>
065 *
066 * <p>
067 * <strong>Not that the base implementation of the {@code LCG64ShiftRandom}
068 * class is not thread-safe.</strong> If multiple threads requests random
069 * numbers from this class, it <i>must</i> be synchronized externally.
070 * Alternatively you can use the thread-safe implementations
071 * {@link LCG64ShiftRandom.ThreadSafe} or {@link LCG64ShiftRandom.ThreadLocal}.
072 *
073 * @see <a href="http://numbercrunch.de/trng/">TRNG</a>
074 * @see RandomRegistry
075 *
076 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
077 * @since 1.1
078 * @version 2.0
079 */
080public class LCG64ShiftRandom extends Random64 {
081
082        private static final long serialVersionUID = 1L;
083
084        /**
085         * This class represents a <i>thread local</i> implementation of the
086         * {@code LCG64ShiftRandom} PRNG.
087         *
088         * It's recommended to initialize the {@code RandomRegistry} the following
089         * way:
090         *
091         * <pre>{@code
092         * // Register the PRNG with the default parameters.
093         * RandomRegistry.setRandom(new LCG64ShiftRandom.ThreadLocal());
094         *
095         * // Register the PRNG with the {@code LECUYER3} parameters.
096         * RandomRegistry.setRandom(new LCG64ShiftRandom.ThreadLocal(
097         *     LCG64ShiftRandom.LECUYER3
098         * ));
099         * }</pre>
100         *
101         * Be aware, that calls of the {@code setSeed(long)} method will throw an
102         * {@code UnsupportedOperationException} for <i>thread local</i> instances.
103         * <pre>{@code
104         * RandomRegistry.setRandom(new LCG64ShiftRandom.ThreadLocal());
105         *
106         * // Will throw 'UnsupportedOperationException'.
107         * RandomRegistry.getRandom().setSeed(1234);
108         * }</pre>
109         *
110         * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
111         * @since 1.1
112         * @version 3.0
113         */
114        public static final class ThreadLocal
115                extends java.lang.ThreadLocal<LCG64ShiftRandom>
116        {
117                private static final long STEP_BASE = 1L << 56;
118
119                private int _block = 0;
120                private long _seed = random.seed();
121
122                private final Param _param;
123
124                /**
125                 * Create a new <i>thread local</i> instance of the
126                 * {@code LCG64ShiftRandom} PRNG with the {@code DEFAULT} parameters.
127                 */
128                public ThreadLocal() {
129                        this(Param.DEFAULT);
130                }
131
132                /**
133                 * Create a new <i>thread local</i> instance of the
134                 * {@code LCG64ShiftRandom} PRNG with the given parameters.
135                 *
136                 * @param param the LC parameters.
137                 * @throws NullPointerException if the given parameters are null.
138                 */
139                public ThreadLocal(final Param param) {
140                        _param = requireNonNull(param, "PRNG param must not be null.");
141                }
142
143                /**
144                 * Create a new PRNG using <i>block splitting</i> for guaranteeing well
145                 * distributed PRN for every thread.
146                 *
147                 * <p>
148                 * <strong>Tina’s Random Number Generator Library</strong>
149                 * <br>
150                 * <em>Chapter 2. Pseudo-random numbers for parallel Monte Carlo
151                 *     simulations, Page 7</em>
152                 * <br>
153                 * <small>Heiko Bauke</small>
154                 * <br>
155                 * [<a href="http://numbercrunch.de/trng/trng.pdf">
156                 *  http://numbercrunch.de/trng/trng.pdf
157                 *  </a>].
158                 */
159                @Override
160                protected synchronized LCG64ShiftRandom initialValue() {
161                        if (_block > 127) {
162                                _block = 0;
163                                _seed = random.seed();
164                        }
165
166                        final LCG64ShiftRandom random = new TLLCG64ShiftRandom(_seed, _param);
167                        random.jump(_block++*STEP_BASE);
168                        return random;
169                }
170
171        }
172
173        private static final class TLLCG64ShiftRandom extends LCG64ShiftRandom {
174                private static final long serialVersionUID = 1L;
175
176                private final Boolean _sentry = Boolean.TRUE;
177
178                private TLLCG64ShiftRandom(final long seed, final Param param) {
179                        super(param, seed);
180                }
181
182                @Override
183                public void setSeed(final long seed) {
184                        if (_sentry != null) {
185                                throw new UnsupportedOperationException(
186                                        "The 'setSeed(long)' method is not supported " +
187                                        "for thread local instances."
188                                );
189                        }
190                }
191
192        }
193
194        /**
195         * This is a <i>thread safe</i> variation of the this PRNG&mdash;by
196         * synchronizing the random number generation.
197         *
198         * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
199         * @since 1.1
200         * @version 3.0
201         */
202        public static final class ThreadSafe extends LCG64ShiftRandom {
203                private static final long serialVersionUID = 1L;
204
205                /**
206                 * Create a new PRNG instance with the given parameter and seed.
207                 *
208                 * @param seed the seed of the PRNG.
209                 * @param param the parameter of the PRNG.
210                 * @throws NullPointerException if the given {@code param} is null.
211                 *
212                 * @deprecated Use {@code LCG64ShiftRandom.ThreadSafe(Param, long)}
213                 *             instead.
214                 */
215                @Deprecated
216                public ThreadSafe(final long seed, final Param param) {
217                        super(param, seed);
218                }
219
220                /**
221                 * Create a new PRNG instance with the given parameter and seed.
222                 *
223                 * @param seed the seed of the PRNG.
224                 * @param param the parameter of the PRNG.
225                 * @throws NullPointerException if the given {@code param} is null.
226                 */
227                public ThreadSafe(final Param param, final long seed) {
228                        super(param, seed);
229                }
230
231                /**
232                 * Create a new PRNG instance with {@link Param#DEFAULT} parameter and
233                 * the given seed.
234                 *
235                 * @param seed the seed of the PRNG
236                 */
237                public ThreadSafe(final long seed) {
238                        this(Param.DEFAULT, seed);
239                }
240
241                /**
242                 * Create a new PRNG instance with the given parameter and a safe
243                 * default seed.
244                 *
245                 * @param param the PRNG parameter.
246                 * @throws NullPointerException if the given {@code param} is null.
247                 */
248                public ThreadSafe(final Param param) {
249                        this(param, random.seed());
250                }
251
252                /**
253                 * Create a new PRNG instance with {@link Param#DEFAULT} parameter and
254                 * a safe seed.
255                 */
256                public ThreadSafe() {
257                        this(Param.DEFAULT, random.seed());
258                }
259
260                @Override
261                public synchronized void setSeed(final long seed) {
262                        super.setSeed(seed);
263                }
264
265                @Override
266                public synchronized long nextLong() {
267                        return super.nextLong();
268                }
269
270                @Override
271                public synchronized void split(final int p, final int s) {
272                        super.split(p, s);
273                }
274
275                @Override
276                public synchronized void jump2(final int s) {
277                        super.jump2(s);
278                }
279
280                @Override
281                public synchronized void jump(final long step) {
282                        super.jump(step);
283                }
284
285        }
286
287        /**
288         * Parameter class for the {@code LCG64ShiftRandom} generator, for the
289         * parameters <i>a</i> and <i>b</i> of the LC recursion
290         * <i>r<sub>i+1</sub> = a · r<sub>i</sub> + b</i> mod <i>2<sup>64</sup></i>.
291         *
292         * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
293         * @since 1.1
294         * @version 2.0
295         */
296        public static final class Param implements Serializable {
297
298                private static final long serialVersionUID = 1L;
299
300                /**
301                 * The default PRNG parameters: a = 0xFBD19FBBC5C07FF5L; b = 1
302                 */
303                public static final Param DEFAULT = Param.of(0xFBD19FBBC5C07FF5L, 1L);
304
305                /**
306                 * LEcuyer 1 parameters: a = 0x27BB2EE687B0B0FDL; b = 1
307                 */
308                public static final Param LECUYER1 = Param.of(0x27BB2EE687B0B0FDL, 1L);
309
310                /**
311                 * LEcuyer 2 parameters: a = 0x2C6FE96EE78B6955L; b = 1
312                 */
313                public static final Param LECUYER2 = Param.of(0x2C6FE96EE78B6955L, 1L);
314
315                /**
316                 * LEcuyer 3 parameters: a = 0x369DEA0F31A53F85L; b = 1
317                 */
318                public static final Param LECUYER3 = Param.of(0x369DEA0F31A53F85L, 1L);
319
320
321                /**
322                 * The parameter <i>a</i> of the LC recursion.
323                 */
324                public final long a;
325
326                /**
327                 * The parameter <i>b</i> of the LC recursion.
328                 */
329                public final long b;
330
331                /**
332                 * Create a new parameter object.
333                 *
334                 * @param a the parameter <i>a</i> of the LC recursion.
335                 * @param b the parameter <i>b</i> of the LC recursion.
336                 */
337                private Param(final long a, final long b) {
338                        this.a = a;
339                        this.b = b;
340                }
341
342                public static Param of(final long a, final long b) {
343                        return new Param(a, b);
344                }
345
346                @Override
347                public int hashCode() {
348                        return 31*(int)(a^(a >>> 32)) + 31*(int)(b^(b >>> 32));
349                }
350
351                @Override
352                public boolean equals(final Object obj) {
353                        return obj instanceof Param &&
354                                ((Param)obj).a == a &&
355                                ((Param)obj).b == b;
356                }
357
358                @Override
359                public String toString() {
360                        return format("%s[a=%d, b=%d]", getClass().getName(), a, b);
361                }
362        }
363
364        /**
365         * Represents the state of this random engine
366         */
367        private final static class State implements Serializable {
368                private static final long serialVersionUID = 1L;
369
370                long _r;
371
372                State(final long seed) {
373                        setSeed(seed);
374                }
375
376                void setSeed(final long seed) {
377                        _r = seed;
378                }
379
380                @Override
381                public int hashCode() {
382                        return Hash.of(getClass()).and(_r).value();
383                }
384
385                @Override
386                public boolean equals(final Object obj) {
387                        return obj instanceof State && ((State)obj)._r == _r;
388                }
389
390                @Override
391                public String toString() {
392                        return format("State[%d]", _r);
393                }
394        }
395
396
397        private Param _param;
398        private final State _state;
399
400        /**
401         * Create a new PRNG instance with the given parameter and seed.
402         *
403         * @param param the parameter of the PRNG.
404         * @param seed the seed of the PRNG.
405         * @throws NullPointerException if the given {@code param} is null.
406         */
407        public LCG64ShiftRandom(final Param param, final long seed) {
408                _param = requireNonNull(param, "PRNG param must not be null.");
409                _state = new State(seed);
410        }
411
412        /**
413         * Create a new PRNG instance with the given parameter and a safe seed
414         *
415         * @param param the PRNG parameter.
416         * @throws NullPointerException if the given {@code param} is null.
417         */
418        public LCG64ShiftRandom(final Param param) {
419                this(param, random.seed());
420        }
421
422        /**
423         * Create a new PRNG instance with {@link Param#DEFAULT} parameter and the
424         * given seed.
425         *
426         * @param seed the seed of the PRNG
427         */
428        public LCG64ShiftRandom(final long seed) {
429                this(Param.DEFAULT, seed);
430        }
431
432        /**
433         * Create a new PRNG instance with {@link Param#DEFAULT} parameter and safe
434         * seed.
435         */
436        public LCG64ShiftRandom() {
437                this(Param.DEFAULT, random.seed());
438        }
439
440        @Override
441        public long nextLong() {
442                step();
443
444                long t = _state._r;
445                t ^= t >>> 17;
446                t ^= t << 31;
447                t ^= t >>> 8;
448                return t;
449        }
450
451        private void step() {
452                _state._r = _param.a*_state._r + _param.b;
453        }
454
455        @Override
456        public void setSeed(final long seed) {
457                if (_state != null) _state.setSeed(seed);
458        }
459
460        /**
461         * Changes the internal state of the PRNG in a way that future calls to
462         * {@link #nextLong()} will generated the s<sup>th</sup> sub-stream of
463         * p<sup>th</sup> sub-streams. <i>s</i> must be within the range of
464         * {@code [0, p-1)}. This method is mainly used for <i>parallelization</i>
465         * via <i>leap-frogging</i>.
466         *
467         * @param p the overall number of sub-streams
468         * @param s the s<sup>th</sup> sub-stream
469         * @throws IllegalArgumentException if {@code p < 1 || s >= p}.
470         */
471        public void split(final int p, final int s) {
472                if (p < 1) {
473                        throw new IllegalArgumentException(format(
474                                "p must be >= 1 but was %d.", p
475                        ));
476                }
477                if (s >= p) {
478                        throw new IllegalArgumentException(format(
479                                "s must be < %d but was %d.", p, s
480                        ));
481                }
482
483                if (p > 1) {
484                        jump(s + 1);
485                        final long b = _param.b*f(p, _param.a);
486                        final long a = arithmetic.pow(_param.a, p);
487                        _param = Param.of(a, b);
488                        backward();
489                }
490        }
491
492        /**
493         * Changes the internal state of the PRNG in such a way that the engine
494         * <i>jumps</i> 2<sup>s</sup> steps ahead.
495         *
496         * @param s the 2<sup>s</sup> steps to jump ahead.
497         * @throws IllegalArgumentException if {@code s < 0}.
498         */
499        public void jump2(final int s) {
500                if (s < 0) {
501                        throw new IllegalArgumentException(format(
502                                "s must be positive but was %d.", s
503                        ));
504                }
505
506                if (s >= Long.SIZE) {
507                        throw new IllegalArgumentException(format(
508                                "The 'jump2' size must be smaller than %d but was %d.",
509                                Long.SIZE, s
510                        ));
511                }
512
513                _state._r = _state._r*arithmetic.pow(_param.a, 1L << s) +
514                                        f(1L << s, _param.a)*_param.b;
515        }
516
517        /**
518         * Changes the internal state of the PRNG in such a way that the engine
519         * <i>jumps</i> s steps ahead.
520         *
521         * @param step the steps to jump ahead.
522         * @throws IllegalArgumentException if {@code s < 0}.
523         */
524        public void jump(final long step) {
525                if (step < 0) {
526                        throw new IllegalArgumentException(format(
527                                "step must be positive but was %d", step
528                        ));
529                }
530
531                if (step < 16) {
532                        for (int i = 0; i < step; ++i) {
533                                step();
534                        }
535                } else {
536                        long s = step;
537                        int i = 0;
538                        while (s > 0) {
539                                if (s%2 == 1) {
540                                        jump2(i);
541                                }
542                                ++i;
543                                s >>= 1;
544                        }
545                }
546        }
547
548        private void backward() {
549                for (int i = 0; i < Long.SIZE; ++i) {
550                        jump2(i);
551                }
552        }
553
554        public Param getParam() {
555                return _param;
556        }
557
558        @Override
559        public int hashCode() {
560                return Hash.of(getClass())
561                        .and(_param)
562                        .and(_state).value();
563        }
564
565        @Override
566        public boolean equals(final Object obj) {
567                return Equality.of(this, obj).test(random ->
568                        eq(_param, random._param) &&
569                        eq(_state, random._state)
570                );
571        }
572
573        @Override
574        public String toString() {
575                return format("%s[%s, %s]", getClass().getSimpleName(), _param, _state);
576        }
577
578
579
580        /* *************************************************************************
581         * Some static helper methods
582         ***************************************************************************/
583
584        /**
585         * Compute prod(1+a^(2^i), i=0..l-1).
586         */
587        private static long g(final int l, final long a) {
588                long p = a;
589                long res = 1;
590                for (int i = 0; i < l; ++i) {
591                        res *= 1 + p;
592                        p *= p;
593                }
594
595                return res;
596        }
597
598        /**
599         * Compute sum(a^i, i=0..s-1).
600         */
601        private static long f(final long s, final long a) {
602                long y = 0;
603
604                if (s != 0) {
605                        long e = log2Floor(s);
606                        long p = a;
607
608                        for (int l = 0; l <= e; ++l) {
609                                if (((1L << l) & s) != 0) {
610                                        y = g(l, a) + p*y;
611                                }
612                                p *= p;
613                        }
614                }
615
616                return y;
617        }
618
619        private static long log2Floor(final long s) {
620                long x = s;
621                long y = 0;
622
623                while (x != 0) {
624                        x >>>= 1;
625                        ++y;
626                }
627
628                return y - 1;
629        }
630
631}
632
633/*
634#=============================================================================#
635# Testing: org.jenetics.util.LCG64ShiftRandom (2015-07-12 01:22)              #
636#=============================================================================#
637#=============================================================================#
638# Linux 3.19.0-22-generic (amd64)                                             #
639# java version "1.8.0_45"                                                     #
640# Java(TM) SE Runtime Environment (build 1.8.0_45-b14)                        #
641# Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02)                         #
642#=============================================================================#
643#=============================================================================#
644#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
645#=============================================================================#
646   rng_name    |rands/second|   Seed   |
647stdin_input_raw|  3.26e+07  |2198533946|
648#=============================================================================#
649        test_name   |ntup| tsamples |psamples|  p-value |Assessment
650#=============================================================================#
651   diehard_birthdays|   0|       100|     100|0.96061667|  PASSED
652      diehard_operm5|   0|   1000000|     100|0.49388035|  PASSED
653  diehard_rank_32x32|   0|     40000|     100|0.76944223|  PASSED
654    diehard_rank_6x8|   0|    100000|     100|0.81999775|  PASSED
655   diehard_bitstream|   0|   2097152|     100|0.66213596|  PASSED
656        diehard_opso|   0|   2097152|     100|0.35244278|  PASSED
657        diehard_oqso|   0|   2097152|     100|0.30642433|  PASSED
658         diehard_dna|   0|   2097152|     100|0.31111322|  PASSED
659diehard_count_1s_str|   0|    256000|     100|0.29900596|  PASSED
660diehard_count_1s_byt|   0|    256000|     100|0.84049939|  PASSED
661 diehard_parking_lot|   0|     12000|     100|0.25249632|  PASSED
662    diehard_2dsphere|   2|      8000|     100|0.89898431|  PASSED
663    diehard_3dsphere|   3|      4000|     100|0.87592069|  PASSED
664     diehard_squeeze|   0|    100000|     100|0.46151457|  PASSED
665        diehard_sums|   0|       100|     100|0.09988415|  PASSED
666        diehard_runs|   0|    100000|     100|0.71496719|  PASSED
667        diehard_runs|   0|    100000|     100|0.84035529|  PASSED
668       diehard_craps|   0|    200000|     100|0.39228628|  PASSED
669       diehard_craps|   0|    200000|     100|0.43227446|  PASSED
670 marsaglia_tsang_gcd|   0|  10000000|     100|0.92226509|  PASSED
671 marsaglia_tsang_gcd|   0|  10000000|     100|0.14768717|  PASSED
672         sts_monobit|   1|    100000|     100|0.99459043|  PASSED
673            sts_runs|   2|    100000|     100|0.14017900|  PASSED
674          sts_serial|   1|    100000|     100|0.93191375|  PASSED
675          sts_serial|   2|    100000|     100|0.78130569|  PASSED
676          sts_serial|   3|    100000|     100|0.48954386|  PASSED
677          sts_serial|   3|    100000|     100|0.20669186|  PASSED
678          sts_serial|   4|    100000|     100|0.51752304|  PASSED
679          sts_serial|   4|    100000|     100|0.81217070|  PASSED
680          sts_serial|   5|    100000|     100|0.61151292|  PASSED
681          sts_serial|   5|    100000|     100|0.43893995|  PASSED
682          sts_serial|   6|    100000|     100|0.70098249|  PASSED
683          sts_serial|   6|    100000|     100|0.88111033|  PASSED
684          sts_serial|   7|    100000|     100|0.08860893|  PASSED
685          sts_serial|   7|    100000|     100|0.10888449|  PASSED
686          sts_serial|   8|    100000|     100|0.48682957|  PASSED
687          sts_serial|   8|    100000|     100|0.79253724|  PASSED
688          sts_serial|   9|    100000|     100|0.57005454|  PASSED
689          sts_serial|   9|    100000|     100|0.57300065|  PASSED
690          sts_serial|  10|    100000|     100|0.60555174|  PASSED
691          sts_serial|  10|    100000|     100|0.26010863|  PASSED
692          sts_serial|  11|    100000|     100|0.23181253|  PASSED
693          sts_serial|  11|    100000|     100|0.55889710|  PASSED
694          sts_serial|  12|    100000|     100|0.50349009|  PASSED
695          sts_serial|  12|    100000|     100|0.67703032|  PASSED
696          sts_serial|  13|    100000|     100|0.09716434|  PASSED
697          sts_serial|  13|    100000|     100|0.01651733|  PASSED
698          sts_serial|  14|    100000|     100|0.58227903|  PASSED
699          sts_serial|  14|    100000|     100|0.49816453|  PASSED
700          sts_serial|  15|    100000|     100|0.35547243|  PASSED
701          sts_serial|  15|    100000|     100|0.77801465|  PASSED
702          sts_serial|  16|    100000|     100|0.55611062|  PASSED
703          sts_serial|  16|    100000|     100|0.45764285|  PASSED
704         rgb_bitdist|   1|    100000|     100|0.74657121|  PASSED
705         rgb_bitdist|   2|    100000|     100|0.95265707|  PASSED
706         rgb_bitdist|   3|    100000|     100|0.71143353|  PASSED
707         rgb_bitdist|   4|    100000|     100|0.99995544|   WEAK
708         rgb_bitdist|   5|    100000|     100|0.99616318|   WEAK
709         rgb_bitdist|   6|    100000|     100|0.66956720|  PASSED
710         rgb_bitdist|   7|    100000|     100|0.95378286|  PASSED
711         rgb_bitdist|   8|    100000|     100|0.46355875|  PASSED
712         rgb_bitdist|   9|    100000|     100|0.21831657|  PASSED
713         rgb_bitdist|  10|    100000|     100|0.97851877|  PASSED
714         rgb_bitdist|  11|    100000|     100|0.35608637|  PASSED
715         rgb_bitdist|  12|    100000|     100|0.11482554|  PASSED
716rgb_minimum_distance|   2|     10000|    1000|0.67569619|  PASSED
717rgb_minimum_distance|   3|     10000|    1000|0.40169012|  PASSED
718rgb_minimum_distance|   4|     10000|    1000|0.68466980|  PASSED
719rgb_minimum_distance|   5|     10000|    1000|0.85971777|  PASSED
720    rgb_permutations|   2|    100000|     100|0.98547170|  PASSED
721    rgb_permutations|   3|    100000|     100|0.13346308|  PASSED
722    rgb_permutations|   4|    100000|     100|0.30098202|  PASSED
723    rgb_permutations|   5|    100000|     100|0.49670259|  PASSED
724      rgb_lagged_sum|   0|   1000000|     100|0.00376838|   WEAK
725      rgb_lagged_sum|   1|   1000000|     100|0.84875325|  PASSED
726      rgb_lagged_sum|   2|   1000000|     100|0.47618795|  PASSED
727      rgb_lagged_sum|   3|   1000000|     100|0.74638546|  PASSED
728      rgb_lagged_sum|   4|   1000000|     100|0.66367284|  PASSED
729      rgb_lagged_sum|   5|   1000000|     100|0.38277246|  PASSED
730      rgb_lagged_sum|   6|   1000000|     100|0.89022413|  PASSED
731      rgb_lagged_sum|   7|   1000000|     100|0.20961380|  PASSED
732      rgb_lagged_sum|   8|   1000000|     100|0.85608212|  PASSED
733      rgb_lagged_sum|   9|   1000000|     100|0.98007494|  PASSED
734      rgb_lagged_sum|  10|   1000000|     100|0.11658240|  PASSED
735      rgb_lagged_sum|  11|   1000000|     100|0.59955707|  PASSED
736      rgb_lagged_sum|  12|   1000000|     100|0.00017001|   WEAK
737      rgb_lagged_sum|  13|   1000000|     100|0.90147191|  PASSED
738      rgb_lagged_sum|  14|   1000000|     100|0.41636295|  PASSED
739      rgb_lagged_sum|  15|   1000000|     100|0.37015147|  PASSED
740      rgb_lagged_sum|  16|   1000000|     100|0.66453012|  PASSED
741      rgb_lagged_sum|  17|   1000000|     100|0.18865006|  PASSED
742      rgb_lagged_sum|  18|   1000000|     100|0.12419575|  PASSED
743      rgb_lagged_sum|  19|   1000000|     100|0.39883314|  PASSED
744      rgb_lagged_sum|  20|   1000000|     100|0.09942580|  PASSED
745      rgb_lagged_sum|  21|   1000000|     100|0.53467964|  PASSED
746      rgb_lagged_sum|  22|   1000000|     100|0.97551479|  PASSED
747      rgb_lagged_sum|  23|   1000000|     100|0.53709182|  PASSED
748      rgb_lagged_sum|  24|   1000000|     100|0.97407004|  PASSED
749      rgb_lagged_sum|  25|   1000000|     100|0.19308485|  PASSED
750      rgb_lagged_sum|  26|   1000000|     100|0.02836261|  PASSED
751      rgb_lagged_sum|  27|   1000000|     100|0.09286364|  PASSED
752      rgb_lagged_sum|  28|   1000000|     100|0.64833884|  PASSED
753      rgb_lagged_sum|  29|   1000000|     100|0.50128799|  PASSED
754      rgb_lagged_sum|  30|   1000000|     100|0.18237609|  PASSED
755      rgb_lagged_sum|  31|   1000000|     100|0.92914172|  PASSED
756      rgb_lagged_sum|  32|   1000000|     100|0.11809175|  PASSED
757     rgb_kstest_test|   0|     10000|    1000|0.40816346|  PASSED
758     dab_bytedistrib|   0|  51200000|       1|0.21337569|  PASSED
759             dab_dct| 256|     50000|       1|0.25233302|  PASSED
760Preparing to run test 207.  ntuple = 0
761        dab_filltree|  32|  15000000|       1|0.29102117|  PASSED
762        dab_filltree|  32|  15000000|       1|0.48186931|  PASSED
763Preparing to run test 208.  ntuple = 0
764       dab_filltree2|   0|   5000000|       1|0.48666498|  PASSED
765       dab_filltree2|   1|   5000000|       1|0.90599317|  PASSED
766Preparing to run test 209.  ntuple = 0
767        dab_monobit2|  12|  65000000|       1|0.98621807|  PASSED
768#=============================================================================#
769# Summary: PASSED=110, WEAK=4, FAILED=0                                       #
770#          235,031.406 MB of random data created with 99.045 MB/sec           #
771#=============================================================================#
772#=============================================================================#
773# Runtime: 0:39:32                                                            #
774#=============================================================================#
775*/