/*********************************************************************
 *  This class implements a linear congruential generator (LCG)
 *
 *  Methods:
 *  int intRand()         output: z_i
 *  double doubleRand()   output u_i
 * 
 *  @param m modulusder of the LCG
 *  @param a factor of the LCG
 *  @param a increment of the LCG
 *  @param z pseudo random number (o random seed)
 *  
 *  @author U. Pantle, 18.06.06
 ********************************************************************/

public class CongruentialGenerator{

/* Initialising the parameters */
    private int z = 1, m = 256, a = 17, c=0;
    
/**
 *  Constructs a LCG
 *  with modulus 256, factor 17, increment 0 und seed 1
 */
    public CongruentialGenerator(){
    }

/**
 *   Constructs a LCG with specific parameters
 */
    public CongruentialGenerator(int seed, int modulus, int factor, int incr){
	this.z = seed;
	this.m = modulus;
	this.a = factor;
	this.c = incr;
    }


/**
 *   generating pseudo random numbers in {0,...,m-1}
 *
 *   @return next pseudo random number
 */
    public int intRand(){
	z = (a*z+c)%m;
	return z;
    }

/**
 * transformation of {0,...,m-1} onto [0,1)
 *
 * @return u  pseudo random number in [0,1)
 */
    public double uniRand(){
	double v = intRand();
	double u = v/m;
	return u;
    }

/**
 *  main programm
 */
    static public void main(String[] args){
	/* Initialising with fixed parameters */
	CongruentialGenerator lcg = new CongruentialGenerator();

	if(args.length == 4){
	    /* initialise the parameters
	       attention: wrong input is not intercepted */
	    lcg = new CongruentialGenerator(Integer.parseInt(args[0]), 
					 Integer.parseInt(args[1]), 
		  		         Integer.parseInt(args[2]), 
		  		         Integer.parseInt(args[3]));
	}
        /* input error: not all parameters are specified */
	else if(args.length > 0 && args.length < 3){
	    System.out.println("Please indicate the values of z, m, a and c");
	}

        /* output: the first 10 pseudo random numbers */
	System.out.println("The first 10 pseudo random numbers");
	for(int i=0; i < 10; i++){
  	    System.out.println((i+1)+" th value: "+lcg.intRand());
	}

        /* output: the first 10 pseudo random numbers */
	System.out.println("\n10 pseudo random numbers from uniform distribution");
	for(int i=0; i < 10; i++){
  	    System.out.println((i+1)+" th value: "+lcg.uniRand());
	}

    }
}


