package org.spaceroots.mantissa.random;

import java.util.Random;

/** This class implements a powerful pseudo-random number generator
 * studied by Robert M Ziff.

 * 

This generator belongs to the family of Generalized Feedback * Shift-Register (GFSR) generators, but uses four feedback taps * instead of two, thus greatly improving their quality for * Monte-Carlo simulations.

*

This generator is described in a paper by Robert M. Ziff in * 1997: Four-tap * shift-register-sequence random-number generators, it is * generator 9f (defined as R(471, 1586, 6988, 9689)) of * the paper. It has been kindly contributed to mantissa by Bill * Maier.

*

The class is implemented as a specialization of the standard * java.util.Random class. This allows to use it in * algorithms expecting a standard random generator, and hence benefit * from a better generator without code change.

* @author Bill Maier (java.util.Random specialization by Luc Maisonobe) * @version $Id: FourTapRandom.java 1666 2005-12-15 16:37:55Z luc $ */ public class FourTapRandom extends Random { /** Creates a new random number generator. *

The instance is initialized using the current time as the * seed.

*/ public FourTapRandom() { setSeed(System.currentTimeMillis()); } /** Creates a new random number generator using a single long seed. * @param seed the initial seed */ public FourTapRandom(long seed) { setSeed(seed); } /** Reinitialize the generator as if just built with the given seed. *

The state of the generator is exactly the same as a new * generator built with the same seed.

* @param seed the initial seed */ public void setSeed(long seed) { super.setSeed(seed); fourTapBuffer = new int[TAP4M + 1]; for (int j = 0; j <= TAP4M; j++) { fourTapBuffer[j] = super.next(32); } n4TapJ = 0; } /** Generate next pseudorandom number. *

This method is the core generation algorithm. As per * {@link java.util.Random Random} contract, it is used by all the * public generation methods for the various primitive types {@link * java.util.Random#nextBoolean nextBoolean}, {@link java.util.Random#nextBytes * nextBytes}, {@link java.util.Random#nextDouble nextDouble}, {@link * java.util.Random#nextFloat nextFloat}, {@link java.util.Random#nextGaussian * nextGaussian}, {@link java.util.Random#nextInt() nextInt} and {@link * java.util.Random#nextLong nextLong}.

* @param bits number of random bits to produce */ protected int next(int bits) { ++n4TapJ; fourTapBuffer[n4TapJ & TAP4M] = fourTapBuffer[(n4TapJ - TAP4A) & TAP4M] ^ fourTapBuffer[(n4TapJ - TAP4B) & TAP4M] ^ fourTapBuffer[(n4TapJ - TAP4C) & TAP4M] ^ fourTapBuffer[(n4TapJ - TAP4D) & TAP4M]; return fourTapBuffer[n4TapJ & TAP4M] >>> (32 - bits); } private static final int TAP4A = 471; private static final int TAP4B = 1586; private static final int TAP4C = 6988; private static final int TAP4D = 9689; private static final int TAP4M = 16383; private int[] fourTapBuffer; private int n4TapJ; private static final long serialVersionUID = -4095251494398895580L; }

Ads help maintain this website.