/* * 作成日: 2009/11/25 */ package jp.ac.fit.asura.nao.misc; import java.util.Random; import javax.vecmath.Point2f; /** * 32bitのXOR-SHIFTによる疑似乱数生成器. * * Java標準の乱数(48bit線形合同法)より3倍ぐらい速い. * * @author sey * * @version $Id: $ * */ public class XorShift32 extends Random { private int x; public XorShift32() { x = (int) (System.nanoTime() & 0xFFFFFFFF); } public XorShift32(int seed) { this.x = seed; } public int xorshift() { x ^= (x << 1); x ^= (x >>> 5); x ^= (x << 9); return x; } protected int next(int bits) { return xorshift() >>> (Integer.SIZE - bits); } // ボックス・ミュラー法による正規分布の作成 public void nextGaussian(Point2f p) { float v1, v2, s; do { v1 = 2 * nextFloat() - 1; // between -1 and 1 v2 = 2 * nextFloat() - 1; // between -1 and 1 s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); float multiplier = (float) Math.sqrt(-2 * (float) Math.log(s) / s); p.x = v1 * multiplier; p.y = v2 * multiplier; } public float nextGaussianFloat() { float v1, v2, s; do { v1 = 2 * nextFloat() - 1; // between -1 and 1 v2 = 2 * nextFloat() - 1; // between -1 and 1 s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); float multiplier = (float) Math.sqrt(-2 * (float) Math.log(s) / s); return v1 * multiplier; } float nextGaussian; boolean hasNextGaussian; public synchronized float nextGaussianFloat2() { if (hasNextGaussian) { hasNextGaussian = false; return nextGaussian; } hasNextGaussian = true; float v1, v2, s; do { v1 = 2 * nextFloat() - 1; // between -1 and 1 v2 = 2 * nextFloat() - 1; // between -1 and 1 s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); float multiplier = (float) Math.sqrt(-2 * (float) Math.log(s) / s); nextGaussian = v2 * multiplier; return v1 * multiplier; } @Override public void setSeed(long seed) { x = (int) (seed & 0xFFFFFFFF); } }