throw new UnknownError("Cloning HmmModels broke. Check for programming errors, changed APIs etc.");
}
// allocate space for baum-welch factors
int hiddenCount = initialModel.getNrOfHiddenStates();
int visibleCount = observedSequence.length;
Matrix alpha = new DenseMatrix(visibleCount, hiddenCount);
Matrix beta = new DenseMatrix(visibleCount, hiddenCount);
// now run the baum Welch training iteration
for (int it = 0; it < maxIterations; ++it) {
// fetch emission and transition matrix of current iteration
Vector initialProbabilities = iteration.getInitialProbabilities();
Matrix emissionMatrix = iteration.getEmissionMatrix();
Matrix transitionMatrix = iteration.getTransitionMatrix();
// compute forward and backward factors
HmmAlgorithms.forwardAlgorithm(alpha, iteration, observedSequence, scaled);
HmmAlgorithms.backwardAlgorithm(beta, iteration, observedSequence, scaled);
if (scaled) {
logScaledBaumWelch(observedSequence, iteration, alpha, beta);
} else {
unscaledBaumWelch(observedSequence, iteration, alpha, beta);
}
// normalize transition/emission probabilities
// and normalize the probabilities
double isum = 0;
for (int j = 0; j < iteration.getNrOfHiddenStates(); ++j) {
double sum = 0;
// normalize the rows of the transition matrix
for (int k = 0; k < iteration.getNrOfHiddenStates(); ++k) {
sum += transitionMatrix.getQuick(j, k);
}
for (int k = 0; k < iteration.getNrOfHiddenStates(); ++k) {
transitionMatrix
.setQuick(j, k, transitionMatrix.getQuick(j, k) / sum);
}
// normalize the rows of the emission matrix
sum = 0;
for (int k = 0; k < iteration.getNrOfOutputStates(); ++k) {
sum += emissionMatrix.getQuick(j, k);