forked from lin-limin/DTW
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdtw.m
147 lines (132 loc) · 4 KB
/
dtw.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
function [Dist,D,k,w,rw,tw]=dtw(r,t,pflag)
%
% [Dist,D,k,w,rw,tw]=dtw(r,t,pflag)
%
% Dynamic Time Warping Algorithm
% Dist is unnormalized distance between t and r
% D is the accumulated distance matrix
% k is the normalizing factor
% w is the optimal path
% t is the vector you are testing against
% r is the vector you are testing
% rw is the warped r vector
% tw is the warped t vector
% pflag plot flag: 1 (yes), 0(no)
%
% Version comments:
% rw, tw and pflag added by Pau Mic
r=zscore(r);
t=zscore(t);
[row,M]=size(r); if (row > M) M=row; r=r'; end;
[row,N]=size(t); if (row > N) N=row; t=t'; end;
d=sqrt((repmat(r',1,N)-repmat(t,M,1)).^2); %this makes clear the above instruction Thanks Pau Mic
d;
D=zeros(size(d));
D(1,1)=d(1,1);
for m=2:M
D(m,1)=d(m,1)+D(m-1,1);
end
for n=2:N
D(1,n)=d(1,n)+D(1,n-1);
end
for m=2:M
for n=2:N
D(m,n)=d(m,n)+min(D(m-1,n),min(D(m-1,n-1),D(m,n-1))); % this double MIn construction improves in 10-fold the Speed-up. Thanks Sven Mensing
end
end
Dist=D(M,N);
disp(Dist);
n=N;
m=M;
k=1;
w=[M N];
while ((n+m)~=2)
if (n-1)==0
m=m-1;
elseif (m-1)==0
n=n-1;
else
[values,number]=min([D(m-1,n),D(m,n-1),D(m-1,n-1)]);
switch number
case 1
m=m-1;
case 2
n=n-1;
case 3
m=m-1;
n=n-1;
end
end
k=k+1;
w=[m n; w]; % this replace the above sentence. Thanks Pau Mic
end
% warped waves
rw=r(w(:,1));
tw=t(w(:,2));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if pflag
% --- Accumulated distance matrix and optimal path
figure('Name','DTW - Accumulated distance matrix and optimal path', 'NumberTitle','off');
main1=subplot('position',[0.19 0.19 0.67 0.79]);
image(D);
cmap = contrast(D);
colormap(cmap); % 'copper' 'bone', 'gray' imagesc(D);
hold on;
x=w(:,1); y=w(:,2);
ind=find(x==1); x(ind)=1+0.2;
ind=find(x==M); x(ind)=M-0.2;
ind=find(y==1); y(ind)=1+0.2;
ind=find(y==N); y(ind)=N-0.2;
plot(y,x,'-w', 'LineWidth',1);
hold off;
axis([1 N 1 M]);
set(main1, 'FontSize',7, 'XTickLabel','', 'YTickLabel','');
colorb1=subplot('position',[0.88 0.19 0.05 0.79]);
nticks=8;
ticks=floor(1:(size(cmap,1)-1)/(nticks-1):size(cmap,1));
mx=max(max(D));
mn=min(min(D));
ticklabels=floor(mn:(mx-mn)/(nticks-1):mx);
colorbar(colorb1);
set(colorb1, 'FontSize',7, 'YTick',ticks, 'YTickLabel',ticklabels);
set(get(colorb1,'YLabel'), 'String','Distance', 'Rotation',-90, 'FontSize',7, 'VerticalAlignment','bottom');
left1=subplot('position',[0.07 0.19 0.10 0.79]);
plot(r,M:-1:1,'-b');
set(left1, 'YTick',mod(M,10):10:M, 'YTickLabel',10*rem(M,10):-10:0)
axis([min(r) 1.1*max(r) 1 M]);
set(left1, 'FontSize',7);
set(get(left1,'YLabel'), 'String','Samples', 'FontSize',7, 'Rotation',-90, 'VerticalAlignment','cap');
set(get(left1,'XLabel'), 'String','Amp', 'FontSize',6, 'VerticalAlignment','cap');
bottom1=subplot('position',[0.19 0.07 0.67 0.10]);
plot(t,'-r');
axis([1 N min(t) 1.1*max(t)]);
set(bottom1, 'FontSize',7, 'YAxisLocation','right');
set(get(bottom1,'XLabel'), 'String','Samples', 'FontSize',7, 'VerticalAlignment','middle');
set(get(bottom1,'YLabel'), 'String','Amp', 'Rotation',-90, 'FontSize',6, 'VerticalAlignment','bottom');
% --- Warped signals
figure('Name','DTW - warped signals', 'NumberTitle','off');
subplot(1,2,1);
set(gca, 'FontSize',7);
hold on;
plot(r,'-bx');
plot(t,':r.');
hold off;
axis([1 max(M,N) min(min(r),min(t)) 1.1*max(max(r),max(t))]);
grid;
legend('时间序列1','时间序列2');
title('原始时间序列');
xlabel('时间');
ylabel('幅度');
subplot(1,2,2);
set(gca, 'FontSize',7);
hold on;
plot(rw,'-bx');
plot(tw,':r.');
hold off;
axis([1 k min(min([rw; tw])) 1.1*max(max([rw; tw]))]);
grid;
legend('规整时间序列1','规整时间序列2');
title('规整时间序列');
xlabel('时间');
ylabel('幅度');
end