matthiasm@0: function d = flstViterbiUpdate(obsLik, d, isFinal) matthiasm@0: matthiasm@0: if nargin < 3 matthiasm@0: isFinal = 0; matthiasm@0: end matthiasm@0: matthiasm@0: % d.psi(:,1:(d.memory-1)) = d.psi(:,2:d.memory); matthiasm@0: d.psi = circshift(d.psi, -1, 2); matthiasm@0: % d.scale(1:(d.memory-1)) = d.scale(2:d.memory); matthiasm@0: d.scale = circshift(d.scale, -1, 2); matthiasm@0: matthiasm@0: if d.updateCount == 0 matthiasm@0: % initialise first frame matthiasm@0: d.oldDelta = d.init .* obsLik; matthiasm@0: deltaSum = sum(d.oldDelta); matthiasm@0: d.oldDelta = d.oldDelta / deltaSum; matthiasm@0: d.scale(d.memory) = 1.0/deltaSum; matthiasm@0: else matthiasm@0: tempPsi = ones(d.nState, 1); matthiasm@0: matthiasm@0: % calculate best previous state for every current state matthiasm@0: % this would be the "sparse" loop in C++ matthiasm@0: matthiasm@0: % for jState = 1:d.nState matthiasm@0: % temp = d.oldDelta(d.from) .* d.prob'; matthiasm@0: % [d.delta(jState), tempPsi(jState)] = max(temp(d.to==jState)); matthiasm@0: % end matthiasm@0: matthiasm@0: for iTrans = 1:d.nTrans matthiasm@0: transProb = d.prob(iTrans); matthiasm@0: fromState = d.from(iTrans); matthiasm@0: toState = d.to(iTrans); matthiasm@0: currentValue = d.oldDelta(fromState) * transProb; matthiasm@0: if (currentValue > d.delta(toState)) matthiasm@0: d.delta(toState) = currentValue; % will be multiplied by the right obs later! matthiasm@0: tempPsi(toState) = fromState; matthiasm@0: end matthiasm@0: end matthiasm@1: % d.delta = d.delta .* obsLik; matthiasm@1: d.delta = d.delta .* obsLik + eps; matthiasm@0: deltaSum = sum(d.delta); matthiasm@0: matthiasm@0: if deltaSum > 0 matthiasm@0: d.oldDelta = d.delta / deltaSum; % normalise (scale) matthiasm@0: d.scale(d.memory) = 1.0/deltaSum; matthiasm@0: d.delta = zeros(size(d.delta)); matthiasm@0: else matthiasm@0: warning('Viterbi has been fed some zero probabilities (update %d),\nat least they become zero in combination with the model.', d.updateCount); matthiasm@0: d.oldDelta = ones(d.nState,1)/d.nState; matthiasm@0: d.scale(d.memory) = 1.0; matthiasm@0: d.delta = zeros(size(d.delta)); matthiasm@0: end matthiasm@0: d.psi(:,d.memory) = tempPsi; matthiasm@0: end matthiasm@0: d.updateCount = d.updateCount + 1; matthiasm@0: matthiasm@0: if isFinal matthiasm@0: temp = flstDecode(d); matthiasm@0: d.path = [d.path, temp]; matthiasm@0: elseif d.updateCount > (d.memory-1) matthiasm@0: temp = flstDecode(d); matthiasm@0: d.path = [d.path, temp(1)]; matthiasm@0: end