package edu.cornell.lassp.houle.RngPack;

//
// RngPack 1.1a by Paul Houle
// http://www.honeylocust.com/RngPack/
//

/**
* RandomShuffle uses one random number generator to shuffle the numbers
* produced by another to obliterate sequential correlations.
* To initialize a RandomShuffle,  pass it two RandomElements.  The
* first RandomElement is used to generate a table of random numbers
* and the second is used to choose one from the table.  An example of
* usage is,
*
* <PRE>
* RandomElement markov=new RandomShuffle(new Ranecu(),new Ranmar(),32)
* </PRE>
*
* which would generate a deck of 32 numbers from <TT>RANECU</TT> and
* use <TT>RANMAR</TT> to choose from the deck.
*
* <BR>
* <B>References:</B>
* <UL>
* <LI> F. James; <CITE>Comp. Phys. Comm.</CITE> <STRONG>60</STRONG> (1990) p 329-344
* <LI> D. Knuth; <CITE>The Art of Computer Programming</CITE> vol. 2, sec 3.2.2
* </UL>
*
* <P>
* <A HREF="/RngPack/src/edu/cornell/lassp/houle/RngPack/RandomShuffle.java">
* Source code </A> is available.
*
* @author <A HREF="http://www.honeylocust.com/"> Paul Houle </A> (E-mail: <A HREF="paul@honeylocust.com">paul@honeylocust.com</A>)
* @version 1.1a
*/

public class RandomShuffle extends RandomElement {

  RandomElement generatorA,generatorB;
  int decksize;
  double deck[]; 

/**
* @param ga generator to fill shuffle deck
* @param gb geberator to choose from shuffle deck
* @param ds the size of the shuffle deck
*/

  public RandomShuffle(RandomElement ga,RandomElement gb,int ds) {

	generatorA=ga;
        generatorB=gb;
	decksize=ds;

	stackdeck();

};

/**
* The generator.
*
* @see RandomElement#raw
*/

public double raw() {
        double random;
	int i;

	i=generatorB.choose(0,decksize-1);
        random=deck[i];
        deck[i]=generatorA.raw();

	return random;
};

private void stackdeck() {

        int i;
	deck = new double[decksize];
	
	for(i=0;i<decksize;i++)
		deck[i]=generatorA.raw();
};

};


