matthiasm@8
|
1 function [p,q,D,sc] = dpfast(M,C,T,G)
|
matthiasm@8
|
2 % [p,q,D,sc] = dpfast(M,C,T,G)
|
matthiasm@8
|
3 % Use dynamic programming to find a min-cost path through matrix M.
|
matthiasm@8
|
4 % Return state sequence in p,q; full min cost matrix as D and
|
matthiasm@8
|
5 % local costs along best path in sc.
|
matthiasm@8
|
6 % This version gives the same results as dp.m, but uses dpcore.mex
|
matthiasm@8
|
7 % to run ~200x faster.
|
matthiasm@8
|
8 % C is a step matrix, with rows (i step, j step, cost factor)
|
matthiasm@8
|
9 % Default is [1 1 1.0;0 1 1.0;1 0 1.0];
|
matthiasm@8
|
10 % Another good one is [1 1 1;1 0 1;0 1 1;1 2 2;2 1 2]
|
matthiasm@8
|
11 % T selects traceback origin: 0 is to any edge; 1 is top right (default);
|
matthiasm@8
|
12 % T > 1 finds path to min of anti-diagonal T points away from top-right.
|
matthiasm@8
|
13 % Optional G defines length of 'gulleys' for T=0 mode; default 0.5
|
matthiasm@8
|
14 % (i.e. accept path to only 50% of edge nearest top-right)
|
matthiasm@8
|
15 % 2003-04-04,2005-04-04 dpwe@ee.columbia.edu $Header: /Users/dpwe/projects/dtw/RCS/dpfast.m,v 1.6 2008/03/14 14:40:50 dpwe Exp $
|
matthiasm@8
|
16
|
matthiasm@8
|
17 % Copyright (c) 2003 Dan Ellis <dpwe@ee.columbia.edu>
|
matthiasm@8
|
18 % released under GPL - see file COPYRIGHT
|
matthiasm@8
|
19
|
matthiasm@8
|
20 if nargin < 2
|
matthiasm@8
|
21 % Default step / cost matrix
|
matthiasm@8
|
22 C = [1 1 1.0;0 1 1.0;1 0 1.0];
|
matthiasm@8
|
23 end
|
matthiasm@8
|
24
|
matthiasm@8
|
25 if nargin < 3
|
matthiasm@8
|
26 % Default: path to top-right
|
matthiasm@8
|
27 T = 1;
|
matthiasm@8
|
28 end
|
matthiasm@8
|
29
|
matthiasm@8
|
30 if nargin < 4
|
matthiasm@8
|
31 % how big are gulleys?
|
matthiasm@8
|
32 G = 0.5; % half the extent
|
matthiasm@8
|
33 end
|
matthiasm@8
|
34
|
matthiasm@8
|
35 if sum(isnan(M(:)))>0
|
matthiasm@8
|
36 error('dpwe:dpfast:NAN','Error: Cost matrix includes NaNs');
|
matthiasm@8
|
37 end
|
matthiasm@8
|
38
|
matthiasm@8
|
39 if min(M(:)) < 0
|
matthiasm@8
|
40 disp('Warning: cost matrix includes negative values; results may not be what you expect');
|
matthiasm@8
|
41 end
|
matthiasm@8
|
42
|
matthiasm@8
|
43 [r,c] = size(M);
|
matthiasm@8
|
44
|
matthiasm@8
|
45 % Core cumulative cost calculation coded as mex
|
matthiasm@8
|
46 [D,phi] = dpcore(M,C);
|
matthiasm@8
|
47
|
matthiasm@8
|
48 p = [];
|
matthiasm@8
|
49 q = [];
|
matthiasm@8
|
50
|
matthiasm@8
|
51 %% Traceback from top left?
|
matthiasm@8
|
52 %i = r;
|
matthiasm@8
|
53 %j = c;
|
matthiasm@8
|
54
|
matthiasm@8
|
55 if T == 0
|
matthiasm@8
|
56 % Traceback from lowest cost "to edge" (gulleys)
|
matthiasm@8
|
57 TE = D(r,:);
|
matthiasm@8
|
58 RE = D(:,c);
|
matthiasm@8
|
59 % eliminate points not in gulleys
|
matthiasm@8
|
60 TE(1:round((1-G)*c)) = max(max(D));
|
matthiasm@8
|
61 RE(1:round((1-G)*r)) = max(max(D));
|
matthiasm@8
|
62 if (min(TE) < min(RE))
|
matthiasm@8
|
63 i = r;
|
matthiasm@8
|
64 j = max(find(TE==min(TE)));
|
matthiasm@8
|
65 else
|
matthiasm@8
|
66 i = max(find(RE==min(RE)));
|
matthiasm@8
|
67 j = c;
|
matthiasm@8
|
68 end
|
matthiasm@8
|
69 else
|
matthiasm@8
|
70 % Traceback from min of antidiagonal
|
matthiasm@8
|
71 %stepback = floor(0.1*c);
|
matthiasm@8
|
72 stepback = T;
|
matthiasm@8
|
73 slice = diag(fliplr(D),-(r-stepback));
|
matthiasm@8
|
74 [mm,ii] = min(slice);
|
matthiasm@8
|
75 i = r - stepback + ii;
|
matthiasm@8
|
76 j = c + 1 - ii;
|
matthiasm@8
|
77 end
|
matthiasm@8
|
78
|
matthiasm@8
|
79 p=i;
|
matthiasm@8
|
80 q=j;
|
matthiasm@8
|
81
|
matthiasm@8
|
82 sc = M(p,q);
|
matthiasm@8
|
83
|
matthiasm@8
|
84 while i > 1 & j > 1
|
matthiasm@8
|
85 % disp(['i=',num2str(i),' j=',num2str(j)]);
|
matthiasm@8
|
86 tb = phi(i,j);
|
matthiasm@8
|
87 i = i - C(tb,1);
|
matthiasm@8
|
88 j = j - C(tb,2);
|
matthiasm@8
|
89 p = [i,p];
|
matthiasm@8
|
90 q = [j,q];
|
matthiasm@8
|
91 sc = [M(i,j),sc];
|
matthiasm@8
|
92 end
|