comparison query.cpp @ 768:b9dbe4611dde

Adding Kullback-Leibler divergence as alternate distance function
author mas01mc
date Sat, 15 Oct 2011 17:28:07 +0000
parents ddf08008d45b
children
comparison
equal deleted inserted replaced
767:6d0d41604aba 768:b9dbe4611dde
53 goto error; 53 goto error;
54 } 54 }
55 break; 55 break;
56 case ADB_DISTANCE_EUCLIDEAN_NORMED: 56 case ADB_DISTANCE_EUCLIDEAN_NORMED:
57 case ADB_DISTANCE_EUCLIDEAN: 57 case ADB_DISTANCE_EUCLIDEAN:
58 case ADB_DISTANCE_KULLBACK_LEIBLER_DIVERGENCE:
58 switch(qspec->params.accumulation) { 59 switch(qspec->params.accumulation) {
59 case ADB_ACCUMULATION_DB: 60 case ADB_ACCUMULATION_DB:
60 qstate.accumulator = new DBAccumulator<adb_result_dist_lt>(qspec->params.npoints); 61 qstate.accumulator = new DBAccumulator<adb_result_dist_lt>(qspec->params.npoints);
61 break; 62 break;
62 case ADB_ACCUMULATION_PER_TRACK: 63 case ADB_ACCUMULATION_PER_TRACK:
106 107
107 /* FIXME: we should check the return values from allocation */ 108 /* FIXME: we should check the return values from allocation */
108 static void audiodb_initialize_arrays(adb_t *adb, const adb_query_spec_t *spec, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD) { 109 static void audiodb_initialize_arrays(adb_t *adb, const adb_query_spec_t *spec, int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD) {
109 unsigned int j, k, l, w; 110 unsigned int j, k, l, w;
110 double *dp, *qp, *sp; 111 double *dp, *qp, *sp;
112 double a,b, tmp1;
113 #ifdef SYMMETRIC_KL
114 double tmp2;
115 #endif
111 116
112 const unsigned wL = spec->qid.sequence_length; 117 const unsigned wL = spec->qid.sequence_length;
113 118
114 for(j = 0; j < numVectors; j++) { 119 for(j = 0; j < numVectors; j++) {
115 // Sum products matrix 120 // Sum products matrix
125 sp = data_buffer + k * adb->header->dim; 130 sp = data_buffer + k * adb->header->dim;
126 DD[j][k] = 0.0; // Initialize matched filter array 131 DD[j][k] = 0.0; // Initialize matched filter array
127 dp = &D[j][k]; // point to correlation cell j,k 132 dp = &D[j][k]; // point to correlation cell j,k
128 *dp = 0.0; // initialize correlation cell 133 *dp = 0.0; // initialize correlation cell
129 l = adb->header->dim; // size of vectors 134 l = adb->header->dim; // size of vectors
130 while(l--) 135 if (spec->params.distance!=ADB_DISTANCE_KULLBACK_LEIBLER_DIVERGENCE){
131 *dp += *qp++ * *sp++; 136 while(l--)
137 *dp += *qp++ * *sp++;
138 }
139 else{ // KL
140 while(l--){
141 a = *qp++;
142 b = *sp++;
143 tmp1 = a * log( a / b );
144 if(isnan(tmp1))
145 tmp1=0.0;
146 #ifdef SYMMETRIC_KL
147 tmp2 = b * log( b / a );
148 if(isnan(tmp2))
149 tmp2=0.0;
150 *dp += ( tmp1 + tmp2 ) / 2.0;
151 #else
152 *dp += tmp1;
153 #endif
154 }
155 }
132 } 156 }
133 157
134 double* spd; 158 double* spd;
135 if(!(spec->refine.flags & ADB_REFINE_HOP_SIZE)) { 159 if(!(spec->refine.flags & ADB_REFINE_HOP_SIZE)) {
136 for(w = 0; w < wL; w++) { 160 for(w = 0; w < wL; w++) {
459 uint32_t sPos = pp.spos; // index into l2norm table 483 uint32_t sPos = pp.spos; // index into l2norm table
460 // Test power thresholds before computing distance 484 // Test power thresholds before computing distance
461 if( ( (!power_refine) || audiodb_powers_acceptable(&spec->refine, qpointers->power[qPos], dbpointers.power[sPos])) && 485 if( ( (!power_refine) || audiodb_powers_acceptable(&spec->refine, qpointers->power[qPos], dbpointers.power[sPos])) &&
462 ( qPos<qpointers->nvectors-sequence_length+1 && sPos<(*adb->track_lengths)[pp.trackID]-sequence_length+1 ) ){ 486 ( qPos<qpointers->nvectors-sequence_length+1 && sPos<(*adb->track_lengths)[pp.trackID]-sequence_length+1 ) ){
463 // Compute distance 487 // Compute distance
464 dist = audiodb_dot_product(query + qPos*adb->header->dim, dbdata + sPos*adb->header->dim, adb->header->dim*sequence_length); 488 dist = 1.0e9;
489 if (spec->params.distance==ADB_DISTANCE_EUCLIDEAN_NORMED || spec->params.distance==ADB_DISTANCE_EUCLIDEAN)
490 dist = audiodb_dot_product(query + qPos*adb->header->dim, dbdata + sPos*adb->header->dim, adb->header->dim*sequence_length);
491 else if(spec->params.distance==ADB_DISTANCE_KULLBACK_LEIBLER_DIVERGENCE)
492 dist = audiodb_kullback_leibler(query + qPos*adb->header->dim, dbdata + sPos*adb->header->dim, adb->header->dim*sequence_length);
465 double qn = qpointers->l2norm[qPos]; 493 double qn = qpointers->l2norm[qPos];
466 double sn = dbpointers.l2norm[sPos]; 494 double sn = dbpointers.l2norm[sPos];
467 switch(spec->params.distance) { 495 switch(spec->params.distance) {
468 case ADB_DISTANCE_EUCLIDEAN_NORMED: 496 case ADB_DISTANCE_EUCLIDEAN_NORMED:
469 dist = 2 - (2/(qn*sn))*dist; 497 dist = 2 - (2/(qn*sn))*dist;