package dist.hmm;
import dist.Distribution;
import shared.Copyable;
import shared.DataSet;
import shared.Instance;
/**
* The abstract base class representing a hidden markov model
* @author Andrew Guillory gtg008g@mail.gatech.edu
* @version 1.0
*/
public class ModularHiddenMarkovModel implements HiddenMarkovModel, Copyable {
/**
* The array of transition probability functions
*/
private StateDistribution[] transitionDistributions;
/**
* The array of output probability functions
*/
private Distribution[] outputDistributions;
/**
* The initial state probability distribution
*/
private StateDistribution initialStateDistribution;
/**
* Create a new hidden markov model of the given size
* @param stateCount the number of states
*/
public ModularHiddenMarkovModel(int stateCount) {
initialStateDistribution = null;
transitionDistributions = new StateDistribution[stateCount];
outputDistributions = new Distribution[stateCount];
}
/** Default constructor */
public ModularHiddenMarkovModel() { }
/**
* Get the state count for this model
* @return the number of states in the model
*/
public int getStateCount() {
return transitionDistributions.length;
}
/**
* Set the output functions
* @param functions the output functions
*/
public void setOutputDistributions(Distribution[] functions) {
outputDistributions = functions;
}
/**
* Get the output distributions
* @return the distributions;
*/
public Distribution[] getOutputDistributions() {
return outputDistributions;
}
/**
* Set the transition functions
* @param functions the transition functions
*/
public void setTransitionDistributions(StateDistribution[] functions) {
transitionDistributions = functions;
}
/**
* Get the transition distributions
* @return the distributions
*/
public StateDistribution[] getTransitionDistributions() {
return transitionDistributions;
}
/**
* Set the intial state distribution
* @param distribution the distribution
*/
public void setInitialStateDistribution(StateDistribution distribution) {
initialStateDistribution = distribution;
}
/**
* Get the initial state distribution
* @return the initial state distribution
*/
public StateDistribution getInitialStateDistribution() {
return initialStateDistribution;
}
/**
* Get the initial state probability
* @param i the initial state
* @param o the initial observation
* @return the probability
*/
public double initialStateProbability(int i, Instance o) {
return initialStateDistribution.p(i, o);
}
/**
* Get the probability of transitioning from state i to state j,
* with observation o
* @param i the first state
* @param j the second state
* @param o the observation at state i
* @return the probability
*/
public double transitionProbability(int i, int j, Instance o) {
return transitionDistributions[i].p(j, o);
}
/**
* Get the probability of observing o in state i
* @param i the current state
* @param o the observation
* @return the probability
*/
public double observationProbability(int i, Instance o) {
return outputDistributions[i].p(o);
}
/**
* @see dist.hmm.HiddenMarkovModel#sampleState(int, shared.Instance)
*/
public int sampleState(int i, Instance o) {
return transitionDistributions[i].generateRandomState(o);
}
/**
* @see dist.hmm.HiddenMarkovModel#sampleInitialState(shared.Instance)
*/
public int sampleInitialState(Instance o) {
return initialStateDistribution.generateRandomState(o);
}
/**
* @see dist.hmm.HiddenMarkovModel#sampleObservation(int, shared.Instance)
*/
public Instance sampleObservation(int i, Instance o) {
return outputDistributions[i].sample(o);
}
/**
* Match the outputs in state i to the given expectaions for the given
* sequence
* @param i the state
* @param expectations the expectations
* @param sequence the sequence
*/
public void estimateOutputDistribution(int i, DataSet sequence) {
outputDistributions[i].estimate(sequence);
}
/**
* Match the initial state distribution to the given expectations and observations
* @param expectations [k][i] is the expected times in state i initially
* for observation sequence k
* @param observations the observation sequence
*/
public void estimateIntialStateDistribution(double[][] expectations, DataSet observations) {
initialStateDistribution.estimate(expectations, observations);
}
/**
* Match the transitions in state i to the given expectations for the given
* sequence
* @param i the start state
* @param expectations the expected transitions [t][j] for time t to state j
* @param sequence the observation sequence
*/
public void estimateTransitionDistribution(int i, double[][] expectations, DataSet sequence) {
transitionDistributions[i].estimate(expectations, sequence);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
String result = "";
result += "Transition Distributions\n";
for (int i = 0; i < getStateCount(); i++) {
result += transitionDistributions[i] + "\n";
}
result += "Output Distributions\n";
for (int i = 0; i < getStateCount(); i++) {
result += outputDistributions[i] + "\n";
}
result += "Initial Distribution\n"
+ initialStateDistribution + "\n";
return result;
}
/**
* @see shared.Copyable#copy()
*/
public Copyable copy() {
ModularHiddenMarkovModel copy = new ModularHiddenMarkovModel();
copy.setInitialStateDistribution((StateDistribution) ((Copyable) initialStateDistribution).copy());
StateDistribution[] transitionCopies = new StateDistribution[transitionDistributions.length];
for (int i = 0; i < transitionCopies.length; i++) {
transitionCopies[i] = (StateDistribution) ((Copyable) transitionDistributions[i]).copy();
}
copy.setTransitionDistributions(transitionCopies);
Distribution[] outputCopies = new Distribution[outputDistributions.length];
for (int i = 0; i < outputCopies.length; i++) {
outputCopies[i] = (Distribution) ((Copyable) outputDistributions[i]).copy();
}
copy.setOutputDistributions(outputCopies);
return copy;
}
}