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 }
|