comparison core/magnatagatune/DistMeasureMahal.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 % ---
2 % The DistMeasureMahal class states a wrapper for
3 % special Mahalanobis similarity distance, and is compatible with the
4 % DistMeasure class
5 % ---
6 classdef DistMeasureMahal < handle
7
8 properties (SetAccess = private)
9
10 mahalW;
11
12 featX;
13
14 ids;
15 ret_ids;
16
17 % special delta parameters
18 deltafun;
19 deltafun_params;
20 end
21
22 methods
23
24 % ---
25 % constructor
26 % ---
27 function m = DistMeasureMahal(clips, mahalW, featX, deltafun, deltafun_params)
28
29 if nargin < 4 && (size(featX, 2) ~= numel(clips) || size(featX, 1) ~= length(mahalW))
30 error 'wrong input format'
31 end
32
33 % fill index and generate matrix;
34 m.ids = [clips.id];
35
36 % reverse index
37 m.ret_ids = sparse(numel(m.ids),1);
38 m.ret_ids(m.ids) = 1:numel(m.ids);
39
40 % ---
41 % save mahal Matrix and lazy-copy features
42 % ---
43 if size(mahalW, 1) ~= size(mahalW, 2)
44
45 m.mahalW = diag(mahalW);
46 else
47
48 m.mahalW = mahalW;
49 end
50
51 m.featX = featX;
52
53 % ---
54 % special deltas
55 % ---
56 if nargin > 3
57 m.deltafun = deltafun;
58 m.deltafun_params = deltafun_params;
59 else
60 m.deltafun = [];
61 end
62 end
63
64
65 % ---
66 % this compability function returns the
67 % mahalanobis similarity of two clip indices
68 % ---
69 function out = mat(m, idxa, idxb)
70
71 if nargin == 1
72 idxa = 1:numel(m.ids);
73 idxb = 1:numel(m.ids);
74 end
75
76 % ---
77 % account for different delta functions
78 % ---
79 if ~isempty(m.deltafun)
80 out = zeros(numel(idxa),numel(idxb));
81 for i=1:numel(idxa)
82 for j=1:numel(idxb)
83
84 % calculate new distance
85 tmp = m.deltafun(m.featX(:,idxa), m.featX(:,idxb),m.deltafun_params{:});
86 out(i,j) = tmp' * m.mahalW * tmp;
87 end
88 end
89 else
90 % Standard Mahaldist is much faster to calculate
91 out = sqdist( m.featX(:,idxa), m.featX(:,idxb), m.mahalW);
92 end
93 end
94
95 % ---
96 % returns the distance for the two input clips
97 % ---
98 function out = distance(m, clipa, clipb)
99 posa = m.get_clip_pos(clipa);
100 posb = m.get_clip_pos(clipb);
101
102 out = m.mat(posa, posb);
103 end
104
105 % ---
106 % returns a list of n (default = 10) clips most
107 % similar to the input
108 % ---
109 function [clips, dist] = get_nearest(m, clip, n)
110 % list = get_nearest(m, clip, n)
111 %
112 % returns a list of n (default = 10) clips most
113 % similar to the input
114
115 % default number of results
116 if nargin == 2
117
118 n = 10;
119 end
120
121 % return all clips in case n = 0
122 if n == 0; n = numel(m.ids); end
123
124 % get clip positions
125 pos = m.get_clip_pos(clip);
126
127 % sort according to distance
128 [sc, idx] = sort( m.mat(pos, 1:numel(m.ids)), 'ascend');
129
130 % we only output relevant data
131 idx = idx(sc < inf);
132
133 if numel(idx) > 0
134 % create clips form best ids
135 clips = MTTClip( m.ids( idx(1:min(n, end))));
136 dist = m.mat(pos, idx(1:min(n, end)));
137
138 else
139 clips = [];
140 dist = [];
141 end
142 end
143
144
145
146 function [clips, dist] = present_nearest(m, clip, n)
147 % plays and shows the n best hits for a given clip
148
149 % default number of results
150 if nargin == 2
151
152 n = 3;
153 end
154
155 % get best list
156 [clips, dist] = get_nearest(m, clip, n);
157
158 clip.audio_features_basicsm.visualise();
159 for i = 1:numel(clips)
160 fprintf('\n\n\n- Rank %d, distance: %1.4f \n\n',i, dist(i));
161
162 clips(i).audio_features_basicsm.visualise();
163 h = gcf();
164 t = clips(i).play(20);
165 pause(t);
166 close(h);
167 end
168 end
169
170 function a = visualise(m)
171
172 figure;
173
174 % plot data
175
176 imagesc(m.mat);
177
178 a = gca;
179 set(a,'YTick',[1:numel(m.ids)], 'YTickLabel',m.ids);
180 set(a,'XTick',[1:numel(m.ids)], 'XTickLabel', m.ids);
181
182 axis xy;
183 colormap(hot);
184 end
185
186 % end methods
187 end
188
189 % ---
190 % private methods
191 % ---
192 methods(Access = private)
193
194 function out = get_clip_pos(m, clip)
195 % returns position in mat for given clip
196
197 out = m.ret_ids(clip.id);
198 end
199
200 end
201
202 end