annotate SparseHMM.cpp @ 0:99bac62ee2da

added PYIN sources, should be compileable
author matthiasm
date Wed, 27 Nov 2013 11:59:49 +0000
parents
children 5945b8905d1f
rev   line source
matthiasm@0 1 #include "SparseHMM.h"
matthiasm@0 2 #include <vector>
matthiasm@0 3 #include <cstdio>
matthiasm@0 4 #include <iostream>
matthiasm@0 5
matthiasm@0 6 using std::vector;
matthiasm@0 7 using std::pair;
matthiasm@0 8
matthiasm@0 9 const vector<double>
matthiasm@0 10 SparseHMM::calculateObsProb(const vector<pair<double, double> > data)
matthiasm@0 11 {
matthiasm@0 12 // dummy (virtual?) implementation to be overloaded
matthiasm@0 13 return(vector<double>());
matthiasm@0 14 }
matthiasm@0 15
matthiasm@0 16 const std::vector<int>
matthiasm@0 17 SparseHMM::decodeViterbi(std::vector<vector<double> > obsProb,
matthiasm@0 18 vector<double> *scale)
matthiasm@0 19 {
matthiasm@0 20 size_t nState = init.size();
matthiasm@0 21 size_t nFrame = obsProb.size();
matthiasm@0 22
matthiasm@0 23 // check for consistency
matthiasm@0 24 size_t nTrans = transProb.size();
matthiasm@0 25
matthiasm@0 26 // declaring variables
matthiasm@0 27 std::vector<double> delta = std::vector<double>(nState);
matthiasm@0 28 std::vector<double> oldDelta = std::vector<double>(nState);
matthiasm@0 29 vector<vector<int> > psi; // "matrix" of remembered indices of the best transitions
matthiasm@0 30 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@0 31
matthiasm@0 32 double deltasum = 0;
matthiasm@0 33
matthiasm@0 34 // initialise first frame
matthiasm@0 35 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 36 {
matthiasm@0 37 oldDelta[iState] = init[iState] * obsProb[0][iState];
matthiasm@0 38 // std::cerr << iState << " ----- " << init[iState] << std::endl;
matthiasm@0 39 deltasum += oldDelta[iState];
matthiasm@0 40 }
matthiasm@0 41
matthiasm@0 42 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 43 {
matthiasm@0 44 oldDelta[iState] /= deltasum; // normalise (scale)
matthiasm@0 45 // std::cerr << oldDelta[iState] << std::endl;
matthiasm@0 46 }
matthiasm@0 47
matthiasm@0 48 scale->push_back(1.0/deltasum);
matthiasm@0 49 psi.push_back(vector<int>(nState,0));
matthiasm@0 50
matthiasm@0 51 // rest of forward step
matthiasm@0 52 for (size_t iFrame = 1; iFrame < nFrame; ++iFrame)
matthiasm@0 53 {
matthiasm@0 54 deltasum = 0;
matthiasm@0 55 psi.push_back(vector<int>(nState,0));
matthiasm@0 56
matthiasm@0 57 // calculate best previous state for every current state
matthiasm@0 58 size_t fromState;
matthiasm@0 59 size_t toState;
matthiasm@0 60 double currentTransProb;
matthiasm@0 61 double currentValue;
matthiasm@0 62
matthiasm@0 63 // this is the "sparse" loop
matthiasm@0 64 for (size_t iTrans = 0; iTrans < nTrans; ++iTrans)
matthiasm@0 65 {
matthiasm@0 66 fromState = from[iTrans];
matthiasm@0 67 toState = to[iTrans];
matthiasm@0 68 currentTransProb = transProb[iTrans];
matthiasm@0 69
matthiasm@0 70 currentValue = oldDelta[fromState] * currentTransProb;
matthiasm@0 71 if (currentValue > delta[toState])
matthiasm@0 72 {
matthiasm@0 73 delta[toState] = currentValue; // will be multiplied by the right obs later!
matthiasm@0 74 psi[iFrame][toState] = fromState;
matthiasm@0 75 }
matthiasm@0 76 }
matthiasm@0 77
matthiasm@0 78 for (size_t jState = 0; jState < nState; ++jState)
matthiasm@0 79 {
matthiasm@0 80 delta[jState] *= obsProb[iFrame][jState];
matthiasm@0 81 deltasum += delta[jState];
matthiasm@0 82 }
matthiasm@0 83
matthiasm@0 84 if (deltasum > 0)
matthiasm@0 85 {
matthiasm@0 86 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 87 {
matthiasm@0 88 oldDelta[iState] = delta[iState] / deltasum; // normalise (scale)
matthiasm@0 89 delta[iState] = 0;
matthiasm@0 90 }
matthiasm@0 91 scale->push_back(1.0/deltasum);
matthiasm@0 92 } else
matthiasm@0 93 {
matthiasm@0 94 std::cerr << "WARNING: Viterbi has been fed some zero probabilities, at least they become zero in combination with the model." << std::endl;
matthiasm@0 95 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 96 {
matthiasm@0 97 oldDelta[iState] = 1.0/nState;
matthiasm@0 98 delta[iState] = 0;
matthiasm@0 99 }
matthiasm@0 100 scale->push_back(1.0);
matthiasm@0 101 }
matthiasm@0 102 }
matthiasm@0 103
matthiasm@0 104 // initialise backward step
matthiasm@0 105 double bestValue = 0;
matthiasm@0 106 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 107 {
matthiasm@0 108 double currentValue = oldDelta[iState];
matthiasm@0 109 if (currentValue > bestValue)
matthiasm@0 110 {
matthiasm@0 111 bestValue = currentValue;
matthiasm@0 112 path[nFrame-1] = iState;
matthiasm@0 113 }
matthiasm@0 114 }
matthiasm@0 115
matthiasm@0 116 // rest of backward step
matthiasm@0 117 for (int iFrame = nFrame-2; iFrame != -1; --iFrame)
matthiasm@0 118 {
matthiasm@0 119 path[iFrame] = psi[iFrame+1][path[iFrame+1]];
matthiasm@0 120 }
matthiasm@0 121
matthiasm@0 122 for (size_t iState = 0; iState < nState; ++iState)
matthiasm@0 123 {
matthiasm@0 124 // std::cerr << psi[2][iState] << std::endl;
matthiasm@0 125 }
matthiasm@0 126
matthiasm@0 127 return path;
matthiasm@0 128 }