private void computeStep( final HiddenMarkovModel hmm, final MLDataPair o, final int t, final int j) { double minDelta = Double.MAX_VALUE; int min_psy = 0; for (int i = 0; i < hmm.getStateCount(); i++) { final double thisDelta = this.delta[t - 1][i] - Math.log(hmm.getTransitionProbability(i, j)); if (minDelta > thisDelta) { minDelta = thisDelta; min_psy = i; } } this.delta[t][j] = minDelta - Math.log(hmm.getStateDistribution(j).probability(o)); this.psy[t][j] = min_psy; }
public ViterbiCalculator(final MLDataSet oseq, final HiddenMarkovModel hmm) { if (oseq.size() < 1) { throw new IllegalArgumentException("Must not have empty sequence"); } this.delta = new double[oseq.size()][hmm.getStateCount()]; this.psy = new int[oseq.size()][hmm.getStateCount()]; this.stateSequence = new int[oseq.size()]; for (int i = 0; i < hmm.getStateCount(); i++) { this.delta[0][i] = -Math.log(hmm.getPi(i)) - Math.log(hmm.getStateDistribution(i).probability(oseq.get(0))); this.psy[0][i] = 0; } final Iterator<MLDataPair> oseqIterator = oseq.iterator(); if (oseqIterator.hasNext()) { oseqIterator.next(); } int t = 1; while (oseqIterator.hasNext()) { final MLDataPair observation = oseqIterator.next(); for (int i = 0; i < hmm.getStateCount(); i++) { computeStep(hmm, observation, t, i); } t++; } this.lnProbability = Double.MAX_VALUE; for (int i = 0; i < hmm.getStateCount(); i++) { final double thisProbability = this.delta[oseq.size() - 1][i]; if (this.lnProbability > thisProbability) { this.lnProbability = thisProbability; this.stateSequence[oseq.size() - 1] = i; } } this.lnProbability = -this.lnProbability; for (int t2 = oseq.size() - 2; t2 >= 0; t2--) { this.stateSequence[t2] = this.psy[t2 + 1][this.stateSequence[t2 + 1]]; } }