return false;
}
@Override
public void iteration() {
HiddenMarkovModel nhmm;
try {
nhmm = this.method.clone();
} catch (final CloneNotSupportedException e) {
throw new InternalError();
}
final double allGamma[][][] = new double[this.training
.getSequenceCount()][][];
final double aijNum[][] = new double[this.method.getStateCount()][this.method
.getStateCount()];
final double aijDen[] = new double[this.method.getStateCount()];
Arrays.fill(aijDen, 0.0);
for (int i = 0; i < this.method.getStateCount(); i++) {
Arrays.fill(aijNum[i], 0.);
}
int g = 0;
for (final MLDataSet obsSeq : this.training.getSequences()) {
final ForwardBackwardCalculator fbc = generateForwardBackwardCalculator(
obsSeq, this.method);
final double xi[][][] = estimateXi(obsSeq, fbc, this.method);
final double gamma[][] = allGamma[g++] = estimateGamma(xi, fbc);
for (int i = 0; i < this.method.getStateCount(); i++) {
for (int t = 0; t < (obsSeq.size() - 1); t++) {
aijDen[i] += gamma[t][i];
for (int j = 0; j < this.method.getStateCount(); j++) {
aijNum[i][j] += xi[t][i][j];
}
}
}
}
for (int i = 0; i < this.method.getStateCount(); i++) {
if (aijDen[i] == 0.0) {
for (int j = 0; j < this.method.getStateCount(); j++) {
nhmm.setTransitionProbability(i, j,
this.method.getTransitionProbability(i, j));
}
} else {
for (int j = 0; j < this.method.getStateCount(); j++) {
nhmm.setTransitionProbability(i, j, aijNum[i][j]
/ aijDen[i]);
}
}
}
/* compute pi */
for (int i = 0; i < this.method.getStateCount(); i++) {
nhmm.setPi(i, 0.);
}
for (int o = 0; o < this.training.getSequenceCount(); o++) {
for (int i = 0; i < this.method.getStateCount(); i++) {
nhmm.setPi(
i,
nhmm.getPi(i)
+ (allGamma[o][0][i] / this.training
.getSequenceCount()));
}
}
/* compute pdfs */
for (int i = 0; i < this.method.getStateCount(); i++) {
final double[] weights = new double[this.training.size()];
double sum = 0.;
int j = 0;
int o = 0;
for (final MLDataSet obsSeq : this.training.getSequences()) {
for (int t = 0; t < obsSeq.size(); t++, j++) {
sum += weights[j] = allGamma[o][t][i];
}
o++;
}
for (j--; j >= 0; j--) {
weights[j] /= sum;
}
final StateDistribution opdf = nhmm.getStateDistribution(i);
opdf.fit(this.training, weights);
}
this.method = nhmm;
}