annotate src/DistanceMetric.cpp @ 172:30d59e1e4232 structure

Minor tidy
author Chris Cannam
date Fri, 06 Feb 2015 18:09:18 +0000
parents d6c1556fadd0
children d1bc89794cd4
rev   line source
Chris@26 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@26 2
Chris@26 3 /*
Chris@26 4 Vamp feature extraction plugin using the MATCH audio alignment
Chris@26 5 algorithm.
Chris@26 6
Chris@26 7 Centre for Digital Music, Queen Mary, University of London.
Chris@26 8 This file copyright 2007 Simon Dixon, Chris Cannam and QMUL.
Chris@26 9
Chris@26 10 This program is free software; you can redistribute it and/or
Chris@26 11 modify it under the terms of the GNU General Public License as
Chris@26 12 published by the Free Software Foundation; either version 2 of the
Chris@26 13 License, or (at your option) any later version. See the file
Chris@26 14 COPYING included with this distribution for more information.
Chris@26 15 */
Chris@26 16
Chris@26 17 #include "DistanceMetric.h"
Chris@26 18
Chris@26 19 #include <cassert>
Chris@26 20 #include <cmath>
Chris@133 21 #include <iostream>
Chris@26 22
Chris@133 23 using namespace std;
Chris@26 24
Chris@140 25 //#define DEBUG_DISTANCE_METRIC 1
Chris@140 26
Chris@143 27 DistanceMetric::DistanceMetric(Parameters params) :
Chris@143 28 m_params(params)
Chris@140 29 {
Chris@140 30 #ifdef DEBUG_DISTANCE_METRIC
Chris@143 31 cerr << "*** DistanceMetric: norm = " << m_params.norm
Chris@143 32 << endl;
Chris@140 33 #endif
Chris@140 34 }
Chris@140 35
Chris@26 36 double
Chris@26 37 DistanceMetric::calcDistance(const vector<double> &f1,
Chris@26 38 const vector<double> &f2)
Chris@26 39 {
Chris@26 40 double d = 0;
Chris@26 41 double sum = 0;
Chris@156 42 double eps = 1e-16;
Chris@26 43
Chris@26 44 int featureSize = f1.size();
Chris@26 45 assert(int(f2.size()) == featureSize);
Chris@145 46
Chris@156 47 if (m_params.metric == Cosine) {
Chris@156 48
Chris@156 49 double num = 0, denom1 = 0, denom2 = 0;
Chris@156 50
Chris@156 51 for (int i = 0; i < featureSize; ++i) {
Chris@156 52 num += f1[i] * f2[i];
Chris@156 53 denom1 += f1[i] * f1[i];
Chris@156 54 denom2 += f2[i] * f2[i];
Chris@156 55 }
Chris@156 56
Chris@156 57 d = 1.0 - (num / (eps + sqrt(denom1 * denom2)));
Chris@156 58
Chris@156 59 if (m_params.noise == AddNoise) {
Chris@156 60 d += 1e-2;
Chris@156 61 }
Chris@156 62 if (d > 1.0) d = 1.0;
Chris@156 63
Chris@156 64 return d; // normalisation param ignored
Chris@157 65
Chris@156 66 }
Chris@156 67
Chris@157 68 if (m_params.metric == Manhattan) {
Chris@157 69 for (int i = 0; i < featureSize; i++) {
Chris@157 70 d += fabs(f1[i] - f2[i]);
Chris@157 71 sum += fabs(f1[i]) + fabs(f2[i]);
Chris@157 72 }
Chris@157 73 } else {
Chris@157 74 // Euclidean
Chris@157 75 for (int i = 0; i < featureSize; i++) {
Chris@157 76 d += (f1[i] - f2[i]) * (f1[i] - f2[i]);
Chris@157 77 sum += fabs(f1[i]) + fabs(f2[i]);
Chris@157 78 }
Chris@157 79 d = sqrt(d);
Chris@26 80 }
Chris@26 81
Chris@145 82 double noise = 1e-3 * featureSize;
Chris@150 83 if (m_params.noise == AddNoise) {
Chris@150 84 d += noise;
Chris@150 85 sum += noise;
Chris@150 86 }
Chris@145 87
Chris@143 88 if (sum == 0) {
Chris@26 89 return 0;
Chris@143 90 }
Chris@26 91
Chris@143 92 double distance = 0;
Chris@26 93
Chris@143 94 if (m_params.norm == NormaliseDistanceToSum) {
Chris@143 95
Chris@143 96 distance = d / sum; // 0 <= d/sum <= 2
Chris@143 97
Chris@143 98 } else if (m_params.norm == NormaliseDistanceToLogSum) {
Chris@143 99
Chris@143 100 // note if this were to be restored, it would have to use
Chris@143 101 // totalEnergies vector instead of f1[freqMapSize] which used to
Chris@143 102 // store the total energy:
Chris@143 103 // double weight = (5 + Math.log(f1[freqMapSize] + f2[freqMapSize]))/10.0;
Chris@143 104
Chris@143 105 double weight = (8 + log(sum)) / 10.0;
Chris@133 106
Chris@143 107 if (weight < 0) weight = 0;
Chris@143 108 else if (weight > 1) weight = 1;
Chris@26 109
Chris@143 110 distance = d / sum * weight;
Chris@143 111
Chris@143 112 } else {
Chris@143 113
Chris@143 114 distance = d;
Chris@143 115 }
Chris@143 116
Chris@143 117 return distance;
Chris@26 118 }
Chris@26 119