Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirdist.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirdist.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,122 @@ +function d = mirdist(x,y,dist) +% d = mirdist(x,y) evaluates the distance between x and y. +% x is the feature values corresponding to one audio file, and y is the +% values (for the same feature) corrdponding to one (or several) +% audio files. +% If x and y are not decomposed into frames, +% d = mirdist(x,y,f) specifies distance function. +% Default value: f = 'Cosine' +% If x and y are composed of clustered frames (using mircluster), the +% cluster signatures are compared using Earth Mover Distance. +% (Logan, Salomon, 2001) +% If x and y contains peaks, the vectors representing the peak +% distributions are compared using Euclidean distance. +% (used with mirnovelty in Jacobson, 2006) +% +% The Earth Mover Distance is based on the implementation by Yossi Rubner, +% wrapped for Matlab by Elias Pampalk. + +if not(isa(x,'mirdata')) + x = miraudio(x); +end +if not(isa(y,'mirdata')) + y = miraudio(y); +end + +clx = get(x,'Clusters'); +if isempty(clx{1}) + px = get(x,'PeakPos'); + if not(iscell(px)) || isempty(px{1}) || ... + not(iscell(px{1})) || isempty(px{1}{1}) || not(iscell(px{1}{1})) + if nargin < 3 + dist = 'Cosine'; + end + + d = get(x,'Data'); + dd = d{1}{1}; + if iscell(dd) + dd = dd{1}; + end + if size(dd,2)>1 + if size(dd,1)>1 + error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); + else + dd = dd'; + end + end + + e = get(y,'Data'); + dt = cell(1,length(e)); + for h = 1:length(e) + ee = e{h}{1}; + if iscell(ee) + ee = ee{1}; + end + if size(ee,2)>1 + if size(ee,1)>1 + error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); + else + ee = ee'; + end + end + if isempty(ee) + if isempty(dd) + dt{h}{1} = 0; + else + dt{h}{1} = Inf; + end + else + if length(dd)<length(ee) + dd(length(ee)) = 0; + %ee = ee(1:length(d)); + elseif length(ee)<length(dd) + ee(length(dd)) = 0; + %dd = dd(1:length(ee)); + end + if length(dd) == 1 + dt{h}{1} = abs(dd-ee); + elseif norm(dd) && norm(ee) + dt{h}{1} = pdist([dd(:)';ee(:)'],dist); + else + dt{h}{1} = NaN; + end + end + end + else + % Euclidean distance between vectors to compare data with peaks + % (used with mirnovelty in Jacobson, 2006). + sig = pi/4; + dx = get(x,'Data'); + nx = length(px{1}{1}{1}); + cx = mean(px{1}{1}{1}/length(dx{1}{1})); + dy = get(y,'Data'); + py = get(y,'PeakPos'); + dt = cell(1,length(py)); + for h = 1:length(py) + ny = length(py{h}{1}{1}); + cy = mean(py{h}{1}{1}/length(dy{h}{1})); + dt{h}{1} = sqrt((nx*cos(sig*cx)-ny*cos(sig*cy))^2 ... + +(nx*sin(sig*cx)-ny*sin(sig*cy))^2); + end + end +else + % Earth Mover's Distance to compare clustered data. + cly = get(y,'Clusters'); + dt = cell(1,length(cly)); + for h = 1:length(cly) + cost = zeros(length(clx{1}.weight),length(cly{h}.weight)); + for i = 1:length(clx{1}.weight) + for j = 1:length(cly{h}.weight) + covx = clx{1}.covar(:,i); + covy = cly{h}.covar(:,j); + mux = clx{1}.centr(:,i); + muy = cly{h}.centr(:,j); + cost(i,j) = sum(covx./covy + covy./covx + ... + (mux-muy).^2.*(1./covx + 1./covy) - 2); + end + end + dt{h}{1} = emd_wrapper(cost,clx{1}.weight,cly{h}.weight); + end +end +d = mirscalar(y,'Data',dt,'Title',[get(y,'Title'),' Distance'],... + 'Name',get(x,'Name'),'Name2',get(y,'Name')); \ No newline at end of file