annotate viterbi.cpp @ 64:12fd1d3ccd6e matthiasm-plugin 0.1

* Update URLs
author Chris Cannam
date Tue, 26 Oct 2010 11:33:53 +0200
parents b6cddb109482
children 19f3b33a19fb
rev   line source
matthiasm@43 1
matthiasm@43 2 #include "viterbi.h"
matthiasm@43 3 #include <iostream>
matthiasm@43 4
matthiasm@50 5 std::vector<int> ViterbiPath(std::vector<double> init, std::vector<vector<double> > trans, std::vector<vector<double> > obs, double *delta) {
matthiasm@43 6
matthiasm@43 7 int nState = init.size();
matthiasm@43 8 int nFrame = obs.size();
matthiasm@43 9 // cerr << nState << " " << nFrame << endl;
matthiasm@43 10
matthiasm@43 11 // check for consistency
matthiasm@43 12 if (trans[0].size() != nState || trans.size() != nState || obs[0].size() != nState) {
matthiasm@43 13 cerr << "ERROR: matrix sizes inconsistent." << endl;
matthiasm@43 14 }
matthiasm@50 15
matthiasm@50 16 for (int iState = 0; iState < nState; ++iState) delta[iState] = init[iState];
matthiasm@50 17 for (int iFrame = 1; iFrame < nFrame; ++iFrame) {
matthiasm@50 18 for (int iState = 0; iState < nState; ++iState) delta[iFrame*nState + iState];
matthiasm@50 19 }
matthiasm@43 20
matthiasm@50 21 // vector<vector<double> > delta; // "matrix" of conditional probabilities
matthiasm@43 22 vector<vector<int> > psi; // "matrix" of remembered indices of the best transitions
matthiasm@43 23 vector<int> path = vector<int>(nFrame, nState-1); // the final output path (current assignment arbitrary, makes sense only for Chordino, where nChord-1 is the "no chord" label)
matthiasm@43 24 vector<double> scale = vector<double>(nFrame, 0); // remembers by how much the vectors in delta are scaled.
matthiasm@43 25
matthiasm@43 26 double deltasum = 0;
matthiasm@43 27
matthiasm@43 28 /* initialise first frame */
matthiasm@50 29 // delta.push_back(init);
matthiasm@43 30 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 31 delta[iState] *= obs[0][iState];
matthiasm@50 32 deltasum += delta[iState];
matthiasm@43 33 }
matthiasm@50 34 for (int iState = 0; iState < nState; ++iState) delta[iState] /= deltasum; // normalise (scale)
matthiasm@43 35 scale.push_back(1.0/deltasum);
matthiasm@43 36 psi.push_back(vector<int>(nState,0));
matthiasm@43 37
matthiasm@43 38 /* rest of the forward step */
matthiasm@43 39 for (int iFrame = 1; iFrame < nFrame; ++iFrame) {
matthiasm@50 40 // delta.push_back(vector<double>(nState,0));
matthiasm@43 41 deltasum = 0;
matthiasm@43 42 psi.push_back(vector<int>(nState,0));
matthiasm@43 43 /* every state wants to know which previous state suits him best */
matthiasm@43 44 for (int jState = 0; jState < nState; ++jState) {
matthiasm@43 45 int bestState = nState - 1;
matthiasm@43 46 double bestValue = 0;
matthiasm@44 47 if (obs[iFrame][jState] > 0) {
matthiasm@44 48 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 49 double currentValue = delta[(iFrame-1) * nState + iState] * trans[iState][jState];
matthiasm@44 50 if (currentValue > bestValue) {
matthiasm@44 51 bestValue = currentValue;
matthiasm@44 52 bestState = iState;
matthiasm@44 53 }
matthiasm@43 54 }
matthiasm@43 55 }
matthiasm@43 56 // cerr << bestState <<" ::: " << bestValue << endl ;
matthiasm@50 57 delta[iFrame * nState + jState] = bestValue * obs[iFrame][jState];
matthiasm@50 58 deltasum += delta[iFrame * nState + jState];
matthiasm@43 59 psi[iFrame][jState] = bestState;
matthiasm@43 60 }
matthiasm@43 61 if (deltasum > 0) {
matthiasm@43 62 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 63 delta[iFrame * nState + iState] /= deltasum; // normalise (scale)
matthiasm@43 64 }
matthiasm@43 65 scale.push_back(1.0/deltasum);
matthiasm@43 66 } else {
matthiasm@43 67 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 68 delta[iFrame * nState + iState] = 1.0/nState;
matthiasm@43 69 }
matthiasm@43 70 scale.push_back(1.0);
matthiasm@43 71 }
matthiasm@43 72
matthiasm@43 73 }
matthiasm@43 74
matthiasm@43 75 /* initialise backward step */
matthiasm@43 76 int bestValue = 0;
matthiasm@43 77 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 78 double currentValue = delta[(nFrame-1) * nState + iState];
matthiasm@43 79 if (currentValue > path[nFrame-1]) {
matthiasm@43 80 bestValue = currentValue;
matthiasm@43 81 path[nFrame-1] = iState;
matthiasm@43 82 }
matthiasm@43 83 }
matthiasm@43 84
matthiasm@43 85 /* rest of backward step */
matthiasm@43 86 for (int iFrame = nFrame-2; iFrame > -1; --iFrame) {
matthiasm@43 87 path[iFrame] = psi[iFrame+1][path[iFrame+1]];
matthiasm@43 88 // cerr << path[iFrame] << endl;
matthiasm@43 89 }
matthiasm@43 90
matthiasm@43 91 return path;
matthiasm@43 92 }