public void Iteration() { HiddenMarkovModel nhmm; nhmm = _method.Clone(); var allGamma = new double[_training.SequenceCount][][]; double[][] aijNum = EngineArray.AllocateDouble2D(_method.StateCount, _method.StateCount); var aijDen = new double[_method.StateCount]; EngineArray.Fill(aijDen, 0.0); for (int i = 0; i < _method.StateCount; i++) { EngineArray.Fill(aijNum[i], 0.0); } int g = 0; foreach (IMLDataSet obsSeq in _training.Sequences) { ForwardBackwardCalculator fbc = GenerateForwardBackwardCalculator( obsSeq, _method); double[][][] xi = EstimateXi(obsSeq, fbc, _method); double[][] gamma = allGamma[g++] = EstimateGamma(xi, fbc); for (int i = 0; i < _method.StateCount; i++) { for (int t = 0; t < (obsSeq.Count - 1); t++) { aijDen[i] += gamma[t][i]; for (int j = 0; j < _method.StateCount; j++) { aijNum[i][j] += xi[t][i][j]; } } } } for (int i = 0; i < _method.StateCount; i++) { if (aijDen[i] == 0.0) { for (int j = 0; j < _method.StateCount; j++) { nhmm.TransitionProbability[i][j] = _method.TransitionProbability[i][j]; } } else { for (int j = 0; j < _method.StateCount; j++) { nhmm.TransitionProbability[i][j] = aijNum[i][j] / aijDen[i]; } } } /* compute pi */ for (int i = 0; i < _method.StateCount; i++) { nhmm.Pi[i] = 0.0; } for (int o = 0; o < _training.SequenceCount; o++) { for (int i = 0; i < _method.StateCount; i++) { nhmm.Pi[i] += (allGamma[o][0][i] / _training .SequenceCount); } } /* compute pdfs */ for (int i = 0; i < _method.StateCount; i++) { var weights = new double[_training.Count]; double sum = 0.0; int j = 0; int o = 0; foreach (IMLDataSet obsSeq in _training.Sequences) { for (int t = 0; t < obsSeq.Count; t++, j++) { sum += weights[j] = allGamma[o][t][i]; } o++; } for (j--; j >= 0; j--) { weights[j] /= sum; } IStateDistribution opdf = nhmm.StateDistributions[i]; opdf.Fit(_training, weights); } _method = nhmm; Iterations++; }