Mercurial > hg > audiodb
comparison audioDB.cpp @ 155:b251c49379d1 powertable
Implement power thresholding for radius search.
(Also clean up a bit more after oneself, deleting power vectors if
appropriate)
author | mas01cr |
---|---|
date | Thu, 01 Nov 2007 14:37:08 +0000 |
parents | 97f704a32bf2 |
children | d241a22593bb |
comparison
equal
deleted
inserted
replaced
154:97f704a32bf2 | 155:b251c49379d1 |
---|---|
1692 // Copy the L2 norm values to core to avoid disk random access later on | 1692 // Copy the L2 norm values to core to avoid disk random access later on |
1693 memcpy(sNorm, l2normTable, dbVectors*sizeof(double)); | 1693 memcpy(sNorm, l2normTable, dbVectors*sizeof(double)); |
1694 double* qnPtr = qNorm; | 1694 double* qnPtr = qNorm; |
1695 double* snPtr = sNorm; | 1695 double* snPtr = sNorm; |
1696 | 1696 |
1697 double *sPower = 0, *qPower; | 1697 double *sPower = 0, *qPower = 0; |
1698 double *spPtr = 0, *qpPtr = 0; | 1698 double *spPtr = 0, *qpPtr = 0; |
1699 | 1699 |
1700 if (usingPower) { | 1700 if (usingPower) { |
1701 if (!(dbH->flags & O2_FLAG_POWER)) { | 1701 if (!(dbH->flags & O2_FLAG_POWER)) { |
1702 error("database not power-enabled", dbName); | 1702 error("database not power-enabled", dbName); |
2123 delete[] queryCopy; | 2123 delete[] queryCopy; |
2124 if(qNorm) | 2124 if(qNorm) |
2125 delete[] qNorm; | 2125 delete[] qNorm; |
2126 if(sNorm) | 2126 if(sNorm) |
2127 delete[] sNorm; | 2127 delete[] sNorm; |
2128 if(qPower) | |
2129 delete[] qPower; | |
2130 if(sPower) | |
2131 delete[] sPower; | |
2128 if(D) | 2132 if(D) |
2129 delete[] D; | 2133 delete[] D; |
2130 if(DD) | 2134 if(DD) |
2131 delete[] DD; | 2135 delete[] DD; |
2132 if(timesdata) | 2136 if(timesdata) |
2147 // we use stdout in this stub version | 2151 // we use stdout in this stub version |
2148 unsigned numVectors = (statbuf.st_size-sizeof(int))/(sizeof(double)*dbH->dim); | 2152 unsigned numVectors = (statbuf.st_size-sizeof(int))/(sizeof(double)*dbH->dim); |
2149 double* query = (double*)(indata+sizeof(int)); | 2153 double* query = (double*)(indata+sizeof(int)); |
2150 double* queryCopy = 0; | 2154 double* queryCopy = 0; |
2151 | 2155 |
2152 double qMeanL2; | |
2153 double* sMeanL2; | |
2154 | |
2155 unsigned USE_THRESH=0; | |
2156 double SILENCE_THRESH=0; | |
2157 double DIFF_THRESH=0; | |
2158 | |
2159 if(!(dbH->flags & O2_FLAG_L2NORM) ) | 2156 if(!(dbH->flags & O2_FLAG_L2NORM) ) |
2160 error("Database must be L2 normed for sequence query","use -l2norm"); | 2157 error("Database must be L2 normed for sequence query","use -l2norm"); |
2161 | 2158 |
2162 if(verbosity>1) { | 2159 if(verbosity>1) { |
2163 cerr << "performing norms ... "; cerr.flush(); | 2160 cerr << "performing norms ... "; cerr.flush(); |
2167 // Make a copy of the query | 2164 // Make a copy of the query |
2168 queryCopy = new double[numVectors*dbH->dim]; | 2165 queryCopy = new double[numVectors*dbH->dim]; |
2169 memcpy(queryCopy, query, numVectors*dbH->dim*sizeof(double)); | 2166 memcpy(queryCopy, query, numVectors*dbH->dim*sizeof(double)); |
2170 qNorm = new double[numVectors]; | 2167 qNorm = new double[numVectors]; |
2171 sNorm = new double[dbVectors]; | 2168 sNorm = new double[dbVectors]; |
2172 sMeanL2=new double[dbH->numFiles]; | 2169 assert(qNorm&&sNorm&&queryCopy&&sequenceLength); |
2173 assert(qNorm&&sNorm&&queryCopy&&sMeanL2&&sequenceLength); | |
2174 unitNorm(queryCopy, dbH->dim, numVectors, qNorm); | 2170 unitNorm(queryCopy, dbH->dim, numVectors, qNorm); |
2175 query = queryCopy; | 2171 query = queryCopy; |
2176 | 2172 |
2177 // Make norm measurements relative to sequenceLength | 2173 // Make norm measurements relative to sequenceLength |
2178 unsigned w = sequenceLength-1; | 2174 unsigned w = sequenceLength-1; |
2181 | 2177 |
2182 // Copy the L2 norm values to core to avoid disk random access later on | 2178 // Copy the L2 norm values to core to avoid disk random access later on |
2183 memcpy(sNorm, l2normTable, dbVectors*sizeof(double)); | 2179 memcpy(sNorm, l2normTable, dbVectors*sizeof(double)); |
2184 double* snPtr = sNorm; | 2180 double* snPtr = sNorm; |
2185 double* qnPtr = qNorm; | 2181 double* qnPtr = qNorm; |
2182 | |
2183 double *sPower = 0, *qPower = 0; | |
2184 double *spPtr = 0, *qpPtr = 0; | |
2185 | |
2186 if (usingPower) { | |
2187 if(!(dbH->flags & O2_FLAG_POWER)) { | |
2188 error("database not power-enabled", dbName); | |
2189 } | |
2190 sPower = new double[dbVectors]; | |
2191 spPtr = sPower; | |
2192 memcpy(sPower, powerTable, dbVectors * sizeof(double)); | |
2193 } | |
2194 | |
2186 for(i=0; i<dbH->numFiles; i++){ | 2195 for(i=0; i<dbH->numFiles; i++){ |
2187 if(trackTable[i]>=sequenceLength){ | 2196 if(trackTable[i]>=sequenceLength) { |
2188 sequence_sum(snPtr, trackTable[i], sequenceLength); | 2197 sequence_sum(snPtr, trackTable[i], sequenceLength); |
2198 if (usingPower) { | |
2199 sequence_sum(spPtr, trackTable[i], sequenceLength); | |
2200 } | |
2189 | 2201 |
2190 ps = snPtr; | 2202 ps = snPtr; |
2191 w=trackTable[i]-sequenceLength+1; | 2203 w=trackTable[i]-sequenceLength+1; |
2192 while(w--){ | 2204 while(w--){ |
2193 *ps=sqrt(*ps); | 2205 *ps=sqrt(*ps); |
2194 ps++; | 2206 ps++; |
2195 } | 2207 } |
2196 } | 2208 if (usingPower) { |
2197 snPtr+=trackTable[i]; | 2209 ps = spPtr; |
2198 } | 2210 w = trackTable[i] - sequenceLength + 1; |
2199 | 2211 while(w--) { |
2200 double* pn = sMeanL2; | 2212 *ps = *ps / sequenceLength; |
2201 w=dbH->numFiles; | 2213 ps++; |
2202 while(w--) | 2214 } |
2203 *pn++=0.0; | 2215 } |
2204 ps=sNorm; | 2216 } |
2205 unsigned processedTracks=0; | 2217 snPtr += trackTable[i]; |
2206 for(i=0; i<dbH->numFiles; i++){ | 2218 if (usingPower) { |
2207 if(trackTable[i]>sequenceLength-1){ | 2219 spPtr += trackTable[i]; |
2208 w = trackTable[i]-sequenceLength+1; | 2220 } |
2209 pn = sMeanL2+i; | 2221 } |
2210 *pn=0; | 2222 |
2211 while(w--) | |
2212 if(*ps>0) | |
2213 *pn+=*ps++; | |
2214 *pn/=trackTable[i]-sequenceLength+1; | |
2215 SILENCE_THRESH+=*pn; | |
2216 processedTracks++; | |
2217 } | |
2218 ps = sNorm + trackTable[i]; | |
2219 } | |
2220 if(verbosity>1) { | |
2221 cerr << "processedTracks: " << processedTracks << endl; | |
2222 } | |
2223 | |
2224 SILENCE_THRESH/=processedTracks; | |
2225 USE_THRESH=1; // Turn thresholding on | |
2226 DIFF_THRESH=SILENCE_THRESH; // mean shingle power | |
2227 SILENCE_THRESH/=5; // 20% of the mean shingle power is SILENCE | |
2228 if(verbosity>4) { | |
2229 cerr << "silence thresh: " << SILENCE_THRESH; | |
2230 } | |
2231 | |
2232 sequence_sum(qnPtr, numVectors, sequenceLength); | 2223 sequence_sum(qnPtr, numVectors, sequenceLength); |
2224 if (usingPower) { | |
2225 qPower = new double[numVectors]; | |
2226 qpPtr = qPower; | |
2227 if (lseek(powerfd, sizeof(int), SEEK_SET) == (off_t) -1) { | |
2228 error("error seeking to data", powerFileName, "lseek"); | |
2229 } | |
2230 int count = read(powerfd, qPower, numVectors * sizeof(double)); | |
2231 if (count == -1) { | |
2232 error("error reading data", powerFileName, "read"); | |
2233 } | |
2234 if ((unsigned) count != numVectors * sizeof(double)) { | |
2235 error("short read", powerFileName); | |
2236 } | |
2237 | |
2238 sequence_sum(qpPtr, numVectors, sequenceLength); | |
2239 ps = qpPtr; | |
2240 w = numVectors - sequenceLength + 1; | |
2241 while(w--) { | |
2242 *ps = *ps / sequenceLength; | |
2243 ps++; | |
2244 } | |
2245 } | |
2233 | 2246 |
2234 ps = qnPtr; | 2247 ps = qnPtr; |
2235 qMeanL2 = 0; | 2248 w = numVectors - sequenceLength + 1; |
2236 w=numVectors-sequenceLength+1; | |
2237 while(w--){ | 2249 while(w--){ |
2238 *ps=sqrt(*ps); | 2250 *ps=sqrt(*ps); |
2239 qMeanL2+=*ps++; | 2251 } |
2240 } | |
2241 qMeanL2 /= numVectors-sequenceLength+1; | |
2242 | 2252 |
2243 if(verbosity>1) { | 2253 if(verbosity>1) { |
2244 cerr << "done." << endl; | 2254 cerr << "done." << endl; |
2245 } | 2255 } |
2246 | 2256 |
2333 assert(D); | 2343 assert(D); |
2334 DD = new double*[numVectors]; | 2344 DD = new double*[numVectors]; |
2335 assert(DD); | 2345 assert(DD); |
2336 | 2346 |
2337 gettimeofday(&tv1, NULL); | 2347 gettimeofday(&tv1, NULL); |
2338 processedTracks=0; | 2348 unsigned processedTracks = 0; |
2339 unsigned successfulTracks=0; | 2349 unsigned successfulTracks=0; |
2340 | 2350 |
2341 double* qp; | 2351 double* qp; |
2342 double* sp; | 2352 double* sp; |
2343 double* dp; | 2353 double* dp; |
2451 | 2461 |
2452 // Search for minimum distance by shingles (concatenated vectors) | 2462 // Search for minimum distance by shingles (concatenated vectors) |
2453 for(j=0;j<=numVectors-wL;j+=HOP_SIZE) | 2463 for(j=0;j<=numVectors-wL;j+=HOP_SIZE) |
2454 for(k=0;k<=trackTable[track]-wL;k+=HOP_SIZE){ | 2464 for(k=0;k<=trackTable[track]-wL;k+=HOP_SIZE){ |
2455 thisDist=2-(2/(qnPtr[j]*sNorm[trackIndexOffset+k]))*DD[j][k]; | 2465 thisDist=2-(2/(qnPtr[j]*sNorm[trackIndexOffset+k]))*DD[j][k]; |
2456 if(verbosity>10) { | 2466 if(verbosity>9) { |
2457 cerr << thisDist << " " << qnPtr[j] << " " << sNorm[trackIndexOffset+k] << endl; | 2467 cerr << thisDist << " " << qnPtr[j] << " " << sNorm[trackIndexOffset+k] << endl; |
2458 } | 2468 } |
2459 // Gather chi^2 statistics | 2469 // Gather chi^2 statistics |
2460 if(thisDist<minSample) | 2470 if(thisDist<minSample) |
2461 minSample=thisDist; | 2471 minSample=thisDist; |
2467 logSampleSum+=log(thisDist); | 2477 logSampleSum+=log(thisDist); |
2468 } | 2478 } |
2469 | 2479 |
2470 // diffL2 = fabs(qnPtr[j] - sNorm[trackIndexOffset+k]); | 2480 // diffL2 = fabs(qnPtr[j] - sNorm[trackIndexOffset+k]); |
2471 // Power test | 2481 // Power test |
2472 if(!USE_THRESH || | 2482 if (usingPower) { |
2473 // Threshold on mean L2 of Q and S sequences | 2483 if (!(powers_acceptable(qpPtr[j], sPower[trackIndexOffset + k]))) { |
2474 (USE_THRESH && qnPtr[j]>SILENCE_THRESH && sNorm[trackIndexOffset+k]>SILENCE_THRESH && | 2484 thisDist = 1000000.0; |
2475 // Are both query and target windows above mean energy? | 2485 } |
2476 (qnPtr[j]>qMeanL2*.25 && sNorm[trackIndexOffset+k]>sMeanL2[track]*.25))) // && diffL2 < DIFF_THRESH ))) | 2486 } |
2477 thisDist=thisDist; // Computed above | 2487 |
2478 else | |
2479 thisDist=1000000.0; | |
2480 if(thisDist>=0 && thisDist<=radius){ | 2488 if(thisDist>=0 && thisDist<=radius){ |
2481 distances[0]++; // increment count | 2489 distances[0]++; // increment count |
2482 break; // only need one track point per query point | 2490 break; // only need one track point per query point |
2483 } | 2491 } |
2484 } | 2492 } |
2577 delete[] queryCopy; | 2585 delete[] queryCopy; |
2578 if(qNorm) | 2586 if(qNorm) |
2579 delete[] qNorm; | 2587 delete[] qNorm; |
2580 if(sNorm) | 2588 if(sNorm) |
2581 delete[] sNorm; | 2589 delete[] sNorm; |
2582 if(sMeanL2) | 2590 if(qPower) |
2583 delete[] sMeanL2; | 2591 delete[] qPower; |
2592 if(sPower) | |
2593 delete[] sPower; | |
2584 if(D) | 2594 if(D) |
2585 delete[] D; | 2595 delete[] D; |
2586 if(DD) | 2596 if(DD) |
2587 delete[] DD; | 2597 delete[] DD; |
2588 if(timesdata) | 2598 if(timesdata) |
2589 delete[] timesdata; | 2599 delete[] timesdata; |
2590 if(meanDBdur) | 2600 if(meanDBdur) |
2591 delete[] meanDBdur; | 2601 delete[] meanDBdur; |
2592 | |
2593 | |
2594 } | 2602 } |
2595 | 2603 |
2596 // Unit norm block of features | 2604 // Unit norm block of features |
2597 void audioDB::unitNorm(double* X, unsigned dim, unsigned n, double* qNorm){ | 2605 void audioDB::unitNorm(double* X, unsigned dim, unsigned n, double* qNorm){ |
2598 unsigned d; | 2606 unsigned d; |