comparison src/Matcher.cpp @ 72:c3c50d5e05b7 refactors

Pull up Matcher set/get to public API, use only public API in Finder
author Chris Cannam
date Wed, 19 Nov 2014 10:18:19 +0000
parents cba231851957
children b9aa663a607b
comparison
equal deleted inserted replaced
71:cba231851957 72:c3c50d5e05b7
19 #include <iostream> 19 #include <iostream>
20 20
21 #include <cstdlib> 21 #include <cstdlib>
22 #include <cassert> 22 #include <cassert>
23 23
24 using namespace std;
25
24 //#define DEBUG_MATCHER 1 26 //#define DEBUG_MATCHER 1
25 27
26 Matcher::Matcher(Parameters parameters, 28 Matcher::Matcher(Parameters parameters,
27 FeatureExtractor::Parameters feParams, 29 FeatureExtractor::Parameters feParams,
28 Matcher *p) : 30 Matcher *p) :
123 125
124 return feature; 126 return feature;
125 } 127 }
126 128
127 void 129 void
128 Matcher::consumeFeatureVector(std::vector<double> feature) 130 Matcher::consumeFeatureVector(vector<double> feature)
129 { 131 {
130 if (!m_initialised) init(); 132 if (!m_initialised) init();
131 int frameIndex = m_frameCount % m_blockSize; 133 int frameIndex = m_frameCount % m_blockSize;
132 m_frames[frameIndex] = feature; 134 m_frames[frameIndex] = feature;
133 calcAdvance(); 135 calcAdvance();
202 204
203 if ((m_frameCount == 0) && (index == 0)) // first element 205 if ((m_frameCount == 0) && (index == 0)) // first element
204 updateValue(0, 0, AdvanceNone, 0, dMN); 206 updateValue(0, 0, AdvanceNone, 0, dMN);
205 else if (m_frameCount == 0) // first row 207 else if (m_frameCount == 0) // first row
206 updateValue(0, index, AdvanceOther, 208 updateValue(0, index, AdvanceOther,
207 getValue(0, index-1), dMN); 209 getPathCost(0, index-1), dMN);
208 else if (index == 0) // first column 210 else if (index == 0) // first column
209 updateValue(m_frameCount, index, AdvanceThis, 211 updateValue(m_frameCount, index, AdvanceThis,
210 getValue(m_frameCount - 1, 0), dMN); 212 getPathCost(m_frameCount - 1, 0), dMN);
211 else if (index == m_otherMatcher->m_frameCount - m_blockSize) { 213 else if (index == m_otherMatcher->m_frameCount - m_blockSize) {
212 // missing value(s) due to cutoff 214 // missing value(s) due to cutoff
213 // - no previous value in current row (resp. column) 215 // - no previous value in current row (resp. column)
214 // - no diagonal value if prev. dir. == curr. dirn 216 // - no diagonal value if prev. dir. == curr. dirn
215 double min2 = getValue(m_frameCount - 1, index); 217 double min2 = getPathCost(m_frameCount - 1, index);
216 // if ((m_firstPM && (first[m_frameCount - 1] == index)) || 218 // if ((m_firstPM && (first[m_frameCount - 1] == index)) ||
217 // (!m_firstPM && (m_last[index-1] < m_frameCount))) 219 // (!m_firstPM && (m_last[index-1] < m_frameCount)))
218 if (m_first[m_frameCount - 1] == index) 220 if (m_first[m_frameCount - 1] == index)
219 updateValue(m_frameCount, index, AdvanceThis, min2, dMN); 221 updateValue(m_frameCount, index, AdvanceThis, min2, dMN);
220 else { 222 else {
221 double min1 = getValue(m_frameCount - 1, index - 1); 223 double min1 = getPathCost(m_frameCount - 1, index - 1);
222 if (min1 + dMN <= min2) 224 if (min1 + dMN <= min2)
223 updateValue(m_frameCount, index, AdvanceBoth, min1,dMN); 225 updateValue(m_frameCount, index, AdvanceBoth, min1,dMN);
224 else 226 else
225 updateValue(m_frameCount, index, AdvanceThis, min2,dMN); 227 updateValue(m_frameCount, index, AdvanceThis, min2,dMN);
226 } 228 }
227 } else { 229 } else {
228 double min1 = getValue(m_frameCount, index-1); 230 double min1 = getPathCost(m_frameCount, index-1);
229 double min2 = getValue(m_frameCount - 1, index); 231 double min2 = getPathCost(m_frameCount - 1, index);
230 double min3 = getValue(m_frameCount - 1, index-1); 232 double min3 = getPathCost(m_frameCount - 1, index-1);
231 if (min1 <= min2) { 233 if (min1 <= min2) {
232 if (min3 + dMN <= min1) 234 if (min3 + dMN <= min1)
233 updateValue(m_frameCount, index, AdvanceBoth, min3,dMN); 235 updateValue(m_frameCount, index, AdvanceBoth, min3,dMN);
234 else 236 else
235 updateValue(m_frameCount, index, AdvanceOther,min1,dMN); 237 updateValue(m_frameCount, index, AdvanceOther,min1,dMN);
274 } else { 276 } else {
275 return m_otherMatcher->isAvailable(j, i); 277 return m_otherMatcher->isAvailable(j, i);
276 } 278 }
277 } 279 }
278 280
281 pair<int, int>
282 Matcher::getColRange(int i)
283 {
284 if (i < 0 || i >= int(m_first.size())) {
285 cerr << "ERROR: Matcher::getColRange(" << i << "): Index out of range"
286 << endl;
287 throw "Index out of range";
288 } else {
289 return pair<int, int>(m_first[i], m_last[i]);
290 }
291 }
292
293 pair<int, int>
294 Matcher::getRowRange(int i)
295 {
296 return m_otherMatcher->getColRange(i);
297 }
298
299 float
300 Matcher::getDistance(int i, int j)
301 {
302 if (m_firstPM) {
303 if (!isInRange(i, j)) {
304 cerr << "ERROR: Matcher::getDistance(" << i << ", " << j << "): "
305 << "Location is not in range" << endl;
306 throw "Distance not available";
307 }
308 float dist = m_distance[i][j - m_first[i]];
309 if (dist < 0) {
310 cerr << "ERROR: Matcher::getDistance(" << i << ", " << j << "): "
311 << "Location is in range, but distance ("
312 << dist << ") is invalid or has not been set" << endl;
313 throw "Distance not available";
314 }
315 return dist;
316 } else {
317 return m_otherMatcher->getDistance(j, i);
318 }
319 }
320
321 void
322 Matcher::setDistance(int i, int j, float distance)
323 {
324 if (m_firstPM) {
325 if (!isInRange(i, j)) {
326 cerr << "ERROR: Matcher::setDistance(" << i << ", " << j << ", "
327 << distance << "): Location is out of range" << endl;
328 throw "Indices out of range";
329 }
330 m_distance[i][j - m_first[i]] = distance;
331 } else {
332 m_otherMatcher->setDistance(j, i, distance);
333 }
334 }
335
279 double 336 double
280 Matcher::getValue(int i, int j) 337 Matcher::getPathCost(int i, int j)
281 { 338 {
282 if (m_firstPM) { 339 if (m_firstPM) {
283 if (!isAvailable(i, j)) { 340 if (!isAvailable(i, j)) {
284 if (!isInRange(i, j)) { 341 if (!isInRange(i, j)) {
285 cerr << "ERROR: Matcher::getValue(" << i << ", " << j << "): " 342 cerr << "ERROR: Matcher::getPathCost(" << i << ", " << j << "): "
286 << "Location is not in range" << endl; 343 << "Location is not in range" << endl;
287 } else { 344 } else {
288 cerr << "ERROR: Matcher::getValue(" << i << ", " << j << "): " 345 cerr << "ERROR: Matcher::getPathCost(" << i << ", " << j << "): "
289 << "Location is in range, but value (" 346 << "Location is in range, but pathCost ("
290 << m_bestPathCost[i][j - m_first[i]] 347 << m_bestPathCost[i][j - m_first[i]]
291 << ") is invalid or has not been set" << endl; 348 << ") is invalid or has not been set" << endl;
292 } 349 }
293 throw "Value not available"; 350 throw "Path cost not available";
294 } 351 }
295 return m_bestPathCost[i][j - m_first[i]]; 352 return m_bestPathCost[i][j - m_first[i]];
296 } else { 353 } else {
297 return m_otherMatcher->getValue(j, i); 354 return m_otherMatcher->getPathCost(j, i);
298 } 355 }
299 } 356 }
300 357
301 void 358 void
302 Matcher::setValue(int i, int j, double value) 359 Matcher::setPathCost(int i, int j, Advance dir, double pathCost)
303 { 360 {
304 if (m_firstPM) { 361 if (m_firstPM) {
305 if (!isInRange(i, j)) { 362 if (!isInRange(i, j)) {
306 cerr << "ERROR: Matcher::setValue(" << i << ", " << j << ", " 363 cerr << "ERROR: Matcher::setPathCost(" << i << ", " << j << ", "
307 << value << "): Location is out of range" << endl; 364 << dir << ", " << pathCost
365 << "): Location is out of range" << endl;
308 throw "Indices out of range"; 366 throw "Indices out of range";
309 } 367 }
310 m_bestPathCost[i][j - m_first[i]] = value; 368 m_advance[i][j - m_first[i]] = dir;
311 } else { 369 m_bestPathCost[i][j - m_first[i]] = pathCost;
312 m_otherMatcher->setValue(j, i, value); 370 } else {
313 }
314 }
315
316 void
317 Matcher::updateValue(int i, int j, Advance dir, double value, float dMN)
318 {
319 if (m_firstPM) {
320
321 int jdx = j - m_first[i];
322 m_distance[i][jdx] = dMN;
323 m_advance[i][jdx] = dir;
324 setValue(i, j, value + (dir == AdvanceBoth ? dMN*2: dMN));
325
326 } else {
327
328 if (dir == AdvanceThis) { 371 if (dir == AdvanceThis) {
329 dir = AdvanceOther; 372 dir = AdvanceOther;
330 } else if (dir == AdvanceOther) { 373 } else if (dir == AdvanceOther) {
331 dir = AdvanceThis; 374 dir = AdvanceThis;
332 } 375 }
376 m_otherMatcher->setPathCost(j, i, dir, pathCost);
377 }
378
379 }
380
381 void
382 Matcher::updateValue(int i, int j, Advance dir, double value, float dMN)
383 {
384 if (m_firstPM) {
385
386 m_distance[i][j - m_first[i]] = dMN;
387 setPathCost(i, j, dir, value + (dir == AdvanceBoth ? dMN*2: dMN));
388
389 } else {
333 390
334 int idx = i - m_otherMatcher->m_first[j]; 391 int idx = i - m_otherMatcher->m_first[j];
335 392
336 if (idx == (int)m_otherMatcher->m_distance[j].size()) { 393 if (idx == (int)m_otherMatcher->m_distance[j].size()) {
337 // This should never happen, but if we allow arbitrary 394 // This should never happen, but if we allow arbitrary
338 // pauses in either direction, and arbitrary lengths at 395 // pauses in either direction, and arbitrary lengths at
339 // end, it is better than a segmentation fault. 396 // end, it is better than a segmentation fault.
340 std::cerr << "Emergency resize: " << idx << " -> " << idx * 2 << std::endl; 397 cerr << "Emergency resize: " << idx << " -> " << idx * 2 << endl;
341 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, -1); 398 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, -1);
342 m_otherMatcher->m_distance[j].resize(idx * 2, -1); 399 m_otherMatcher->m_distance[j].resize(idx * 2, -1);
343 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone); 400 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone);
344 } 401 }
345 402
346 m_otherMatcher->m_distance[j][idx] = dMN; 403 m_otherMatcher->m_distance[j][idx] = dMN;
347 m_otherMatcher->m_advance[j][idx] = dir; 404 m_otherMatcher->setPathCost(j, i, dir, value + (dir == AdvanceBoth ? dMN*2: dMN));
348 m_otherMatcher->setValue(j, i, value + (dir == AdvanceBoth ? dMN*2: dMN)); 405 }
349 } 406 }
350 } 407
351 408 Matcher::Advance
409 Matcher::getAdvance(int i, int j)
410 {
411 if (m_firstPM) {
412 if (!isInRange(i, j)) {
413 cerr << "ERROR: Matcher::getAdvance(" << i << ", " << j << "): "
414 << "Location is not in range" << endl;
415 throw "Advance not available";
416 }
417 return m_advance[i][j - m_first[i]];
418 } else {
419 return m_otherMatcher->getAdvance(j, i);
420 }
421 }