Mercurial > hg > audiodb
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 } |