comparison reporter.h @ 277:abfb26e08d9c audiodb-debian

Merge trunk changes -r326:386 into audiodb-debian branch. Plus new debian/changelog version. (Should have used an epoch really, but couldn't be bothered; TODO: work out a sane version numbering policy).
author mas01cr
date Tue, 01 Jul 2008 09:12:40 +0000
parents cbf51690c78c
children
comparison
equal deleted inserted replaced
246:cbf51690c78c 277:abfb26e08d9c
1 #include <utility> 1 #include <utility>
2 #include <queue> 2 #include <queue>
3 #include <deque>
3 #include <set> 4 #include <set>
4 #include <functional> 5 #include <functional>
5 6
6 typedef struct nnresult { 7 typedef struct nnresult {
7 unsigned int trackID; 8 unsigned int trackID;
86 std::vector<NNresult>::reverse_iterator rit; 87 std::vector<NNresult>::reverse_iterator rit;
87 88
88 if(adbQueryResponse==0) { 89 if(adbQueryResponse==0) {
89 for(rit = v.rbegin(); rit < v.rend(); rit++) { 90 for(rit = v.rbegin(); rit < v.rend(); rit++) {
90 r = *rit; 91 r = *rit;
91 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; 92 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
92 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; 93 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
93 } 94 }
94 } else { 95 } else {
95 adbQueryResponse->result.__sizeRlist=size; 96 adbQueryResponse->result.__sizeRlist=size;
96 adbQueryResponse->result.__sizeDist=size; 97 adbQueryResponse->result.__sizeDist=size;
105 r = *rit; 106 r = *rit;
106 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; 107 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
107 adbQueryResponse->result.Dist[k] = r.dist; 108 adbQueryResponse->result.Dist[k] = r.dist;
108 adbQueryResponse->result.Qpos[k] = r.qpos; 109 adbQueryResponse->result.Qpos[k] = r.qpos;
109 adbQueryResponse->result.Spos[k] = r.spos; 110 adbQueryResponse->result.Spos[k] = r.spos;
110 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); 111 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
111 } 112 }
112 } 113 }
113 } 114 }
114 115
115 template <class T> class trackAveragingReporter : public Reporter { 116 template <class T> class trackAveragingReporter : public Reporter {
116 public: 117 public:
117 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); 118 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
118 ~trackAveragingReporter(); 119 ~trackAveragingReporter();
119 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); 120 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
120 void report(char *fileTable, adb__queryResponse *adbQueryResponse); 121 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
121 private: 122 protected:
122 unsigned int pointNN; 123 unsigned int pointNN;
123 unsigned int trackNN; 124 unsigned int trackNN;
124 unsigned int numFiles; 125 unsigned int numFiles;
125 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues; 126 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues;
126 }; 127 };
187 std::vector<NNresult>::reverse_iterator rit; 188 std::vector<NNresult>::reverse_iterator rit;
188 189
189 if(adbQueryResponse==0) { 190 if(adbQueryResponse==0) {
190 for(rit = v.rbegin(); rit < v.rend(); rit++) { 191 for(rit = v.rbegin(); rit < v.rend(); rit++) {
191 r = *rit; 192 r = *rit;
192 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; 193 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
193 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; 194 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
194 } 195 }
195 } else { 196 } else {
196 adbQueryResponse->result.__sizeRlist=size; 197 adbQueryResponse->result.__sizeRlist=size;
197 adbQueryResponse->result.__sizeDist=size; 198 adbQueryResponse->result.__sizeDist=size;
206 r = *rit; 207 r = *rit;
207 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; 208 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
208 adbQueryResponse->result.Dist[k] = r.dist; 209 adbQueryResponse->result.Dist[k] = r.dist;
209 adbQueryResponse->result.Qpos[k] = r.qpos; 210 adbQueryResponse->result.Qpos[k] = r.qpos;
210 adbQueryResponse->result.Spos[k] = r.spos; 211 adbQueryResponse->result.Spos[k] = r.spos;
211 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); 212 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
212 } 213 }
213 } 214 }
214 } 215 }
215 216
217 // track Sequence Query Radius Reporter
218 // only return tracks and retrieved point counts
216 class trackSequenceQueryRadReporter : public Reporter { 219 class trackSequenceQueryRadReporter : public Reporter {
217 public: 220 public:
218 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles); 221 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles);
219 ~trackSequenceQueryRadReporter(); 222 ~trackSequenceQueryRadReporter();
220 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); 223 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
221 void report(char *fileTable, adb__queryResponse *adbQueryResponse); 224 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
222 private: 225 protected:
223 unsigned int trackNN; 226 unsigned int trackNN;
224 unsigned int numFiles; 227 unsigned int numFiles;
225 std::set<std::pair<unsigned int, unsigned int> > *set; 228 std::set<std::pair<unsigned int, unsigned int> > *set;
226 unsigned int *count; 229 unsigned int *count;
227 }; 230 };
240 delete [] count; 243 delete [] count;
241 } 244 }
242 245
243 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { 246 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
244 std::set<std::pair<unsigned int, unsigned int> >::iterator it; 247 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
245 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); 248 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once
246 it = set->find(pair); 249 it = set->find(pair);
247 if (it == set->end()) { 250 if (it == set->end()) {
248 set->insert(pair); 251 set->insert(pair);
249 count[trackID]++; 252 count[trackID]++; // only count if <tackID,qpos> pair is unique
250 } 253 }
251 } 254 }
252 255
253 void trackSequenceQueryRadReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { 256 void trackSequenceQueryRadReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
254 std::priority_queue < Radresult > result; 257 std::priority_queue < Radresult > result;
277 std::vector<Radresult>::reverse_iterator rit; 280 std::vector<Radresult>::reverse_iterator rit;
278 281
279 if(adbQueryResponse==0) { 282 if(adbQueryResponse==0) {
280 for(rit = v.rbegin(); rit < v.rend(); rit++) { 283 for(rit = v.rbegin(); rit < v.rend(); rit++) {
281 r = *rit; 284 r = *rit;
282 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " " << r.count << std::endl; 285 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.count << std::endl;
283 } 286 }
284 } else { 287 } else {
285 // FIXME 288 // FIXME
286 } 289 }
287 } 290 }
291
292 // Another type of trackAveragingReporter that reports all pointNN nearest neighbours
293 template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> {
294 protected:
295 using trackAveragingReporter<T>::numFiles;
296 using trackAveragingReporter<T>::queues;
297 using trackAveragingReporter<T>::trackNN;
298 using trackAveragingReporter<T>::pointNN;
299 public:
300 trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
301 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
302 };
303
304 template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
305 :trackAveragingReporter<T>(pointNN, trackNN, numFiles){}
306
307 template <class T> void trackSequenceQueryNNReporter<T>::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
308 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
309 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
310
311 for (int i = numFiles-1; i >= 0; i--) {
312 unsigned int size = queues[i].size();
313 if (size > 0) {
314 NNresult r;
315 double dist = 0;
316 NNresult oldr = queues[i].top();
317 for (unsigned int j = 0; j < size; j++) {
318 r = queues[i].top();
319 dist += r.dist;
320 point_queues[i].push(r);
321 queues[i].pop();
322 if (r.dist == oldr.dist) {
323 r.qpos = oldr.qpos;
324 r.spos = oldr.spos;
325 } else {
326 oldr = r;
327 }
328 }
329 dist /= size;
330 r.dist = dist; // trackID, qpos and spos are magically right already.
331 result.push(r);
332 if (result.size() > trackNN) {
333 result.pop();
334 }
335 }
336 }
337
338 NNresult r;
339 std::vector<NNresult> v;
340 unsigned int size = result.size();
341 for(unsigned int k = 0; k < size; k++) {
342 r = result.top();
343 v.push_back(r);
344 result.pop();
345 }
346 std::vector<NNresult>::reverse_iterator rit;
347 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
348
349 if(adbQueryResponse==0) {
350 for(rit = v.rbegin(); rit < v.rend(); rit++) {
351 r = *rit;
352 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.dist << std::endl;
353 unsigned int qsize = point_queues[r.trackID].size();
354 // Reverse the order of the points stored in point_queues
355 for(unsigned int k=0; k < qsize; k++){
356 point_queue.push( point_queues[r.trackID].top() );
357 point_queues[r.trackID].pop();
358 }
359
360 for(unsigned int k = 0; k < qsize; k++) {
361 NNresult rk = point_queue.top();
362 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
363 point_queue.pop();
364 }
365 }
366 } else {
367 adbQueryResponse->result.__sizeRlist=size;
368 adbQueryResponse->result.__sizeDist=size;
369 adbQueryResponse->result.__sizeQpos=size;
370 adbQueryResponse->result.__sizeSpos=size;
371 adbQueryResponse->result.Rlist= new char*[size];
372 adbQueryResponse->result.Dist = new double[size];
373 adbQueryResponse->result.Qpos = new unsigned int[size];
374 adbQueryResponse->result.Spos = new unsigned int[size];
375 unsigned int k = 0;
376 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
377 r = *rit;
378 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
379 adbQueryResponse->result.Dist[k] = r.dist;
380 adbQueryResponse->result.Qpos[k] = r.qpos;
381 adbQueryResponse->result.Spos[k] = r.spos;
382 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
383 }
384 }
385 // clean up
386 delete[] point_queues;
387 }
388
389
390 // track Sequence Query Radius NN Reporter
391 // retrieve tracks ordered by query-point matches (one per track per query point)
392 //
393 // as well as sorted n-NN points per retrieved track
394 class trackSequenceQueryRadNNReporter : public Reporter {
395 public:
396 trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
397 ~trackSequenceQueryRadNNReporter();
398 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
399 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
400 protected:
401 unsigned int pointNN;
402 unsigned int trackNN;
403 unsigned int numFiles;
404 std::set< NNresult > *set;
405 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues;
406 unsigned int *count;
407 };
408
409 trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
410 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
411 // Where to count Radius track matches (one-to-one)
412 set = new std::set< NNresult >;
413 // Where to insert individual point matches (one-to-many)
414 point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
415
416 count = new unsigned int[numFiles];
417 for (unsigned i = 0; i < numFiles; i++) {
418 count[i] = 0;
419 }
420 }
421
422 trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() {
423 delete set;
424 delete [] count;
425 }
426
427 void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
428 std::set< NNresult >::iterator it;
429 NNresult r;
430 r.trackID = trackID;
431 r.qpos = qpos;
432 r.dist = dist;
433 r.spos = spos;
434
435 // Record all matching points (within radius)
436 if (!isnan(dist)) {
437 point_queues[trackID].push(r);
438 if(point_queues[trackID].size() > pointNN)
439 point_queues[trackID].pop();
440 }
441
442 // Record counts of <trackID,qpos> pairs
443 it = set->find(r);
444 if (it == set->end()) {
445 set->insert(r);
446 count[trackID]++;
447 }
448 }
449
450 void trackSequenceQueryRadNNReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
451 std::priority_queue < Radresult > result;
452 // KLUDGE: doing this backwards in an attempt to get the same
453 // tiebreak behaviour as before.
454 for (int i = numFiles-1; i >= 0; i--) {
455 Radresult r;
456 r.trackID = i;
457 r.count = count[i];
458 if(r.count > 0) {
459 result.push(r);
460 if (result.size() > trackNN) {
461 result.pop();
462 }
463 }
464 }
465
466 Radresult r;
467 std::vector<Radresult> v;
468 unsigned int size = result.size();
469 for(unsigned int k = 0; k < size; k++) {
470 r = result.top();
471 v.push_back(r);
472 result.pop();
473 }
474
475
476 // Traverse tracks in descending order of count cardinality
477 std::vector<Radresult>::reverse_iterator rit;
478 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
479
480 if(adbQueryResponse==0) {
481 for(rit = v.rbegin(); rit < v.rend(); rit++) {
482 r = *rit;
483 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.count << std::endl;
484
485 // Reverse the order of the points stored in point_queues
486 unsigned int qsize=point_queues[r.trackID].size();
487 for(unsigned int k=0; k < qsize; k++){
488 point_queue.push(point_queues[r.trackID].top());
489 point_queues[r.trackID].pop();
490 }
491
492 for(unsigned int k=0; k < qsize; k++){
493 NNresult rk = point_queue.top();
494 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
495 point_queue.pop();
496 }
497 }
498 } else {
499 // FIXME
500 }
501 delete[] point_queues;
502 }
503
504
505 /********** ONE-TO-ONE REPORTERS *****************/
506
507 // track Sequence Query Radius NN Reporter One-to-One
508 // for each query point find the single best matching target point in all database
509 // report qpos, spos and trackID
510 class trackSequenceQueryRadNNReporterOneToOne : public Reporter {
511 public:
512 trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
513 ~trackSequenceQueryRadNNReporterOneToOne();
514 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
515 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
516 protected:
517 unsigned int pointNN;
518 unsigned int trackNN;
519 unsigned int numFiles;
520 std::set< NNresult > *set;
521 std::vector< NNresult> *point_queue;
522 unsigned int *count;
523
524 };
525
526 trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
527 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
528 // Where to count Radius track matches (one-to-one)
529 set = new std::set< NNresult >;
530 // Where to insert individual point matches (one-to-many)
531 point_queue = new std::vector< NNresult >;
532
533 count = new unsigned int[numFiles];
534 for (unsigned i = 0; i < numFiles; i++) {
535 count[i] = 0;
536 }
537 }
538
539 trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() {
540 delete set;
541 delete [] count;
542 }
543
544 void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
545 std::set< NNresult >::iterator it;
546 NNresult r;
547
548 r.qpos = qpos;
549 r.trackID = trackID;
550 r.spos = spos;
551 r.dist = dist;
552
553 if(point_queue->size() < r.qpos + 1){
554 point_queue->resize( r.qpos + 1 );
555 (*point_queue)[r.qpos].dist = 1e6;
556 }
557
558 if (r.dist < (*point_queue)[r.qpos].dist)
559 (*point_queue)[r.qpos] = r;
560
561 }
562
563 void trackSequenceQueryRadNNReporterOneToOne::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
564 if(adbQueryResponse==0) {
565 std::vector< NNresult >::iterator vit;
566 NNresult rk;
567 for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){
568 rk = *vit;
569 std::cout << rk.dist << " "
570 << rk.qpos << " "
571 << rk.spos << " "
572 << fileTable + rk.trackID*O2_FILETABLE_ENTRY_SIZE
573 << std::endl;
574 }
575 } else {
576 // FIXME
577 }
578 }