/*
* 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.frontend.Data;
import edu.cmu.sphinx.linguist.acoustic.HMM;
import edu.cmu.sphinx.linguist.acoustic.HMMState;
import edu.cmu.sphinx.linguist.acoustic.HMMStateArc;
import edu.cmu.sphinx.util.LogMath;
import edu.cmu.sphinx.util.Utilities;
import java.util.ArrayList;
import java.util.List;
/** Represents a single state in an HMM */
public class SenoneHMMState implements HMMState {
private final SenoneHMM hmm;
private final int state;
HMMStateArc[] arcs;
private final boolean isEmitting;
private Senone senone;
private final int hashCode;
private static int objectCount;
/**
* Constructs a SenoneHMMState
*
* @param hmm the HMM for this state
* @param which the index for this particular state
*/
SenoneHMMState(SenoneHMM hmm, int which) {
this.hmm = hmm;
this.state = which;
this.isEmitting = ((hmm.getTransitionMatrix().length - 1) != state);
if (isEmitting) {
SenoneSequence ss = hmm.getSenoneSequence();
senone = ss.getSenones()[state];
}
Utilities.objectTracker("HMMState", objectCount++);
hashCode = hmm.hashCode() + 37 * state;
}
/**
* Gets the HMM associated with this state
*
* @return the HMM
*/
public HMM getHMM() {
return hmm;
}
/**
* Gets the state
*
* @return the state
*/
public int getState() {
return state;
}
/**
* Gets the score for this HMM state
*
* @param feature the feature to be scored
* @return the acoustic score for this state.
*/
public float getScore(Data feature) {
return senone.getScore(feature);
}
/**
* Gets the scores for each mixture component in this HMM state
*
* @param feature the feature to be scored
* @return the acoustic scores for the components of this state.
*/
public float[] calculateComponentScore(Data feature) {
hmm.getSenoneSequence();
return senone.calculateComponentScore(feature);
}
/**
* Gets the senone for this HMM state
*
* @return the senone for this state.
*/
public Senone getSenone() {
return senone;
}
/**
* Determines if two HMMStates are equal
*
* @param other the state to compare this one to
* @return true if the states are equal
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof SenoneHMMState)) {
return false;
} else {
SenoneHMMState otherState = (SenoneHMMState) other;
return this.hmm == otherState.hmm &&
this.state == otherState.state;
}
}
/**
* Returns the hashcode for this state
*
* @return the hashcode
*/
@Override
public int hashCode() {
return hashCode;
}
/**
* Determines if this HMMState is an emitting state
*
* @return true if the state is an emitting state
*/
// TODO: We may have non-emitting entry states as well.
public final boolean isEmitting() {
return isEmitting;
}
/**
* Retrieves the state of successor states for this state
*
* @return the set of successor state arcs
*/
public HMMStateArc[] getSuccessors() {
if (arcs == null) {
List<HMMStateArc> list = new ArrayList<HMMStateArc>();
float[][] transitionMatrix = hmm.getTransitionMatrix();
for (int i = 0; i < transitionMatrix.length; i++) {
if (transitionMatrix[state][i] > LogMath.LOG_ZERO) {
HMMStateArc arc = new HMMStateArc(hmm.getState(i),
transitionMatrix[state][i]);
list.add(arc);
}
}
arcs = list.toArray(new HMMStateArc[list.size()]);
}
return arcs;
}
/**
* Determines if this state is an exit state of the HMM
*
* @return true if the state is an exit state
*/
public boolean isExitState() {
// return (hmm.getTransitionMatrix().length - 1) == state;
return !isEmitting;
}
/**
* returns a string representation of this object
*
* @return a string representation
*/
@Override
public String toString() {
return "HMMS " + hmm + " state " + state;
}
public MixtureComponent[] getMixtureComponents() {
return senone.getMixtureComponents();
}
public long getMixtureId() {
return senone.getID();
}
public float[] getLogMixtureWeights() {
return senone.getLogMixtureWeights();
}
}