/*
* Copyright 1999-2002 Carnegie Mellon University.
* Portions Copyright 2002 Sun Microsystems, Inc.
* Portions Copyright 2002 Mitsubishi Electric Research Laboratories.
* All Rights Reserved. Use is subject to license terms.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*
*/
package edu.cmu.sphinx.linguist.acoustic.tiedstate;
import edu.cmu.sphinx.linguist.acoustic.HMM;
import edu.cmu.sphinx.linguist.acoustic.HMMPosition;
import edu.cmu.sphinx.linguist.acoustic.HMMState;
import edu.cmu.sphinx.linguist.acoustic.Unit;
import edu.cmu.sphinx.util.Utilities;
/**
* Represents a hidden-markov-model. An HMM consists of a unit (context dependent or independent), a transition matrix
* from state to state, and a sequence of senones associated with each state. This representation of an HMM is a
* specialized left-to-right markov model. No backward transitions are allowed.
*/
public class SenoneHMM implements HMM {
private final Unit unit;
private final Unit baseUnit;
private final SenoneSequence senoneSequence;
private final float[][] transitionMatrix;
private final HMMPosition position;
private static int objectCount;
private final HMMState[] hmmStates;
/**
* Constructs an HMM
*
* @param unit the unit for this HMM
* @param senoneSequence the sequence of senones for this HMM
* @param transitionMatrix the state transition matrix
* @param position the position associated with this HMM
*/
public SenoneHMM(Unit unit, SenoneSequence senoneSequence,
float[][] transitionMatrix, HMMPosition position) {
this.unit = unit;
this.senoneSequence = senoneSequence;
this.transitionMatrix = transitionMatrix;
this.position = position;
Utilities.objectTracker("HMM", objectCount++);
hmmStates = new HMMState[transitionMatrix.length];
for (int i = 0; i < hmmStates.length; i++) {
hmmStates[i] = new SenoneHMMState(this, i);
}
// baseUnit = Unit.getUnit(unit.getName());
baseUnit = unit.getBaseUnit();
}
/**
* Gets the unit associated with this HMM
*
* @return the unit associated with this HMM
*/
public Unit getUnit() {
return unit;
}
/**
* Gets the base unit associated with this HMM
*
* @return the unit associated with this HMM
*/
public Unit getBaseUnit() {
return baseUnit;
}
/**
* Retrieves the hmm state
*
* @param which the state of interest
*/
public HMMState getState(int which) {
return hmmStates[which];
}
/**
* Returns the order of the HMM
*
* @return the order of the HMM
*/
// [[[NOTE: this method is probably not explicitly needed since
// getSenoneSequence.getSenones().length will provide the same
// value, but this is certainly more convenient and easier to
// understand
public int getOrder() {
return getSenoneSequence().getSenones().length;
}
/**
* Returns the SenoneSequence associated with this HMM
*
* @return the sequence of senones associated with this HMM. The length of the sequence is N, where N is the order
* of the HMM. Note that senone sequences may be shared among HMMs.
*/
// [[ NOTE: the senone sequence may in fact be a sequence of
// composite senones
public SenoneSequence getSenoneSequence() {
return senoneSequence;
}
/**
* Determines if this HMM is a composite HMM
*
* @return true if this is a composite hmm
*/
public boolean isComposite() {
Senone[] senones = getSenoneSequence().getSenones();
for (Senone senone : senones) {
if (senone instanceof CompositeSenone) {
return true;
}
}
return false;
}
/**
* Returns the transition matrix that determines the state transition probabilities for the matrix. Each entry in
* the transition matrix defines the probability of transitioning from one state to the next. For example, the
* probability of transitioning from state 1 to state 2 can be determined by accessing transition matrix
* element[1][2].
*
* @return the transition matrix (in log domain) of size NxN where N is the order of the HMM
*/
public float[][] getTransitionMatrix() {
return transitionMatrix;
}
/**
* Returns the transition probability between two states.
*
* @param stateFrom the index of the state this transition goes from
* @param stateTo the index of the state this transition goes to
* @return the transition probability (in log domain)
*/
public float getTransitionProbability(int stateFrom, int stateTo) {
return transitionMatrix[stateFrom][stateTo];
}
/**
* Retrieves the position of this HMM. Possible
*
* @return the position for this HMM
*/
public HMMPosition getPosition() {
return position;
}
/**
* Determines if this HMM represents a filler unit. A filler unit is speech that is not meaningful such as a cough,
* 'um' , 'er', or silence.
*
* @return true if the HMM represents a filler unit
*/
public boolean isFiller() {
return unit.isFiller();
}
/**
* Determines if this HMM corresponds to a context dependent unit
*
* @return true if the HMM is context dependent
*/
public boolean isContextDependent() {
return unit.isContextDependent();
}
/**
* Gets the initial states (with probabilities) for this HMM
*
* @return the set of arcs that transition to the initial states for this HMM
*/
public HMMState getInitialState() {
return getState(0);
}
/**
* Returns the string representation of this object
*
* @return the string representation
*/
@Override
public String toString() {
String name = isComposite() ? "HMM@" : "HMM";
return name + '(' + unit + "):" + position;
}
@Override
public int hashCode() {
return getSenoneSequence().hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o instanceof SenoneHMM) {
SenoneHMM other = (SenoneHMM) o;
return getSenoneSequence().equals(other.getSenoneSequence());
}
return false;
}
}