Mercurial > hg > audiodb
diff 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 |
line wrap: on
line diff
--- a/reporter.h Mon Dec 17 16:44:37 2007 +0000 +++ b/reporter.h Tue Jul 01 09:12:40 2008 +0000 @@ -1,5 +1,6 @@ #include <utility> #include <queue> +#include <deque> #include <set> #include <functional> @@ -88,7 +89,7 @@ if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; - std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; + std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " "; std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; } } else { @@ -107,7 +108,7 @@ adbQueryResponse->result.Dist[k] = r.dist; adbQueryResponse->result.Qpos[k] = r.qpos; adbQueryResponse->result.Spos[k] = r.spos; - snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); + snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE); } } } @@ -118,7 +119,7 @@ ~trackAveragingReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(char *fileTable, adb__queryResponse *adbQueryResponse); - private: + protected: unsigned int pointNN; unsigned int trackNN; unsigned int numFiles; @@ -189,7 +190,7 @@ if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; - std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; + std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " "; std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; } } else { @@ -208,18 +209,20 @@ adbQueryResponse->result.Dist[k] = r.dist; adbQueryResponse->result.Qpos[k] = r.qpos; adbQueryResponse->result.Spos[k] = r.spos; - snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); + snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE); } } } +// track Sequence Query Radius Reporter +// only return tracks and retrieved point counts class trackSequenceQueryRadReporter : public Reporter { public: trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles); ~trackSequenceQueryRadReporter(); void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); void report(char *fileTable, adb__queryResponse *adbQueryResponse); -private: + protected: unsigned int trackNN; unsigned int numFiles; std::set<std::pair<unsigned int, unsigned int> > *set; @@ -242,11 +245,11 @@ void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { std::set<std::pair<unsigned int, unsigned int> >::iterator it; - std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); + std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once it = set->find(pair); if (it == set->end()) { set->insert(pair); - count[trackID]++; + count[trackID]++; // only count if <tackID,qpos> pair is unique } } @@ -279,9 +282,297 @@ if(adbQueryResponse==0) { for(rit = v.rbegin(); rit < v.rend(); rit++) { r = *rit; - std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " " << r.count << std::endl; + std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.count << std::endl; } } else { // FIXME } } + +// Another type of trackAveragingReporter that reports all pointNN nearest neighbours +template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> { + protected: + using trackAveragingReporter<T>::numFiles; + using trackAveragingReporter<T>::queues; + using trackAveragingReporter<T>::trackNN; + using trackAveragingReporter<T>::pointNN; + public: + trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); + void report(char *fileTable, adb__queryResponse *adbQueryResponse); +}; + +template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles) +:trackAveragingReporter<T>(pointNN, trackNN, numFiles){} + +template <class T> void trackSequenceQueryNNReporter<T>::report(char *fileTable, adb__queryResponse *adbQueryResponse) { + std::priority_queue < NNresult, std::vector< NNresult>, T> result; + std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles]; + + for (int i = numFiles-1; i >= 0; i--) { + unsigned int size = queues[i].size(); + if (size > 0) { + NNresult r; + double dist = 0; + NNresult oldr = queues[i].top(); + for (unsigned int j = 0; j < size; j++) { + r = queues[i].top(); + dist += r.dist; + point_queues[i].push(r); + queues[i].pop(); + if (r.dist == oldr.dist) { + r.qpos = oldr.qpos; + r.spos = oldr.spos; + } else { + oldr = r; + } + } + dist /= size; + r.dist = dist; // trackID, qpos and spos are magically right already. + result.push(r); + if (result.size() > trackNN) { + result.pop(); + } + } + } + + NNresult r; + std::vector<NNresult> v; + unsigned int size = result.size(); + for(unsigned int k = 0; k < size; k++) { + r = result.top(); + v.push_back(r); + result.pop(); + } + std::vector<NNresult>::reverse_iterator rit; + std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue; + + if(adbQueryResponse==0) { + for(rit = v.rbegin(); rit < v.rend(); rit++) { + r = *rit; + std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.dist << std::endl; + unsigned int qsize = point_queues[r.trackID].size(); + // Reverse the order of the points stored in point_queues + for(unsigned int k=0; k < qsize; k++){ + point_queue.push( point_queues[r.trackID].top() ); + point_queues[r.trackID].pop(); + } + + for(unsigned int k = 0; k < qsize; k++) { + NNresult rk = point_queue.top(); + std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl; + point_queue.pop(); + } + } + } else { + adbQueryResponse->result.__sizeRlist=size; + adbQueryResponse->result.__sizeDist=size; + adbQueryResponse->result.__sizeQpos=size; + adbQueryResponse->result.__sizeSpos=size; + adbQueryResponse->result.Rlist= new char*[size]; + adbQueryResponse->result.Dist = new double[size]; + adbQueryResponse->result.Qpos = new unsigned int[size]; + adbQueryResponse->result.Spos = new unsigned int[size]; + unsigned int k = 0; + for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { + r = *rit; + adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; + adbQueryResponse->result.Dist[k] = r.dist; + adbQueryResponse->result.Qpos[k] = r.qpos; + adbQueryResponse->result.Spos[k] = r.spos; + snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE); + } + } + // clean up + delete[] point_queues; +} + + +// track Sequence Query Radius NN Reporter +// retrieve tracks ordered by query-point matches (one per track per query point) +// +// as well as sorted n-NN points per retrieved track +class trackSequenceQueryRadNNReporter : public Reporter { +public: + trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); + ~trackSequenceQueryRadNNReporter(); + void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); + void report(char *fileTable, adb__queryResponse *adbQueryResponse); + protected: + unsigned int pointNN; + unsigned int trackNN; + unsigned int numFiles; + std::set< NNresult > *set; + std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues; + unsigned int *count; +}; + +trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles): +pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { + // Where to count Radius track matches (one-to-one) + set = new std::set< NNresult >; + // Where to insert individual point matches (one-to-many) + point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles]; + + count = new unsigned int[numFiles]; + for (unsigned i = 0; i < numFiles; i++) { + count[i] = 0; + } +} + +trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() { + delete set; + delete [] count; +} + +void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { + std::set< NNresult >::iterator it; + NNresult r; + r.trackID = trackID; + r.qpos = qpos; + r.dist = dist; + r.spos = spos; + + // Record all matching points (within radius) + if (!isnan(dist)) { + point_queues[trackID].push(r); + if(point_queues[trackID].size() > pointNN) + point_queues[trackID].pop(); + } + + // Record counts of <trackID,qpos> pairs + it = set->find(r); + if (it == set->end()) { + set->insert(r); + count[trackID]++; + } +} + +void trackSequenceQueryRadNNReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { + std::priority_queue < Radresult > result; + // KLUDGE: doing this backwards in an attempt to get the same + // tiebreak behaviour as before. + for (int i = numFiles-1; i >= 0; i--) { + Radresult r; + r.trackID = i; + r.count = count[i]; + if(r.count > 0) { + result.push(r); + if (result.size() > trackNN) { + result.pop(); + } + } + } + + Radresult r; + std::vector<Radresult> v; + unsigned int size = result.size(); + for(unsigned int k = 0; k < size; k++) { + r = result.top(); + v.push_back(r); + result.pop(); + } + + + // Traverse tracks in descending order of count cardinality + std::vector<Radresult>::reverse_iterator rit; + std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue; + + if(adbQueryResponse==0) { + for(rit = v.rbegin(); rit < v.rend(); rit++) { + r = *rit; + std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " " << r.count << std::endl; + + // Reverse the order of the points stored in point_queues + unsigned int qsize=point_queues[r.trackID].size(); + for(unsigned int k=0; k < qsize; k++){ + point_queue.push(point_queues[r.trackID].top()); + point_queues[r.trackID].pop(); + } + + for(unsigned int k=0; k < qsize; k++){ + NNresult rk = point_queue.top(); + std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl; + point_queue.pop(); + } + } + } else { + // FIXME + } + delete[] point_queues; +} + + +/********** ONE-TO-ONE REPORTERS *****************/ + +// track Sequence Query Radius NN Reporter One-to-One +// for each query point find the single best matching target point in all database +// report qpos, spos and trackID +class trackSequenceQueryRadNNReporterOneToOne : public Reporter { +public: + trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); + ~trackSequenceQueryRadNNReporterOneToOne(); + void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); + void report(char *fileTable, adb__queryResponse *adbQueryResponse); + protected: + unsigned int pointNN; + unsigned int trackNN; + unsigned int numFiles; + std::set< NNresult > *set; + std::vector< NNresult> *point_queue; + unsigned int *count; + +}; + +trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles): +pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { + // Where to count Radius track matches (one-to-one) + set = new std::set< NNresult >; + // Where to insert individual point matches (one-to-many) + point_queue = new std::vector< NNresult >; + + count = new unsigned int[numFiles]; + for (unsigned i = 0; i < numFiles; i++) { + count[i] = 0; + } +} + +trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() { + delete set; + delete [] count; +} + +void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { + std::set< NNresult >::iterator it; + NNresult r; + + r.qpos = qpos; + r.trackID = trackID; + r.spos = spos; + r.dist = dist; + + if(point_queue->size() < r.qpos + 1){ + point_queue->resize( r.qpos + 1 ); + (*point_queue)[r.qpos].dist = 1e6; + } + + if (r.dist < (*point_queue)[r.qpos].dist) + (*point_queue)[r.qpos] = r; + +} + +void trackSequenceQueryRadNNReporterOneToOne::report(char *fileTable, adb__queryResponse *adbQueryResponse) { + if(adbQueryResponse==0) { + std::vector< NNresult >::iterator vit; + NNresult rk; + for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){ + rk = *vit; + std::cout << rk.dist << " " + << rk.qpos << " " + << rk.spos << " " + << fileTable + rk.trackID*O2_FILETABLE_ENTRY_SIZE + << std::endl; + } + } else { + // FIXME + } +}