annotate query.cpp @ 217:685eb707b660 refactoring

set_up_db() analogue to set_up_query()
author mas01cr
date Tue, 04 Dec 2007 12:47:49 +0000
parents cd3dced4f534
children 016303fc3e1b
rev   line source
mas01cr@204 1 #include "audioDB.h"
mas01cr@204 2
mas01cr@204 3 bool audioDB::powers_acceptable(double p1, double p2) {
mas01cr@204 4 if (use_absolute_threshold) {
mas01cr@204 5 if ((p1 < absolute_threshold) || (p2 < absolute_threshold)) {
mas01cr@204 6 return false;
mas01cr@204 7 }
mas01cr@204 8 }
mas01cr@204 9 if (use_relative_threshold) {
mas01cr@204 10 if (fabs(p1-p2) > fabs(relative_threshold)) {
mas01cr@204 11 return false;
mas01cr@204 12 }
mas01cr@204 13 }
mas01cr@204 14 return true;
mas01cr@204 15 }
mas01cr@204 16
mas01cr@206 17 void audioDB::query(const char* dbName, const char* inFile, adb__queryResponse *adbQueryResponse) {
mas01cr@206 18 switch(queryType) {
mas01cr@204 19 case O2_SEQUENCE_QUERY:
mas01cr@204 20 if(radius==0)
mas01cr@204 21 trackSequenceQueryNN(dbName, inFile, adbQueryResponse);
mas01cr@204 22 else
mas01cr@204 23 trackSequenceQueryRad(dbName, inFile, adbQueryResponse);
mas01cr@204 24 break;
mas01cr@204 25 default:
mas01cr@204 26 error("unrecognized queryType in query()");
mas01cr@204 27 }
mas01cr@204 28 }
mas01cr@204 29
mas01cr@206 30 // return ordinal position of key in keyTable
mas01cr@204 31 unsigned audioDB::getKeyPos(char* key){
mas01cr@204 32 for(unsigned k=0; k<dbH->numFiles; k++)
mas01cr@204 33 if(strncmp(fileTable + k*O2_FILETABLESIZE, key, strlen(key))==0)
mas01cr@204 34 return k;
mas01cr@204 35 error("Key not found",key);
mas01cr@204 36 return O2_ERR_KEYNOTFOUND;
mas01cr@204 37 }
mas01cr@204 38
mas01cr@204 39 // This is a common pattern in sequence queries: what we are doing is
mas01cr@204 40 // taking a window of length seqlen over a buffer of length length,
mas01cr@204 41 // and placing the sum of the elements in that window in the first
mas01cr@204 42 // element of the window: thus replacing all but the last seqlen
mas01cr@216 43 // elements in the buffer with the corresponding windowed sum.
mas01cr@204 44 void audioDB::sequence_sum(double *buffer, int length, int seqlen) {
mas01cr@204 45 double tmp1, tmp2, *ps;
mas01cr@204 46 int j, w;
mas01cr@204 47
mas01cr@204 48 tmp1 = *buffer;
mas01cr@204 49 j = 1;
mas01cr@204 50 w = seqlen - 1;
mas01cr@204 51 while(w--) {
mas01cr@204 52 *buffer += buffer[j++];
mas01cr@204 53 }
mas01cr@204 54 ps = buffer + 1;
mas01cr@204 55 w = length - seqlen; // +1 - 1
mas01cr@204 56 while(w--) {
mas01cr@204 57 tmp2 = *ps;
mas01cr@204 58 *ps = *(ps - 1) - tmp1 + *(ps + seqlen - 1);
mas01cr@204 59 tmp1 = tmp2;
mas01cr@204 60 ps++;
mas01cr@204 61 }
mas01cr@204 62 }
mas01cr@204 63
mas01cr@216 64 // In contrast to sequence_sum() above, sequence_sqrt() and
mas01cr@216 65 // sequence_average() below are simple mappers across the sequence.
mas01cr@204 66 void audioDB::sequence_sqrt(double *buffer, int length, int seqlen) {
mas01cr@204 67 int w = length - seqlen + 1;
mas01cr@204 68 while(w--) {
mas01cr@204 69 *buffer = sqrt(*buffer);
mas01cr@204 70 buffer++;
mas01cr@204 71 }
mas01cr@204 72 }
mas01cr@204 73
mas01cr@204 74 void audioDB::sequence_average(double *buffer, int length, int seqlen) {
mas01cr@204 75 int w = length - seqlen + 1;
mas01cr@204 76 while(w--) {
mas01cr@204 77 *buffer /= seqlen;
mas01cr@204 78 buffer++;
mas01cr@204 79 }
mas01cr@204 80 }
mas01cr@204 81
mas01cr@208 82 void audioDB::initialize_arrays(int track, unsigned int numVectors, double *query, double *data_buffer, double **D, double **DD) {
mas01cr@208 83 unsigned int j, k, l, w;
mas01cr@208 84 double *dp, *qp, *sp;
mas01cr@208 85
mas01cr@208 86 const unsigned HOP_SIZE = sequenceHop;
mas01cr@208 87 const unsigned wL = sequenceLength;
mas01cr@208 88
mas01cr@208 89 for(j = 0; j < numVectors; j++) {
mas01cr@208 90 // Sum products matrix
mas01cr@208 91 D[j] = new double[trackTable[track]];
mas01cr@208 92 assert(D[j]);
mas01cr@208 93 // Matched filter matrix
mas01cr@208 94 DD[j]=new double[trackTable[track]];
mas01cr@208 95 assert(DD[j]);
mas01cr@208 96 }
mas01cr@208 97
mas01cr@208 98 // Dot product
mas01cr@208 99 for(j = 0; j < numVectors; j++)
mas01cr@208 100 for(k = 0; k < trackTable[track]; k++){
mas01cr@208 101 qp = query + j * dbH->dim;
mas01cr@208 102 sp = data_buffer + k * dbH->dim;
mas01cr@208 103 DD[j][k] = 0.0; // Initialize matched filter array
mas01cr@208 104 dp = &D[j][k]; // point to correlation cell j,k
mas01cr@208 105 *dp = 0.0; // initialize correlation cell
mas01cr@208 106 l = dbH->dim; // size of vectors
mas01cr@208 107 while(l--)
mas01cr@208 108 *dp += *qp++ * *sp++;
mas01cr@208 109 }
mas01cr@208 110
mas01cr@208 111 // Matched Filter
mas01cr@208 112 // HOP SIZE == 1
mas01cr@208 113 double* spd;
mas01cr@208 114 if(HOP_SIZE == 1) { // HOP_SIZE = shingleHop
mas01cr@209 115 for(w = 0; w < wL; w++) {
mas01cr@208 116 for(j = 0; j < numVectors - w; j++) {
mas01cr@208 117 sp = DD[j];
mas01cr@208 118 spd = D[j+w] + w;
mas01cr@208 119 k = trackTable[track] - w;
mas01cr@208 120 while(k--)
mas01cr@208 121 *sp++ += *spd++;
mas01cr@208 122 }
mas01cr@209 123 }
mas01cr@208 124 } else { // HOP_SIZE != 1
mas01cr@209 125 for(w = 0; w < wL; w++) {
mas01cr@208 126 for(j = 0; j < numVectors - w; j += HOP_SIZE) {
mas01cr@208 127 sp = DD[j];
mas01cr@208 128 spd = D[j+w]+w;
mas01cr@208 129 for(k = 0; k < trackTable[track] - w; k += HOP_SIZE) {
mas01cr@208 130 *sp += *spd;
mas01cr@208 131 sp += HOP_SIZE;
mas01cr@208 132 spd += HOP_SIZE;
mas01cr@208 133 }
mas01cr@208 134 }
mas01cr@209 135 }
mas01cr@208 136 }
mas01cr@208 137 }
mas01cr@208 138
mas01cr@211 139 void audioDB::delete_arrays(int track, unsigned int numVectors, double **D, double **DD) {
mas01cr@211 140 if(D != NULL) {
mas01cr@211 141 for(unsigned int j = 0; j < numVectors; j++) {
mas01cr@211 142 delete[] D[j];
mas01cr@211 143 }
mas01cr@211 144 }
mas01cr@211 145 if(DD != NULL) {
mas01cr@211 146 for(unsigned int j = 0; j < numVectors; j++) {
mas01cr@211 147 delete[] DD[j];
mas01cr@211 148 }
mas01cr@211 149 }
mas01cr@211 150 }
mas01cr@211 151
mas01cr@209 152 void audioDB::read_data(int track, double **data_buffer_p, size_t *data_buffer_size_p) {
mas01cr@209 153 if (trackTable[track] * sizeof(double) * dbH->dim > *data_buffer_size_p) {
mas01cr@209 154 if(*data_buffer_p) {
mas01cr@209 155 free(*data_buffer_p);
mas01cr@209 156 }
mas01cr@209 157 {
mas01cr@209 158 *data_buffer_size_p = trackTable[track] * sizeof(double) * dbH->dim;
mas01cr@209 159 void *tmp = malloc(*data_buffer_size_p);
mas01cr@209 160 if (tmp == NULL) {
mas01cr@209 161 error("error allocating data buffer");
mas01cr@209 162 }
mas01cr@209 163 *data_buffer_p = (double *) tmp;
mas01cr@209 164 }
mas01cr@209 165 }
mas01cr@209 166
mas01cr@209 167 read(dbfid, *data_buffer_p, trackTable[track] * sizeof(double) * dbH->dim);
mas01cr@209 168 }
mas01cr@209 169
mas01cr@215 170 void audioDB::set_up_query(double **qp, double **qnp, double **qpp, unsigned *nvp) {
mas01cr@214 171 *nvp = (statbuf.st_size - sizeof(int)) / (dbH->dim * sizeof(double));
mas01cr@214 172
mas01cr@214 173 if(!(dbH->flags & O2_FLAG_L2NORM)) {
mas01cr@214 174 error("Database must be L2 normed for sequence query","use -L2NORM");
mas01cr@214 175 }
mas01cr@214 176
mas01cr@214 177 if(*nvp < sequenceLength) {
mas01cr@214 178 error("Query shorter than requested sequence length", "maybe use -l");
mas01cr@214 179 }
mas01cr@214 180
mas01cr@214 181 if(verbosity>1) {
mas01cr@214 182 std::cerr << "performing norms ... "; std::cerr.flush();
mas01cr@214 183 }
mas01cr@214 184
mas01cr@214 185 *qp = new double[*nvp * dbH->dim];
mas01cr@214 186 memcpy(*qp, indata+sizeof(int), *nvp * dbH->dim * sizeof(double));
mas01cr@214 187 *qnp = new double[*nvp];
mas01cr@214 188 unitNorm(*qp, dbH->dim, *nvp, *qnp);
mas01cr@215 189
mas01cr@215 190 sequence_sum(*qnp, *nvp, sequenceLength);
mas01cr@215 191 sequence_sqrt(*qnp, *nvp, sequenceLength);
mas01cr@215 192
mas01cr@215 193 if (usingPower) {
mas01cr@215 194 *qpp = new double[*nvp];
mas01cr@215 195 if (lseek(powerfd, sizeof(int), SEEK_SET) == (off_t) -1) {
mas01cr@215 196 error("error seeking to data", powerFileName, "lseek");
mas01cr@215 197 }
mas01cr@215 198 int count = read(powerfd, *qpp, *nvp * sizeof(double));
mas01cr@215 199 if (count == -1) {
mas01cr@215 200 error("error reading data", powerFileName, "read");
mas01cr@215 201 }
mas01cr@215 202 if ((unsigned) count != *nvp * sizeof(double)) {
mas01cr@215 203 error("short read", powerFileName);
mas01cr@215 204 }
mas01cr@215 205
mas01cr@215 206 sequence_sum(*qpp, *nvp, sequenceLength);
mas01cr@215 207 sequence_average(*qpp, *nvp, sequenceLength);
mas01cr@215 208 }
mas01cr@214 209 }
mas01cr@214 210
mas01cr@217 211 void audioDB::set_up_db(double **snp, double **spp, unsigned int *dvp) {
mas01cr@217 212 *dvp = dbH->length / (dbH->dim * sizeof(double));
mas01cr@217 213 *snp = new double[*dvp];
mas01cr@217 214
mas01cr@217 215 double *snpp = *snp, *sppp = 0;
mas01cr@217 216 memcpy(*snp, l2normTable, *dvp * sizeof(double));
mas01cr@217 217
mas01cr@217 218 if (usingPower) {
mas01cr@217 219 if (!(dbH->flags & O2_FLAG_POWER)) {
mas01cr@217 220 error("database not power-enabled", dbName);
mas01cr@217 221 }
mas01cr@217 222 *spp = new double[*dvp];
mas01cr@217 223 sppp = *spp;
mas01cr@217 224 memcpy(*spp, powerTable, *dvp * sizeof(double));
mas01cr@217 225 }
mas01cr@217 226
mas01cr@217 227 for(unsigned int i = 0; i < dbH->numFiles; i++){
mas01cr@217 228 if(trackTable[i] >= sequenceLength) {
mas01cr@217 229 sequence_sum(snpp, trackTable[i], sequenceLength);
mas01cr@217 230 sequence_sqrt(snpp, trackTable[i], sequenceLength);
mas01cr@217 231
mas01cr@217 232 if (usingPower) {
mas01cr@217 233 sequence_sum(sppp, trackTable[i], sequenceLength);
mas01cr@217 234 sequence_average(sppp, trackTable[i], sequenceLength);
mas01cr@217 235 }
mas01cr@217 236 }
mas01cr@217 237 snpp += trackTable[i];
mas01cr@217 238 if (usingPower) {
mas01cr@217 239 sppp += trackTable[i];
mas01cr@217 240 }
mas01cr@217 241 }
mas01cr@217 242 }
mas01cr@217 243
mas01cr@204 244 void audioDB::trackSequenceQueryNN(const char* dbName, const char* inFile, adb__queryResponse *adbQueryResponse){
mas01cr@204 245
mas01cr@204 246 initTables(dbName, inFile);
mas01cr@204 247
mas01cr@214 248 unsigned int numVectors;
mas01cr@214 249 double *query, *query_data;
mas01cr@215 250 double *qNorm, *qnPtr, *qPower = 0, *qpPtr = 0;
mas01cr@204 251
mas01cr@215 252 set_up_query(&query, &qNorm, &qPower, &numVectors);
mas01cr@214 253 query_data = query;
mas01cr@215 254 qpPtr = qPower;
mas01cr@215 255 qnPtr = qNorm;
mas01cr@204 256
mas01cr@217 257 unsigned int dbVectors;
mas01cr@217 258 double *sNorm, *snPtr, *sPower = 0, *spPtr = 0;
mas01cr@204 259
mas01cr@217 260 set_up_db(&sNorm, &sPower, &dbVectors);
mas01cr@217 261 spPtr = sPower;
mas01cr@217 262 snPtr = sNorm;
mas01cr@204 263
mas01cr@204 264 if(verbosity>1) {
mas01cr@204 265 std::cerr << "matching tracks..." << std::endl;
mas01cr@204 266 }
mas01cr@204 267
mas01cr@204 268 assert(pointNN>0 && pointNN<=O2_MAXNN);
mas01cr@204 269 assert(trackNN>0 && trackNN<=O2_MAXNN);
mas01cr@204 270
mas01cr@204 271 // Make temporary dynamic memory for results
mas01cr@204 272 double trackDistances[trackNN];
mas01cr@204 273 unsigned trackIDs[trackNN];
mas01cr@204 274 unsigned trackQIndexes[trackNN];
mas01cr@204 275 unsigned trackSIndexes[trackNN];
mas01cr@204 276
mas01cr@204 277 double distances[pointNN];
mas01cr@204 278 unsigned qIndexes[pointNN];
mas01cr@204 279 unsigned sIndexes[pointNN];
mas01cr@204 280
mas01cr@217 281 unsigned j,k,l,m,n,track,trackOffset=0, HOP_SIZE=sequenceHop, wL=sequenceLength;
mas01cr@204 282 double thisDist;
mas01cr@204 283
mas01cr@204 284 for(k=0; k<pointNN; k++){
mas01cr@204 285 distances[k]=1.0e6;
mas01cr@204 286 qIndexes[k]=~0;
mas01cr@204 287 sIndexes[k]=~0;
mas01cr@204 288 }
mas01cr@204 289
mas01cr@204 290 for(k=0; k<trackNN; k++){
mas01cr@204 291 trackDistances[k]=1.0e6;
mas01cr@204 292 trackQIndexes[k]=~0;
mas01cr@204 293 trackSIndexes[k]=~0;
mas01cr@204 294 trackIDs[k]=~0;
mas01cr@204 295 }
mas01cr@204 296
mas01cr@204 297 // Timestamp and durations processing
mas01cr@204 298 double meanQdur = 0;
mas01cr@204 299 double *timesdata = 0;
mas01cr@204 300 double *querydurs = 0;
mas01cr@204 301 double *meanDBdur = 0;
mas01cr@204 302
mas01cr@204 303 if(usingTimes && !(dbH->flags & O2_FLAG_TIMES)){
mas01cr@204 304 std::cerr << "warning: ignoring query timestamps for non-timestamped database" << std::endl;
mas01cr@204 305 usingTimes=0;
mas01cr@204 306 }
mas01cr@204 307
mas01cr@204 308 else if(!usingTimes && (dbH->flags & O2_FLAG_TIMES))
mas01cr@204 309 std::cerr << "warning: no timestamps given for query. Ignoring database timestamps." << std::endl;
mas01cr@204 310
mas01cr@204 311 else if(usingTimes && (dbH->flags & O2_FLAG_TIMES)){
mas01cr@204 312 timesdata = new double[2*numVectors];
mas01cr@204 313 querydurs = new double[numVectors];
mas01cr@204 314
mas01cr@204 315 insertTimeStamps(numVectors, timesFile, timesdata);
mas01cr@204 316 // Calculate durations of points
mas01cr@204 317 for(k=0; k<numVectors-1; k++) {
mas01cr@204 318 querydurs[k] = timesdata[2*k+1] - timesdata[2*k];
mas01cr@204 319 meanQdur += querydurs[k];
mas01cr@204 320 }
mas01cr@204 321 meanQdur/=k;
mas01cr@204 322 if(verbosity>1) {
mas01cr@204 323 std::cerr << "mean query file duration: " << meanQdur << std::endl;
mas01cr@204 324 }
mas01cr@204 325 meanDBdur = new double[dbH->numFiles];
mas01cr@204 326 assert(meanDBdur);
mas01cr@204 327 for(k=0; k<dbH->numFiles; k++){
mas01cr@204 328 meanDBdur[k]=0.0;
mas01cr@204 329 for(j=0; j<trackTable[k]-1 ; j++) {
mas01cr@204 330 meanDBdur[k]+=timesTable[2*j+1]-timesTable[2*j];
mas01cr@204 331 }
mas01cr@204 332 meanDBdur[k]/=j;
mas01cr@204 333 }
mas01cr@204 334 }
mas01cr@204 335
mas01cr@204 336 if(usingQueryPoint)
mas01cr@204 337 if(queryPoint>numVectors || queryPoint>numVectors-wL+1)
mas01cr@204 338 error("queryPoint > numVectors-wL+1 in query");
mas01cr@204 339 else{
mas01cr@204 340 if(verbosity>1) {
mas01cr@204 341 std::cerr << "query point: " << queryPoint << std::endl; std::cerr.flush();
mas01cr@204 342 }
mas01cr@204 343 query = query + queryPoint * dbH->dim;
mas01cr@204 344 qnPtr = qnPtr + queryPoint;
mas01cr@204 345 if (usingPower) {
mas01cr@204 346 qpPtr = qpPtr + queryPoint;
mas01cr@204 347 }
mas01cr@204 348 numVectors=wL;
mas01cr@204 349 }
mas01cr@204 350
mas01cr@204 351 double ** D = 0; // Differences query and target
mas01cr@204 352 double ** DD = 0; // Matched filter distance
mas01cr@204 353
mas01cr@204 354 D = new double*[numVectors];
mas01cr@204 355 assert(D);
mas01cr@204 356 DD = new double*[numVectors];
mas01cr@204 357 assert(DD);
mas01cr@204 358
mas01cr@204 359 gettimeofday(&tv1, NULL);
mas01cr@204 360 unsigned processedTracks = 0;
mas01cr@204 361 unsigned successfulTracks=0;
mas01cr@204 362
mas01cr@204 363 // build track offset table
mas01cr@204 364 off_t *trackOffsetTable = new off_t[dbH->numFiles];
mas01cr@204 365 unsigned cumTrack=0;
mas01cr@204 366 off_t trackIndexOffset;
mas01cr@204 367 for(k=0; k<dbH->numFiles;k++){
mas01cr@204 368 trackOffsetTable[k]=cumTrack;
mas01cr@204 369 cumTrack+=trackTable[k]*dbH->dim;
mas01cr@204 370 }
mas01cr@204 371
mas01cr@204 372 char nextKey [MAXSTR];
mas01cr@204 373
mas01cr@204 374 // chi^2 statistics
mas01cr@204 375 double sampleCount = 0;
mas01cr@204 376 double sampleSum = 0;
mas01cr@204 377 double logSampleSum = 0;
mas01cr@204 378 double minSample = 1e9;
mas01cr@204 379 double maxSample = 0;
mas01cr@204 380
mas01cr@204 381 // Track loop
mas01cr@204 382 size_t data_buffer_size = 0;
mas01cr@204 383 double *data_buffer = 0;
mas01cr@204 384 lseek(dbfid, dbH->dataOffset, SEEK_SET);
mas01cr@204 385
mas01cr@204 386 for(processedTracks=0, track=0 ; processedTracks < dbH->numFiles ; track++, processedTracks++) {
mas01cr@204 387
mas01cr@204 388 trackOffset = trackOffsetTable[track]; // numDoubles offset
mas01cr@204 389
mas01cr@204 390 // get trackID from file if using a control file
mas01cr@204 391 if(trackFile) {
mas01cr@204 392 trackFile->getline(nextKey,MAXSTR);
mas01cr@204 393 if(!trackFile->eof()) {
mas01cr@204 394 track = getKeyPos(nextKey);
mas01cr@204 395 trackOffset = trackOffsetTable[track];
mas01cr@204 396 lseek(dbfid, dbH->dataOffset + trackOffset * sizeof(double), SEEK_SET);
mas01cr@204 397 } else {
mas01cr@204 398 break;
mas01cr@204 399 }
mas01cr@204 400 }
mas01cr@204 401
mas01cr@204 402 trackIndexOffset=trackOffset/dbH->dim; // numVectors offset
mas01cr@204 403
mas01cr@204 404 if(sequenceLength<=trackTable[track]){ // test for short sequences
mas01cr@204 405
mas01cr@204 406 if(verbosity>7) {
mas01cr@204 407 std::cerr << track << "." << trackIndexOffset << "." << trackTable[track] << " | ";std::cerr.flush();
mas01cr@204 408 }
mas01cr@209 409
mas01cr@209 410 read_data(track, &data_buffer, &data_buffer_size);
mas01cr@208 411 initialize_arrays(track, numVectors, query, data_buffer, D, DD);
mas01cr@207 412
mas01cr@204 413 if(verbosity>3 && usingTimes) {
mas01cr@204 414 std::cerr << "meanQdur=" << meanQdur << " meanDBdur=" << meanDBdur[track] << std::endl;
mas01cr@204 415 std::cerr.flush();
mas01cr@204 416 }
mas01cr@204 417
mas01cr@204 418 if(!usingTimes ||
mas01cr@204 419 (usingTimes
mas01cr@204 420 && fabs(meanDBdur[track]-meanQdur)<meanQdur*timesTol)){
mas01cr@204 421
mas01cr@204 422 if(verbosity>3 && usingTimes) {
mas01cr@204 423 std::cerr << "within duration tolerance." << std::endl;
mas01cr@204 424 std::cerr.flush();
mas01cr@204 425 }
mas01cr@204 426
mas01cr@204 427 // Search for minimum distance by shingles (concatenated vectors)
mas01cr@204 428 for(j=0;j<=numVectors-wL;j+=HOP_SIZE)
mas01cr@204 429 for(k=0;k<=trackTable[track]-wL;k+=HOP_SIZE){
mas01cr@204 430 thisDist=2-(2/(qnPtr[j]*sNorm[trackIndexOffset+k]))*DD[j][k];
mas01cr@204 431 if(verbosity>9) {
mas01cr@204 432 std::cerr << thisDist << " " << qnPtr[j] << " " << sNorm[trackIndexOffset+k] << std::endl;
mas01cr@204 433 }
mas01cr@204 434 // Gather chi^2 statistics
mas01cr@204 435 if(thisDist<minSample)
mas01cr@204 436 minSample=thisDist;
mas01cr@204 437 else if(thisDist>maxSample)
mas01cr@204 438 maxSample=thisDist;
mas01cr@204 439 if(thisDist>1e-9){
mas01cr@204 440 sampleCount++;
mas01cr@204 441 sampleSum+=thisDist;
mas01cr@204 442 logSampleSum+=log(thisDist);
mas01cr@204 443 }
mas01cr@204 444
mas01cr@204 445 // diffL2 = fabs(qnPtr[j] - sNorm[trackIndexOffset+k]);
mas01cr@204 446 // Power test
mas01cr@204 447 if (usingPower) {
mas01cr@204 448 if (!(powers_acceptable(qpPtr[j], sPower[trackIndexOffset + k]))) {
mas01cr@204 449 thisDist = 1000000.0;
mas01cr@204 450 }
mas01cr@204 451 }
mas01cr@204 452
mas01cr@204 453 // k-NN match algorithm
mas01cr@204 454 m=pointNN;
mas01cr@204 455 while(m--){
mas01cr@204 456 if(thisDist<=distances[m])
mas01cr@204 457 if(m==0 || thisDist>=distances[m-1]){
mas01cr@204 458 // Shuffle distances up the list
mas01cr@204 459 for(l=pointNN-1; l>m; l--){
mas01cr@204 460 distances[l]=distances[l-1];
mas01cr@204 461 qIndexes[l]=qIndexes[l-1];
mas01cr@204 462 sIndexes[l]=sIndexes[l-1];
mas01cr@204 463 }
mas01cr@204 464 distances[m]=thisDist;
mas01cr@204 465 if(usingQueryPoint)
mas01cr@204 466 qIndexes[m]=queryPoint;
mas01cr@204 467 else
mas01cr@204 468 qIndexes[m]=j;
mas01cr@204 469 sIndexes[m]=k;
mas01cr@204 470 break;
mas01cr@204 471 }
mas01cr@204 472 }
mas01cr@204 473 }
mas01cr@204 474 // Calculate the mean of the N-Best matches
mas01cr@204 475 thisDist=0.0;
mas01cr@204 476 for(m=0; m<pointNN; m++) {
mas01cr@204 477 if (distances[m] == 1000000.0) break;
mas01cr@204 478 thisDist+=distances[m];
mas01cr@204 479 }
mas01cr@204 480 thisDist/=m;
mas01cr@204 481
mas01cr@204 482 // Let's see the distances then...
mas01cr@204 483 if(verbosity>3) {
mas01cr@204 484 std::cerr << fileTable+track*O2_FILETABLESIZE << " " << thisDist << std::endl;
mas01cr@204 485 }
mas01cr@204 486
mas01cr@204 487
mas01cr@204 488 // All the track stuff goes here
mas01cr@204 489 n=trackNN;
mas01cr@204 490 while(n--){
mas01cr@204 491 if(thisDist<=trackDistances[n]){
mas01cr@204 492 if((n==0 || thisDist>=trackDistances[n-1])){
mas01cr@204 493 // Copy all values above up the queue
mas01cr@204 494 for( l=trackNN-1 ; l > n ; l--){
mas01cr@204 495 trackDistances[l]=trackDistances[l-1];
mas01cr@204 496 trackQIndexes[l]=trackQIndexes[l-1];
mas01cr@204 497 trackSIndexes[l]=trackSIndexes[l-1];
mas01cr@204 498 trackIDs[l]=trackIDs[l-1];
mas01cr@204 499 }
mas01cr@204 500 trackDistances[n]=thisDist;
mas01cr@204 501 trackQIndexes[n]=qIndexes[0];
mas01cr@204 502 trackSIndexes[n]=sIndexes[0];
mas01cr@204 503 successfulTracks++;
mas01cr@204 504 trackIDs[n]=track;
mas01cr@204 505 break;
mas01cr@204 506 }
mas01cr@204 507 }
mas01cr@204 508 else
mas01cr@204 509 break;
mas01cr@204 510 }
mas01cr@211 511 } // Duration match
mas01cr@211 512 delete_arrays(track, numVectors, D, DD);
mas01cr@204 513 }
mas01cr@204 514 // per-track reset array values
mas01cr@204 515 for(unsigned k=0; k<pointNN; k++){
mas01cr@204 516 distances[k]=1.0e6;
mas01cr@204 517 qIndexes[k]=~0;
mas01cr@204 518 sIndexes[k]=~0;
mas01cr@204 519 }
mas01cr@204 520 }
mas01cr@204 521
mas01cr@204 522 free(data_buffer);
mas01cr@204 523
mas01cr@204 524 gettimeofday(&tv2,NULL);
mas01cr@204 525 if(verbosity>1) {
mas01cr@204 526 std::cerr << std::endl << "processed tracks :" << processedTracks << " matched tracks: " << successfulTracks << " elapsed time:"
mas01cr@204 527 << ( tv2.tv_sec*1000 + tv2.tv_usec/1000 ) - ( tv1.tv_sec*1000+tv1.tv_usec/1000 ) << " msec" << std::endl;
mas01cr@204 528 std::cerr << "sampleCount: " << sampleCount << " sampleSum: " << sampleSum << " logSampleSum: " << logSampleSum
mas01cr@204 529 << " minSample: " << minSample << " maxSample: " << maxSample << std::endl;
mas01cr@204 530 }
mas01cr@204 531 if(adbQueryResponse==0){
mas01cr@204 532 if(verbosity>1) {
mas01cr@204 533 std::cerr<<std::endl;
mas01cr@204 534 }
mas01cr@204 535 // Output answer
mas01cr@204 536 // Loop over nearest neighbours
mas01cr@204 537 for(k=0; k < std::min(trackNN,successfulTracks); k++)
mas01cr@204 538 std::cout << fileTable+trackIDs[k]*O2_FILETABLESIZE << " " << trackDistances[k] << " "
mas01cr@204 539 << trackQIndexes[k] << " " << trackSIndexes[k] << std::endl;
mas01cr@204 540 }
mas01cr@204 541 else{ // Process Web Services Query
mas01cr@204 542 int listLen = std::min(trackNN, processedTracks);
mas01cr@204 543 adbQueryResponse->result.__sizeRlist=listLen;
mas01cr@204 544 adbQueryResponse->result.__sizeDist=listLen;
mas01cr@204 545 adbQueryResponse->result.__sizeQpos=listLen;
mas01cr@204 546 adbQueryResponse->result.__sizeSpos=listLen;
mas01cr@204 547 adbQueryResponse->result.Rlist= new char*[listLen];
mas01cr@204 548 adbQueryResponse->result.Dist = new double[listLen];
mas01cr@204 549 adbQueryResponse->result.Qpos = new unsigned int[listLen];
mas01cr@204 550 adbQueryResponse->result.Spos = new unsigned int[listLen];
mas01cr@204 551 for(k=0; k<(unsigned)adbQueryResponse->result.__sizeRlist; k++){
mas01cr@204 552 adbQueryResponse->result.Rlist[k]=new char[O2_MAXFILESTR];
mas01cr@204 553 adbQueryResponse->result.Dist[k]=trackDistances[k];
mas01cr@204 554 adbQueryResponse->result.Qpos[k]=trackQIndexes[k];
mas01cr@204 555 adbQueryResponse->result.Spos[k]=trackSIndexes[k];
mas01cr@204 556 sprintf(adbQueryResponse->result.Rlist[k], "%s", fileTable+trackIDs[k]*O2_FILETABLESIZE);
mas01cr@204 557 }
mas01cr@204 558 }
mas01cr@204 559
mas01cr@204 560 // Clean up
mas01cr@204 561 if(trackOffsetTable)
mas01cr@204 562 delete[] trackOffsetTable;
mas01cr@214 563 if(query_data)
mas01cr@214 564 delete[] query_data;
mas01cr@204 565 if(qNorm)
mas01cr@204 566 delete[] qNorm;
mas01cr@204 567 if(sNorm)
mas01cr@204 568 delete[] sNorm;
mas01cr@204 569 if(qPower)
mas01cr@204 570 delete[] qPower;
mas01cr@204 571 if(sPower)
mas01cr@204 572 delete[] sPower;
mas01cr@204 573 if(D)
mas01cr@204 574 delete[] D;
mas01cr@204 575 if(DD)
mas01cr@204 576 delete[] DD;
mas01cr@204 577 if(timesdata)
mas01cr@204 578 delete[] timesdata;
mas01cr@204 579 if(querydurs)
mas01cr@204 580 delete[] querydurs;
mas01cr@204 581 if(meanDBdur)
mas01cr@204 582 delete[] meanDBdur;
mas01cr@204 583 }
mas01cr@204 584
mas01cr@204 585 void audioDB::trackSequenceQueryRad(const char* dbName, const char* inFile, adb__queryResponse *adbQueryResponse){
mas01cr@204 586
mas01cr@204 587 initTables(dbName, inFile);
mas01cr@204 588
mas01cr@214 589 unsigned int numVectors;
mas01cr@214 590 double *query, *query_data;
mas01cr@215 591 double *qNorm, *qnPtr, *qPower = 0, *qpPtr = 0;
mas01cr@204 592
mas01cr@215 593 set_up_query(&query, &qNorm, &qPower, &numVectors);
mas01cr@214 594 query_data = query;
mas01cr@215 595 qpPtr = qPower;
mas01cr@215 596 qnPtr = qNorm;
mas01cr@214 597
mas01cr@217 598 unsigned int dbVectors;
mas01cr@217 599 double *sNorm, *snPtr, *sPower = 0, *spPtr = 0;
mas01cr@204 600
mas01cr@217 601 set_up_db(&sNorm, &sPower, &dbVectors);
mas01cr@217 602 spPtr = sPower;
mas01cr@217 603 snPtr = sNorm;
mas01cr@204 604
mas01cr@204 605 if(verbosity>1) {
mas01cr@204 606 std::cerr << "matching tracks..." << std::endl;
mas01cr@204 607 }
mas01cr@204 608
mas01cr@204 609 assert(pointNN>0 && pointNN<=O2_MAXNN);
mas01cr@204 610 assert(trackNN>0 && trackNN<=O2_MAXNN);
mas01cr@204 611
mas01cr@204 612 // Make temporary dynamic memory for results
mas01cr@204 613 double trackDistances[trackNN];
mas01cr@204 614 unsigned trackIDs[trackNN];
mas01cr@204 615 unsigned trackQIndexes[trackNN];
mas01cr@204 616 unsigned trackSIndexes[trackNN];
mas01cr@204 617
mas01cr@204 618 double distances[pointNN];
mas01cr@204 619 unsigned qIndexes[pointNN];
mas01cr@204 620 unsigned sIndexes[pointNN];
mas01cr@204 621
mas01cr@217 622 unsigned j,k,l,n,track,trackOffset=0;
mas01cr@208 623 unsigned const HOP_SIZE=sequenceHop;
mas01cr@208 624 unsigned const wL=sequenceLength;
mas01cr@204 625 double thisDist;
mas01cr@204 626
mas01cr@204 627 for(k=0; k<pointNN; k++){
mas01cr@204 628 distances[k]=0.0;
mas01cr@204 629 qIndexes[k]=~0;
mas01cr@204 630 sIndexes[k]=~0;
mas01cr@204 631 }
mas01cr@204 632
mas01cr@204 633 for(k=0; k<trackNN; k++){
mas01cr@204 634 trackDistances[k]=0.0;
mas01cr@204 635 trackQIndexes[k]=~0;
mas01cr@204 636 trackSIndexes[k]=~0;
mas01cr@204 637 trackIDs[k]=~0;
mas01cr@204 638 }
mas01cr@204 639
mas01cr@204 640 // Timestamp and durations processing
mas01cr@204 641 double meanQdur = 0;
mas01cr@204 642 double *timesdata = 0;
mas01cr@204 643 double *querydurs = 0;
mas01cr@204 644 double *meanDBdur = 0;
mas01cr@204 645
mas01cr@204 646 if(usingTimes && !(dbH->flags & O2_FLAG_TIMES)){
mas01cr@204 647 std::cerr << "warning: ignoring query timestamps for non-timestamped database" << std::endl;
mas01cr@204 648 usingTimes=0;
mas01cr@204 649 }
mas01cr@204 650
mas01cr@204 651 else if(!usingTimes && (dbH->flags & O2_FLAG_TIMES))
mas01cr@204 652 std::cerr << "warning: no timestamps given for query. Ignoring database timestamps." << std::endl;
mas01cr@204 653
mas01cr@204 654 else if(usingTimes && (dbH->flags & O2_FLAG_TIMES)){
mas01cr@204 655 timesdata = new double[2*numVectors];
mas01cr@204 656 querydurs = new double[numVectors];
mas01cr@204 657
mas01cr@204 658 insertTimeStamps(numVectors, timesFile, timesdata);
mas01cr@204 659 // Calculate durations of points
mas01cr@204 660 for(k=0; k<numVectors-1; k++){
mas01cr@204 661 querydurs[k] = timesdata[2*k+1] - timesdata[2*k];
mas01cr@204 662 meanQdur += querydurs[k];
mas01cr@204 663 }
mas01cr@204 664 meanQdur/=k;
mas01cr@204 665 if(verbosity>1) {
mas01cr@204 666 std::cerr << "mean query file duration: " << meanQdur << std::endl;
mas01cr@204 667 }
mas01cr@204 668 meanDBdur = new double[dbH->numFiles];
mas01cr@204 669 assert(meanDBdur);
mas01cr@204 670 for(k=0; k<dbH->numFiles; k++){
mas01cr@204 671 meanDBdur[k]=0.0;
mas01cr@204 672 for(j=0; j<trackTable[k]-1 ; j++) {
mas01cr@204 673 meanDBdur[k]+=timesTable[2*j+1]-timesTable[2*j];
mas01cr@204 674 }
mas01cr@204 675 meanDBdur[k]/=j;
mas01cr@204 676 }
mas01cr@204 677 }
mas01cr@204 678
mas01cr@204 679 if(usingQueryPoint)
mas01cr@204 680 if(queryPoint>numVectors || queryPoint>numVectors-wL+1)
mas01cr@204 681 error("queryPoint > numVectors-wL+1 in query");
mas01cr@204 682 else{
mas01cr@204 683 if(verbosity>1) {
mas01cr@204 684 std::cerr << "query point: " << queryPoint << std::endl; std::cerr.flush();
mas01cr@204 685 }
mas01cr@204 686 query = query + queryPoint*dbH->dim;
mas01cr@204 687 qnPtr = qnPtr + queryPoint;
mas01cr@204 688 if (usingPower) {
mas01cr@204 689 qpPtr = qpPtr + queryPoint;
mas01cr@204 690 }
mas01cr@204 691 numVectors=wL;
mas01cr@204 692 }
mas01cr@204 693
mas01cr@204 694 double ** D = 0; // Differences query and target
mas01cr@204 695 double ** DD = 0; // Matched filter distance
mas01cr@204 696
mas01cr@204 697 D = new double*[numVectors];
mas01cr@204 698 assert(D);
mas01cr@204 699 DD = new double*[numVectors];
mas01cr@204 700 assert(DD);
mas01cr@204 701
mas01cr@204 702 gettimeofday(&tv1, NULL);
mas01cr@204 703 unsigned processedTracks = 0;
mas01cr@204 704 unsigned successfulTracks=0;
mas01cr@204 705
mas01cr@204 706 // build track offset table
mas01cr@204 707 off_t *trackOffsetTable = new off_t[dbH->numFiles];
mas01cr@204 708 unsigned cumTrack=0;
mas01cr@204 709 off_t trackIndexOffset;
mas01cr@204 710 for(k=0; k<dbH->numFiles;k++){
mas01cr@204 711 trackOffsetTable[k]=cumTrack;
mas01cr@204 712 cumTrack+=trackTable[k]*dbH->dim;
mas01cr@204 713 }
mas01cr@204 714
mas01cr@204 715 char nextKey [MAXSTR];
mas01cr@204 716
mas01cr@204 717 // chi^2 statistics
mas01cr@204 718 double sampleCount = 0;
mas01cr@204 719 double sampleSum = 0;
mas01cr@204 720 double logSampleSum = 0;
mas01cr@204 721 double minSample = 1e9;
mas01cr@204 722 double maxSample = 0;
mas01cr@204 723
mas01cr@204 724 // Track loop
mas01cr@204 725 size_t data_buffer_size = 0;
mas01cr@204 726 double *data_buffer = 0;
mas01cr@204 727 lseek(dbfid, dbH->dataOffset, SEEK_SET);
mas01cr@204 728
mas01cr@204 729 for(processedTracks=0, track=0 ; processedTracks < dbH->numFiles ; track++, processedTracks++){
mas01cr@204 730
mas01cr@204 731 trackOffset = trackOffsetTable[track]; // numDoubles offset
mas01cr@204 732
mas01cr@204 733 // get trackID from file if using a control file
mas01cr@204 734 if(trackFile) {
mas01cr@204 735 trackFile->getline(nextKey,MAXSTR);
mas01cr@204 736 if(!trackFile->eof()) {
mas01cr@204 737 track = getKeyPos(nextKey);
mas01cr@204 738 trackOffset = trackOffsetTable[track];
mas01cr@204 739 lseek(dbfid, dbH->dataOffset + trackOffset * sizeof(double), SEEK_SET);
mas01cr@204 740 } else {
mas01cr@204 741 break;
mas01cr@204 742 }
mas01cr@204 743 }
mas01cr@204 744
mas01cr@204 745 trackIndexOffset=trackOffset/dbH->dim; // numVectors offset
mas01cr@204 746
mas01cr@204 747 if(sequenceLength<=trackTable[track]){ // test for short sequences
mas01cr@204 748
mas01cr@204 749 if(verbosity>7) {
mas01cr@204 750 std::cerr << track << "." << trackIndexOffset << "." << trackTable[track] << " | ";std::cerr.flush();
mas01cr@204 751 }
mas01cr@204 752
mas01cr@209 753 read_data(track, &data_buffer, &data_buffer_size);
mas01cr@208 754 initialize_arrays(track, numVectors, query, data_buffer, D, DD);
mas01cr@207 755
mas01cr@204 756 if(verbosity>3 && usingTimes) {
mas01cr@204 757 std::cerr << "meanQdur=" << meanQdur << " meanDBdur=" << meanDBdur[track] << std::endl;
mas01cr@204 758 std::cerr.flush();
mas01cr@204 759 }
mas01cr@204 760
mas01cr@204 761 if(!usingTimes ||
mas01cr@204 762 (usingTimes
mas01cr@204 763 && fabs(meanDBdur[track]-meanQdur)<meanQdur*timesTol)){
mas01cr@204 764
mas01cr@204 765 if(verbosity>3 && usingTimes) {
mas01cr@204 766 std::cerr << "within duration tolerance." << std::endl;
mas01cr@204 767 std::cerr.flush();
mas01cr@204 768 }
mas01cr@204 769
mas01cr@204 770 // Search for minimum distance by shingles (concatenated vectors)
mas01cr@204 771 for(j=0;j<=numVectors-wL;j+=HOP_SIZE)
mas01cr@204 772 for(k=0;k<=trackTable[track]-wL;k+=HOP_SIZE){
mas01cr@204 773 thisDist=2-(2/(qnPtr[j]*sNorm[trackIndexOffset+k]))*DD[j][k];
mas01cr@204 774 if(verbosity>9) {
mas01cr@204 775 std::cerr << thisDist << " " << qnPtr[j] << " " << sNorm[trackIndexOffset+k] << std::endl;
mas01cr@204 776 }
mas01cr@204 777 // Gather chi^2 statistics
mas01cr@204 778 if(thisDist<minSample)
mas01cr@204 779 minSample=thisDist;
mas01cr@204 780 else if(thisDist>maxSample)
mas01cr@204 781 maxSample=thisDist;
mas01cr@204 782 if(thisDist>1e-9){
mas01cr@204 783 sampleCount++;
mas01cr@204 784 sampleSum+=thisDist;
mas01cr@204 785 logSampleSum+=log(thisDist);
mas01cr@204 786 }
mas01cr@204 787
mas01cr@204 788 // diffL2 = fabs(qnPtr[j] - sNorm[trackIndexOffset+k]);
mas01cr@204 789 // Power test
mas01cr@204 790 if (usingPower) {
mas01cr@204 791 if (!(powers_acceptable(qpPtr[j], sPower[trackIndexOffset + k]))) {
mas01cr@204 792 thisDist = 1000000.0;
mas01cr@204 793 }
mas01cr@204 794 }
mas01cr@204 795
mas01cr@204 796 if(thisDist>=0 && thisDist<=radius){
mas01cr@204 797 distances[0]++; // increment count
mas01cr@204 798 break; // only need one track point per query point
mas01cr@204 799 }
mas01cr@204 800 }
mas01cr@204 801 // How many points were below threshold ?
mas01cr@204 802 thisDist=distances[0];
mas01cr@204 803
mas01cr@204 804 // Let's see the distances then...
mas01cr@204 805 if(verbosity>3) {
mas01cr@204 806 std::cerr << fileTable+track*O2_FILETABLESIZE << " " << thisDist << std::endl;
mas01cr@204 807 }
mas01cr@204 808
mas01cr@204 809 // All the track stuff goes here
mas01cr@204 810 n=trackNN;
mas01cr@204 811 while(n--){
mas01cr@204 812 if(thisDist>trackDistances[n]){
mas01cr@204 813 if((n==0 || thisDist<=trackDistances[n-1])){
mas01cr@204 814 // Copy all values above up the queue
mas01cr@204 815 for( l=trackNN-1 ; l > n ; l--){
mas01cr@204 816 trackDistances[l]=trackDistances[l-1];
mas01cr@204 817 trackQIndexes[l]=trackQIndexes[l-1];
mas01cr@204 818 trackSIndexes[l]=trackSIndexes[l-1];
mas01cr@204 819 trackIDs[l]=trackIDs[l-1];
mas01cr@204 820 }
mas01cr@204 821 trackDistances[n]=thisDist;
mas01cr@204 822 trackQIndexes[n]=qIndexes[0];
mas01cr@204 823 trackSIndexes[n]=sIndexes[0];
mas01cr@204 824 successfulTracks++;
mas01cr@204 825 trackIDs[n]=track;
mas01cr@204 826 break;
mas01cr@204 827 }
mas01cr@204 828 }
mas01cr@204 829 else
mas01cr@204 830 break;
mas01cr@204 831 }
mas01cr@204 832 } // Duration match
mas01cr@211 833 delete_arrays(track, numVectors, D, DD);
mas01cr@204 834 }
mas01cr@204 835 // per-track reset array values
mas01cr@204 836 for(unsigned k=0; k<pointNN; k++){
mas01cr@204 837 distances[k]=0.0;
mas01cr@204 838 qIndexes[k]=~0;
mas01cr@204 839 sIndexes[k]=~0;
mas01cr@204 840 }
mas01cr@204 841 }
mas01cr@204 842
mas01cr@204 843 free(data_buffer);
mas01cr@204 844
mas01cr@204 845 gettimeofday(&tv2,NULL);
mas01cr@204 846 if(verbosity>1) {
mas01cr@204 847 std::cerr << std::endl << "processed tracks :" << processedTracks << " matched tracks: " << successfulTracks << " elapsed time:"
mas01cr@204 848 << ( tv2.tv_sec*1000 + tv2.tv_usec/1000 ) - ( tv1.tv_sec*1000+tv1.tv_usec/1000 ) << " msec" << std::endl;
mas01cr@204 849 std::cerr << "sampleCount: " << sampleCount << " sampleSum: " << sampleSum << " logSampleSum: " << logSampleSum
mas01cr@204 850 << " minSample: " << minSample << " maxSample: " << maxSample << std::endl;
mas01cr@204 851 }
mas01cr@204 852
mas01cr@204 853 if(adbQueryResponse==0){
mas01cr@204 854 if(verbosity>1) {
mas01cr@204 855 std::cerr<<std::endl;
mas01cr@204 856 }
mas01cr@204 857 // Output answer
mas01cr@204 858 // Loop over nearest neighbours
mas01cr@204 859 for(k=0; k < std::min(trackNN,successfulTracks); k++)
mas01cr@204 860 std::cout << fileTable+trackIDs[k]*O2_FILETABLESIZE << " " << trackDistances[k] << std::endl;
mas01cr@204 861 }
mas01cr@204 862 else{ // Process Web Services Query
mas01cr@204 863 int listLen = std::min(trackNN, processedTracks);
mas01cr@204 864 adbQueryResponse->result.__sizeRlist=listLen;
mas01cr@204 865 adbQueryResponse->result.__sizeDist=listLen;
mas01cr@204 866 adbQueryResponse->result.__sizeQpos=listLen;
mas01cr@204 867 adbQueryResponse->result.__sizeSpos=listLen;
mas01cr@204 868 adbQueryResponse->result.Rlist= new char*[listLen];
mas01cr@204 869 adbQueryResponse->result.Dist = new double[listLen];
mas01cr@204 870 adbQueryResponse->result.Qpos = new unsigned int[listLen];
mas01cr@204 871 adbQueryResponse->result.Spos = new unsigned int[listLen];
mas01cr@204 872 for(k=0; k<(unsigned)adbQueryResponse->result.__sizeRlist; k++){
mas01cr@204 873 adbQueryResponse->result.Rlist[k]=new char[O2_MAXFILESTR];
mas01cr@204 874 adbQueryResponse->result.Dist[k]=trackDistances[k];
mas01cr@204 875 adbQueryResponse->result.Qpos[k]=trackQIndexes[k];
mas01cr@204 876 adbQueryResponse->result.Spos[k]=trackSIndexes[k];
mas01cr@204 877 sprintf(adbQueryResponse->result.Rlist[k], "%s", fileTable+trackIDs[k]*O2_FILETABLESIZE);
mas01cr@204 878 }
mas01cr@204 879 }
mas01cr@204 880
mas01cr@204 881 // Clean up
mas01cr@204 882 if(trackOffsetTable)
mas01cr@204 883 delete[] trackOffsetTable;
mas01cr@214 884 if(query_data)
mas01cr@214 885 delete[] query_data;
mas01cr@204 886 if(qNorm)
mas01cr@204 887 delete[] qNorm;
mas01cr@204 888 if(sNorm)
mas01cr@204 889 delete[] sNorm;
mas01cr@204 890 if(qPower)
mas01cr@204 891 delete[] qPower;
mas01cr@204 892 if(sPower)
mas01cr@204 893 delete[] sPower;
mas01cr@204 894 if(D)
mas01cr@204 895 delete[] D;
mas01cr@204 896 if(DD)
mas01cr@204 897 delete[] DD;
mas01cr@204 898 if(timesdata)
mas01cr@204 899 delete[] timesdata;
mas01cr@204 900 if(querydurs)
mas01cr@204 901 delete[] querydurs;
mas01cr@204 902 if(meanDBdur)
mas01cr@204 903 delete[] meanDBdur;
mas01cr@204 904 }
mas01cr@204 905
mas01cr@204 906 // Unit norm block of features
mas01cr@204 907 void audioDB::unitNorm(double* X, unsigned dim, unsigned n, double* qNorm){
mas01cr@204 908 unsigned d;
mas01cr@204 909 double L2, *p;
mas01cr@204 910 if(verbosity>2) {
mas01cr@204 911 std::cerr << "norming " << n << " vectors...";std::cerr.flush();
mas01cr@204 912 }
mas01cr@212 913 while(n--) {
mas01cr@212 914 p = X;
mas01cr@212 915 L2 = 0.0;
mas01cr@212 916 d = dim;
mas01cr@212 917 while(d--) {
mas01cr@212 918 L2 += *p * *p;
mas01cr@204 919 p++;
mas01cr@204 920 }
mas01cr@212 921 if(qNorm) {
mas01cr@204 922 *qNorm++=L2;
mas01cr@212 923 }
mas01cr@212 924 X += dim;
mas01cr@204 925 }
mas01cr@204 926 if(verbosity>2) {
mas01cr@204 927 std::cerr << "done..." << std::endl;
mas01cr@204 928 }
mas01cr@204 929 }