001    /**
002     * 
003     */
004    package edu.wwu.tobikley.acgc.mc;
005    
006    import cern.jet.random.engine.RandomEngine;
007    
008    /**
009     * Abstract implementation of a markov chain for simulation purposes,
010     * that provides all necessary functionality but the transition mechanim.
011     * 
012     * As a markov chain consists of the following three elements:
013     * 
014     * <ul>
015     * <li>the set of possible states called the state space,
016     * <li>the initial distribution, and
017     * <li>the transition probabilities.
018     * </ul>
019     * A concrete implementation, hence has yet to specify the type of the
020     * states and provide the implementation of the transition mechanism.
021     * Because of the implementations sole purpose is simulation, the initial
022     * state will be set using the classes constructor.
023     * 
024     * @version 1.0
025     * @author  Tobias Kley
026     */
027    public abstract class HomogeneousMarkovChain {
028            
029            /** Current state. */
030            protected Object currentState = null;
031            
032            /** Current time.*/
033            protected int t = 0;
034            
035            /** Pseudo random number generator used when updating. */
036            protected RandomEngine randomEngine = null; 
037            
038            /**
039             * Creates a new instance of the markov chain.
040             * 
041             * @param randomEngine Pseudo random number generator. 
042             * @param initialState State to initialise the markov chain at time t = 0.
043             */
044            public HomogeneousMarkovChain(RandomEngine randomEngine, Object initialState) {
045                    this.currentState = initialState;
046                    this.randomEngine = randomEngine;
047            }
048            
049            /**
050             * Spezifies the transition mechanism of the markov chain.
051             * The implementation has is to simulate the state at time t+1 given
052             * the current time is t. Updating the state of the markovchain will use
053             * always use random numbers invoking <code>randomEngine.raw()</code>.
054             * 
055             * @param fromState State at time t.
056             * @return State at time t+1.
057             */
058            public abstract Object update(Object fromState);
059            
060            /**
061             * Performs one update on the markov chain.
062             * 
063             * @return State of the markov chain at time t+1,
064             *                 given the current time is t.
065             */
066            public Object next() {
067                    currentState = update(currentState);
068                    t++;
069                    return currentState;
070            }
071            
072            /**
073             * Performs n updates on the markov chain.
074             * 
075             * @return State of the markov chain at time t+n,
076             *                 given the current time is t.
077             */
078            public Object next(int n) {
079                    for(int i = 0; i < n; i++) {
080                            currentState = update(currentState);
081                            t++;
082                    }
083                    return currentState;
084            }
085    }