comparison src/Matcher.cpp @ 188:487261a22b18 re-minimise

distance_t * diagonalWeight might not fit in distance_t; use pathcost_t for it. Also remove C-style casts.
author Chris Cannam
date Thu, 26 Feb 2015 12:19:17 +0000
parents 24ddab06aace
children f415747b151b
comparison
equal deleted inserted replaced
187:ba0d2104abec 188:487261a22b18
224 } else if (dir == AdvanceOther) { 224 } else if (dir == AdvanceOther) {
225 dir = AdvanceThis; 225 dir = AdvanceThis;
226 } 226 }
227 m_otherMatcher->setPathCost(j, i, dir, pathCost); 227 m_otherMatcher->setPathCost(j, i, dir, pathCost);
228 } 228 }
229
230 } 229 }
231 230
232 void 231 void
233 Matcher::size() 232 Matcher::size()
234 { 233 {
301 m_first[m_frameCount] = index; 300 m_first[m_frameCount] = index;
302 m_last[m_frameCount] = stop; 301 m_last[m_frameCount] = stop;
303 302
304 for ( ; index < stop; index++) { 303 for ( ; index < stop; index++) {
305 304
306 distance_t distance = (distance_t) m_metric.calcDistance 305 distance_t distance = m_metric.calcDistance
307 (m_features[frameIndex], 306 (m_features[frameIndex],
308 m_otherMatcher->m_features[index % m_blockSize]); 307 m_otherMatcher->m_features[index % m_blockSize]);
309 308
310 distance_t diagDistance = distance_t(distance * m_params.diagonalWeight); 309 pathcost_t straightIncrement(distance);
310 pathcost_t diagIncrement = pathcost_t(distance * m_params.diagonalWeight);
311 311
312 if ((m_frameCount == 0) && (index == 0)) { // first element 312 if ((m_frameCount == 0) && (index == 0)) { // first element
313 313
314 updateValue(0, 0, AdvanceNone, 314 updateValue(0, 0, AdvanceNone,
315 0, 315 0,
346 min2, distance); 346 min2, distance);
347 347
348 } else { 348 } else {
349 349
350 pathcost_t min1 = getPathCost(m_frameCount - 1, index - 1); 350 pathcost_t min1 = getPathCost(m_frameCount - 1, index - 1);
351 if (min1 + diagDistance <= min2 + distance) { 351 if (min1 + diagIncrement <= min2 + straightIncrement) {
352 updateValue(m_frameCount, index, AdvanceBoth, 352 updateValue(m_frameCount, index, AdvanceBoth,
353 min1, distance); 353 min1, distance);
354 } else { 354 } else {
355 updateValue(m_frameCount, index, AdvanceThis, 355 updateValue(m_frameCount, index, AdvanceThis,
356 min2, distance); 356 min2, distance);
361 361
362 pathcost_t min1 = getPathCost(m_frameCount, index - 1); 362 pathcost_t min1 = getPathCost(m_frameCount, index - 1);
363 pathcost_t min2 = getPathCost(m_frameCount - 1, index); 363 pathcost_t min2 = getPathCost(m_frameCount - 1, index);
364 pathcost_t min3 = getPathCost(m_frameCount - 1, index - 1); 364 pathcost_t min3 = getPathCost(m_frameCount - 1, index - 1);
365 365
366 pathcost_t cost1 = min1 + distance; 366 pathcost_t cost1 = min1 + straightIncrement;
367 pathcost_t cost2 = min2 + distance; 367 pathcost_t cost2 = min2 + straightIncrement;
368 pathcost_t cost3 = min3 + diagDistance; 368 pathcost_t cost3 = min3 + diagIncrement;
369 369
370 // Choosing is easy if there is a strict cheapest of the 370 // Choosing is easy if there is a strict cheapest of the
371 // three. If two or more share the lowest cost, we choose 371 // three. If two or more share the lowest cost, we choose
372 // in order of preference: cost3 (AdvanceBoth), cost2 372 // in order of preference: cost3 (AdvanceBoth), cost2
373 // (AdvanceThis), cost1 (AdvanceOther) if we are the first 373 // (AdvanceThis), cost1 (AdvanceOther) if we are the first
406 } 406 }
407 407
408 void 408 void
409 Matcher::updateValue(int i, int j, advance_t dir, pathcost_t value, distance_t distance) 409 Matcher::updateValue(int i, int j, advance_t dir, pathcost_t value, distance_t distance)
410 { 410 {
411 distance_t weighted = distance; 411 pathcost_t increment = distance;
412 if (dir == AdvanceBoth) { 412 if (dir == AdvanceBoth) {
413 weighted = distance_t(weighted * m_params.diagonalWeight); 413 increment = pathcost_t(increment * m_params.diagonalWeight);
414 }
415
416 pathcost_t newValue = value + increment;
417 if (MaxPathCost - increment < value) {
418 cerr << "ERROR: Path cost overflow at i=" << i << ", j=" << j << ": "
419 << value << " + " << increment << " > " << MaxPathCost << endl;
420 newValue = MaxPathCost;
414 } 421 }
415 422
416 if (m_firstPM) { 423 if (m_firstPM) {
417 424
418 setDistance(i, j, distance); 425 setDistance(i, j, distance);
419 setPathCost(i, j, dir, value + weighted); 426 setPathCost(i, j, dir, newValue);
420 427
421 } else { 428 } else {
422 429
423 if (dir == AdvanceThis) dir = AdvanceOther; 430 if (dir == AdvanceThis) dir = AdvanceOther;
424 else if (dir == AdvanceOther) dir = AdvanceThis; 431 else if (dir == AdvanceOther) dir = AdvanceThis;
425 432
426 int idx = i - m_otherMatcher->m_first[j]; 433 int idx = i - m_otherMatcher->m_first[j];
427 434
428 if (idx == (int)m_otherMatcher->m_distance[j].size()) { 435 if (idx < 0 || size_t(idx) == m_otherMatcher->m_distance[j].size()) {
429 // This should never happen, but if we allow arbitrary 436 // This should never happen, but if we allow arbitrary
430 // pauses in either direction, and arbitrary lengths at 437 // pauses in either direction, and arbitrary lengths at
431 // end, it is better than a segmentation fault. 438 // end, it is better than a segmentation fault.
432 cerr << "Emergency resize: " << idx << " -> " << idx * 2 << endl; 439 cerr << "Emergency resize: " << idx << " -> " << idx * 2 << endl;
433 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, InvalidPathCost); 440 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, InvalidPathCost);
434 m_otherMatcher->m_distance[j].resize(idx * 2, InvalidDistance); 441 m_otherMatcher->m_distance[j].resize(idx * 2, InvalidDistance);
435 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone); 442 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone);
436 } 443 }
437 444
438 m_otherMatcher->setDistance(j, i, distance); 445 m_otherMatcher->setDistance(j, i, distance);
439 m_otherMatcher->setPathCost(j, i, dir, value + weighted); 446 m_otherMatcher->setPathCost(j, i, dir, newValue);
440 } 447 }
441 } 448 }
442 449
443 advance_t 450 advance_t
444 Matcher::getAdvance(int i, int j) 451 Matcher::getAdvance(int i, int j)