annotate viterbi.cpp @ 164:3c731acad404

Fix some problems from the plugin tester: zero sample rate with fixed sample type outputs; mismatching parameter id ("spectralshape" in Chordino, "s" in NNLSBase -- changing this in Chordino won't break anything as it would never have worked under that name anyway); some NaN values
author Chris Cannam
date Fri, 04 Sep 2015 16:45:37 +0100
parents 21181297da99
children
rev   line source
matthiasm@43 1
matthiasm@43 2 #include "viterbi.h"
matthiasm@43 3 #include <iostream>
matthiasm@43 4
matthiasm@106 5 std::vector<int> ViterbiPath(std::vector<double> init, std::vector<vector<double> > trans, std::vector<vector<double> > obs, double *delta, vector<double> *scale) {
matthiasm@43 6
matthiasm@122 7 int nState = init.size();
matthiasm@122 8 int nFrame = obs.size();
matthiasm@43 9
matthiasm@43 10 // check for consistency
matthiasm@122 11 if ((int)trans[0].size() != nState || (int)trans.size() != nState || (int)obs[0].size() != nState) {
matthiasm@43 12 cerr << "ERROR: matrix sizes inconsistent." << endl;
matthiasm@43 13 }
mail@119 14
matthiasm@43 15 vector<vector<int> > psi; // "matrix" of remembered indices of the best transitions
matthiasm@43 16 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 17
matthiasm@43 18 double deltasum = 0;
matthiasm@43 19
matthiasm@43 20 /* initialise first frame */
matthiasm@122 21 for (int iState = 0; iState < nState; ++iState) {
matthiasm@94 22 delta[iState] = init[iState] * obs[0][iState];
Chris@164 23 // cerr << "init[" << iState << "] = " << init[iState] << ", obs[0][" << iState << "] = " << obs[0][iState] << endl;
matthiasm@50 24 deltasum += delta[iState];
matthiasm@43 25 }
matthiasm@122 26 for (int iState = 0; iState < nState; ++iState) delta[iState] /= deltasum; // normalise (scale)
matthiasm@106 27 scale->push_back(1.0/deltasum);
matthiasm@43 28 psi.push_back(vector<int>(nState,0));
Chris@164 29
Chris@164 30 // cerr << "nState = " << nState << ", deltasum = " << deltasum << endl;
matthiasm@43 31
matthiasm@43 32 /* rest of the forward step */
matthiasm@122 33 for (int iFrame = 1; iFrame < nFrame; ++iFrame) {
matthiasm@43 34 deltasum = 0;
matthiasm@43 35 psi.push_back(vector<int>(nState,0));
mail@119 36 /* every state wants to know which previous state suits it best */
matthiasm@122 37 for (int jState = 0; jState < nState; ++jState) {
matthiasm@43 38 int bestState = nState - 1;
matthiasm@43 39 double bestValue = 0;
matthiasm@44 40 if (obs[iFrame][jState] > 0) {
matthiasm@122 41 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 42 double currentValue = delta[(iFrame-1) * nState + iState] * trans[iState][jState];
matthiasm@44 43 if (currentValue > bestValue) {
matthiasm@44 44 bestValue = currentValue;
matthiasm@44 45 bestState = iState;
matthiasm@44 46 }
matthiasm@43 47 }
matthiasm@43 48 }
mail@119 49
matthiasm@50 50 delta[iFrame * nState + jState] = bestValue * obs[iFrame][jState];
matthiasm@50 51 deltasum += delta[iFrame * nState + jState];
matthiasm@43 52 psi[iFrame][jState] = bestState;
matthiasm@43 53 }
matthiasm@43 54 if (deltasum > 0) {
matthiasm@122 55 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 56 delta[iFrame * nState + iState] /= deltasum; // normalise (scale)
matthiasm@43 57 }
matthiasm@106 58 scale->push_back(1.0/deltasum);
matthiasm@43 59 } else {
matthiasm@122 60 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 61 delta[iFrame * nState + iState] = 1.0/nState;
matthiasm@43 62 }
matthiasm@106 63 scale->push_back(1.0);
matthiasm@43 64 }
matthiasm@43 65
matthiasm@43 66 }
matthiasm@43 67
matthiasm@43 68 /* initialise backward step */
matthiasm@109 69 double bestValue = 0;
matthiasm@122 70 for (int iState = 0; iState < nState; ++iState) {
matthiasm@50 71 double currentValue = delta[(nFrame-1) * nState + iState];
matthiasm@109 72 if (currentValue > bestValue) {
matthiasm@43 73 bestValue = currentValue;
matthiasm@43 74 path[nFrame-1] = iState;
matthiasm@43 75 }
matthiasm@43 76 }
matthiasm@43 77
matthiasm@43 78 /* rest of backward step */
matthiasm@43 79 for (int iFrame = nFrame-2; iFrame > -1; --iFrame) {
matthiasm@43 80 path[iFrame] = psi[iFrame+1][path[iFrame+1]];
matthiasm@43 81 }
matthiasm@43 82
matthiasm@43 83 return path;
matthiasm@43 84 }