To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / _beattracker / viterbi_path.m
History | View | Annotate | Download (1.52 KB)
| 1 |
function [path,p] = viterbi_path(prior, transmat, obslik) |
|---|---|
| 2 |
% VITERBI Find the most-probable (Viterbi) path through the HMM state trellis. |
| 3 |
% path = viterbi(prior, transmat, obslik) |
| 4 |
% |
| 5 |
% Inputs: |
| 6 |
% prior(i) = Pr(Q(1) = i) |
| 7 |
% transmat(i,j) = Pr(Q(t+1)=j | Q(t)=i) |
| 8 |
% obslik(i,t) = Pr(y(t) | Q(t)=i) |
| 9 |
% |
| 10 |
% Outputs: |
| 11 |
% path(t) = q(t), where q1 ... qT is the argmax of the above expression. |
| 12 |
|
| 13 |
|
| 14 |
% delta(j,t) = prob. of the best sequence of length t-1 and then going to state j, and O(1:t) |
| 15 |
% psi(j,t) = the best predecessor state, given that we ended up in state j at t |
| 16 |
|
| 17 |
scaled = 1; |
| 18 |
|
| 19 |
T = size(obslik, 2); |
| 20 |
prior = prior(:); |
| 21 |
Q = length(prior); |
| 22 |
|
| 23 |
delta = zeros(Q,T); |
| 24 |
psi = zeros(Q,T); |
| 25 |
path = zeros(1,T); |
| 26 |
scale = ones(1,T); |
| 27 |
|
| 28 |
|
| 29 |
t=1; |
| 30 |
delta(:,t) = prior .* obslik(:,t); |
| 31 |
if scaled |
| 32 |
[delta(:,t), n] = normalise(delta(:,t)); |
| 33 |
scale(t) = 1/n; |
| 34 |
end |
| 35 |
psi(:,t) = 0; % arbitrary value, since there is no predecessor to t=1 |
| 36 |
for t=2:T |
| 37 |
for j=1:Q |
| 38 |
[delta(j,t), psi(j,t)] = max(delta(:,t-1) .* transmat(:,j)); |
| 39 |
delta(j,t) = delta(j,t) * obslik(j,t); |
| 40 |
end |
| 41 |
if scaled |
| 42 |
[delta(:,t), n] = normalise(delta(:,t)); |
| 43 |
scale(t) = 1/n; |
| 44 |
end |
| 45 |
end |
| 46 |
[p(T), path(T)] = max(delta(:,T)); |
| 47 |
for t=T-1:-1:1 |
| 48 |
path(t) = psi(path(t+1),t+1); |
| 49 |
end |
| 50 |
|
| 51 |
% keyboard |
| 52 |
|
| 53 |
% If scaled==0, p = prob_path(best_path) |
| 54 |
% If scaled==1, p = Pr(replace sum with max and proceed as in the scaled forwards algo) |
| 55 |
% Both are different from p(data) as computed using the sum-product (forwards) algorithm |
| 56 |
|
| 57 |
if 0 |
| 58 |
if scaled |
| 59 |
loglik = -sum(log(scale)); |
| 60 |
%loglik = prob_path(prior, transmat, obslik, path); |
| 61 |
else |
| 62 |
loglik = log(p); |
| 63 |
end |
| 64 |
end |