001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.util;
025    
026    import java.util.Random;
027    
028    /**
029     * Better than java.util.Random and almost as fast.
030     * 
031     * @author arndt
032     * 
033     */
034    public class RandomMersenne extends Random {
035            private static final long serialVersionUID = 5949991470054762974L;
036    
037            private long u;
038            private long v = 4101842887655102017L;
039            private long w = 1;
040    
041            public RandomMersenne() {
042                    this(System.nanoTime());
043            }
044    
045            public RandomMersenne(long seed) {
046                    u = seed ^ v;
047                    nextLong();
048                    v = u;
049                    nextLong();
050                    w = v;
051                    nextLong();
052            }
053    
054            public long nextLong() {
055                    u = u * 2862933555777941757L + 7046029254386353087L;
056                    v ^= v >>> 17;
057                    v ^= v << 31;
058                    v ^= v >>> 8;
059                    w = 4294957665L * (w & 0xffffffff) + (w >>> 32);
060                    long x = u ^ (u << 21);
061                    x ^= x >>> 35;
062                    x ^= x << 4;
063                    long ret = (x + v) ^ w;
064                    return ret;
065            }
066    
067            protected int next(int bits) {
068                    return (int) (nextLong() >>> (64 - bits));
069            }
070    
071    }