All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.it.unimi.dsi.test.XorShiftPoly Maven / Gradle / Ivy

Go to download

The DSI utilities are a mishmash of classes accumulated during the last twenty years in projects developed at the DSI (Dipartimento di Scienze dell'Informazione, i.e., Information Sciences Department), now DI (Dipartimento di Informatica, i.e., Informatics Department), of the Universita` degli Studi di Milano.

There is a newer version: 2.7.3
Show newest version
package it.unimi.dsi.test;

/*
 * Copyright (C) 2014-2020 Sebastiano Vigna
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 3 of the License, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see .
 *
 */


import java.math.BigInteger;

public class XorShiftPoly {

	private XorShiftPoly() {}

	/** The number of bits of state of the generator. */
	public static int bits;

	/** The period of the generator (2{@link #bits} − 1). */
	public static BigInteger twoToBitsMinus1;

	/** Factors of the Fermat “primes” up to the eleventh (22048 + 1). */
	public static final BigInteger[] factor = {
			new BigInteger("3"),
			new BigInteger("5"),
			new BigInteger("17"),
			new BigInteger("257"),
			new BigInteger("65537"),
			new BigInteger("641"),
			new BigInteger("6700417"),
			new BigInteger("274177"),
			new BigInteger("67280421310721"),
			new BigInteger("59649589127497217"),
			new BigInteger("5704689200685129054721"),
			new BigInteger("1238926361552897"),
			new BigInteger("93461639715357977769163558199606896584051237541638188580280321"),
			new BigInteger("2424833"),
			new BigInteger("7455602825647884208337395736200454918783366342657"),
			new BigInteger("741640062627530801524787141901937474059940781097519023905821316144415759504705008092818711693940737"),
			new BigInteger("45592577"),
			new BigInteger("6487031809"),
			new BigInteger("4659775785220018543264560743076778192897"),
			new BigInteger("130439874405488189727484768796509903946608530841611892186895295776832416251471863574140227977573104895898783928842923844831149032913798729088601617946094119449010595906710130531906171018354491609619193912488538116080712299672322806217820753127014424577"),
			new BigInteger("319489"),
			new BigInteger("974849"),
			new BigInteger("167988556341760475137"),
			new BigInteger("3560841906445833920513"),
			new BigInteger("173462447179147555430258970864309778377421844723664084649347019061363579192879108857591038330408837177983810868451546421940712978306134189864280826014542758708589243873685563973118948869399158545506611147420216132557017260564139394366945793220968665108959685482705388072645828554151936401912464931182546092879815733057795573358504982279280090942872567591518912118622751714319229788100979251036035496917279912663527358783236647193154777091427745377038294584918917590325110939381322486044298573971650711059244462177542540706913047034664643603491382441723306598834177")
	};

	/** An array of cofactors. Entry 0 ≤ {@code i} < {@link #numCofactors} contains {@link #twoToBitsMinus1} divided by {@link #factor factor[i]}. Note that some
	 * entries can be {@code null} if {@link #bits} is less then 4096. */
	public static final BigInteger[] cofactor = new BigInteger[factor.length];

	/** The actual number of valid entries in {@link #cofactor}. */
	public static int numCofactors;

	/** Computes the power to a given exponent, given the quadratures.
	 *
	 * @param e an exponent smaller than or equal to 2{@link #bits}.
	 */
	public static void mPow(BigInteger e) {
		System.out.println("p := 1;");
		for(int i = 0; ! e.equals(BigInteger.ZERO); i++) {
			if (e.testBit(0)) System.out.println("p := *p * q[" + i + "];");
			e = e.shiftRight(1);
		}
	}

	public static void main(final String arg[]) {
		bits = Integer.parseInt(arg[0]);

		if (bits > 4096 || bits != Integer.highestOneBit(bits)) {
			System.err.println("The number of bits must be a power of two smaller than or equal to 4096");
			System.exit(1);
		}

		BigInteger result = BigInteger.ONE;
		twoToBitsMinus1 = BigInteger.valueOf(2).pow(bits).subtract(BigInteger.ONE);
		int n;
		// Initialize cofactors.
		for(n = 0; n < factor.length; n++) {
			cofactor[n] = twoToBitsMinus1.divide(factor[n]);
			result = result.multiply(factor[n]);
			if (twoToBitsMinus1.equals(result)) break;
		}

		numCofactors = n + 1;
		// Safety check (you know, those numbers are LONG).
		if (! twoToBitsMinus1.equals(result)) throw new AssertionError();

		System.out.println("Array q[" + (bits + 1) + "];");
		// Quadratures
		System.out.println("q[0] := x;");
		for(int i1 = 1; i1 <= bits; i1++) System.out.println("q[" + i1 + "] := q[" + (i1 - 1) + "] * q[" + (i1 - 1) + "];");
		System.out.println("!!('Check: ', if q[" + bits + "] = x then 1 else 0; &q fi);");
		// Exponentiation to cofactors
		for(int i = 0; i < numCofactors; i++) {
			mPow(cofactor[i]);
			System.out.println("!!('Result: ', if p = 1 then 0; &q else 1 fi);");
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy