comparison src/Matcher.cpp @ 71:cba231851957 refactors

Encapsulate get/set, add range and init checks
author Chris Cannam
date Wed, 19 Nov 2014 09:17:58 +0000
parents 696f6e7f2f31
children c3c50d5e05b7
comparison
equal deleted inserted replaced
70:a130ec8e5eef 71:cba231851957
100 100
101 void 101 void
102 Matcher::size() 102 Matcher::size()
103 { 103 {
104 int distSize = (m_params.maxRunCount + 1) * m_blockSize; 104 int distSize = (m_params.maxRunCount + 1) * m_blockSize;
105 m_bestPathCost.resize(m_distXSize, vector<double>(distSize, 0)); 105 m_bestPathCost.resize(m_distXSize, vector<double>(distSize, -1));
106 m_distance.resize(m_distXSize, vector<float>(distSize, 0)); 106 m_distance.resize(m_distXSize, vector<float>(distSize, -1));
107 m_advance.resize(m_distXSize, vector<Advance>(distSize, AdvanceNone)); 107 m_advance.resize(m_distXSize, vector<Advance>(distSize, AdvanceNone));
108 m_first.resize(m_distXSize, 0); 108 m_first.resize(m_distXSize, 0);
109 m_last.resize(m_distXSize, 0); 109 m_last.resize(m_distXSize, 0);
110 } 110 }
111 111
152 // distance[m_frameCount], and then truncate 152 // distance[m_frameCount], and then truncate
153 // distance[m_frameCount-m_blockSize] to its first len elements. 153 // distance[m_frameCount-m_blockSize] to its first len elements.
154 // Same for bestPathCost. 154 // Same for bestPathCost.
155 155
156 vector<float> dOld = m_distance[m_frameCount - m_blockSize]; 156 vector<float> dOld = m_distance[m_frameCount - m_blockSize];
157 vector<float> dNew(len, 0.f); 157 vector<float> dNew(len, -1.f);
158 158
159 vector<double> bpcOld = m_bestPathCost[m_frameCount - m_blockSize]; 159 vector<double> bpcOld = m_bestPathCost[m_frameCount - m_blockSize];
160 vector<double> bpcNew(len, 0.0); 160 vector<double> bpcNew(len, -1.0);
161 161
162 vector<Advance> adOld = m_advance[m_frameCount - m_blockSize]; 162 vector<Advance> adOld = m_advance[m_frameCount - m_blockSize];
163 vector<Advance> adNew(len, AdvanceNone); 163 vector<Advance> adNew(len, AdvanceNone);
164 164
165 for (int i = 0; i < len; ++i) { 165 for (int i = 0; i < len; ++i) {
199 mx = dMN; 199 mx = dMN;
200 else if (dMN < mn) 200 else if (dMN < mn)
201 mn = dMN; 201 mn = dMN;
202 202
203 if ((m_frameCount == 0) && (index == 0)) // first element 203 if ((m_frameCount == 0) && (index == 0)) // first element
204 setValue(0, 0, AdvanceNone, 0, dMN); 204 updateValue(0, 0, AdvanceNone, 0, dMN);
205 else if (m_frameCount == 0) // first row 205 else if (m_frameCount == 0) // first row
206 setValue(0, index, AdvanceOther, 206 updateValue(0, index, AdvanceOther,
207 getValue(0, index-1, true), dMN); 207 getValue(0, index-1), dMN);
208 else if (index == 0) // first column 208 else if (index == 0) // first column
209 setValue(m_frameCount, index, AdvanceThis, 209 updateValue(m_frameCount, index, AdvanceThis,
210 getValue(m_frameCount - 1, 0, true), dMN); 210 getValue(m_frameCount - 1, 0), dMN);
211 else if (index == m_otherMatcher->m_frameCount - m_blockSize) { 211 else if (index == m_otherMatcher->m_frameCount - m_blockSize) {
212 // missing value(s) due to cutoff 212 // missing value(s) due to cutoff
213 // - no previous value in current row (resp. column) 213 // - no previous value in current row (resp. column)
214 // - no diagonal value if prev. dir. == curr. dirn 214 // - no diagonal value if prev. dir. == curr. dirn
215 double min2 = getValue(m_frameCount - 1, index, true); 215 double min2 = getValue(m_frameCount - 1, index);
216 // if ((m_firstPM && (first[m_frameCount - 1] == index)) || 216 // if ((m_firstPM && (first[m_frameCount - 1] == index)) ||
217 // (!m_firstPM && (m_last[index-1] < m_frameCount))) 217 // (!m_firstPM && (m_last[index-1] < m_frameCount)))
218 if (m_first[m_frameCount - 1] == index) 218 if (m_first[m_frameCount - 1] == index)
219 setValue(m_frameCount, index, AdvanceThis, min2, dMN); 219 updateValue(m_frameCount, index, AdvanceThis, min2, dMN);
220 else { 220 else {
221 double min1 = getValue(m_frameCount - 1, index - 1, true); 221 double min1 = getValue(m_frameCount - 1, index - 1);
222 if (min1 + dMN <= min2) 222 if (min1 + dMN <= min2)
223 setValue(m_frameCount, index, AdvanceBoth, min1,dMN); 223 updateValue(m_frameCount, index, AdvanceBoth, min1,dMN);
224 else 224 else
225 setValue(m_frameCount, index, AdvanceThis, min2,dMN); 225 updateValue(m_frameCount, index, AdvanceThis, min2,dMN);
226 } 226 }
227 } else { 227 } else {
228 double min1 = getValue(m_frameCount, index-1, true); 228 double min1 = getValue(m_frameCount, index-1);
229 double min2 = getValue(m_frameCount - 1, index, true); 229 double min2 = getValue(m_frameCount - 1, index);
230 double min3 = getValue(m_frameCount - 1, index-1, true); 230 double min3 = getValue(m_frameCount - 1, index-1);
231 if (min1 <= min2) { 231 if (min1 <= min2) {
232 if (min3 + dMN <= min1) 232 if (min3 + dMN <= min1)
233 setValue(m_frameCount, index, AdvanceBoth, min3,dMN); 233 updateValue(m_frameCount, index, AdvanceBoth, min3,dMN);
234 else 234 else
235 setValue(m_frameCount, index, AdvanceOther,min1,dMN); 235 updateValue(m_frameCount, index, AdvanceOther,min1,dMN);
236 } else { 236 } else {
237 if (min3 + dMN <= min2) 237 if (min3 + dMN <= min2)
238 setValue(m_frameCount, index, AdvanceBoth, min3,dMN); 238 updateValue(m_frameCount, index, AdvanceBoth, min3,dMN);
239 else 239 else
240 setValue(m_frameCount, index, AdvanceThis, min2,dMN); 240 updateValue(m_frameCount, index, AdvanceThis, min2,dMN);
241 } 241 }
242 } 242 }
243 m_otherMatcher->m_last[index]++; 243 m_otherMatcher->m_last[index]++;
244 } // loop for row (resp. column) 244 } // loop for row (resp. column)
245 245
247 m_runCount++; 247 m_runCount++;
248 248
249 m_otherMatcher->m_runCount = 0; 249 m_otherMatcher->m_runCount = 0;
250 } 250 }
251 251
252 bool
253 Matcher::isInRange(int i, int j)
254 {
255 if (m_firstPM) {
256 return ((i >= 0) &&
257 (i < int(m_first.size())) &&
258 (j >= m_first[i]) &&
259 (j < int(m_first[i] + m_bestPathCost[i].size())));
260 } else {
261 return m_otherMatcher->isInRange(j, i);
262 }
263 }
264
265 bool
266 Matcher::isAvailable(int i, int j)
267 {
268 if (m_firstPM) {
269 if (isInRange(i, j)) {
270 return (m_bestPathCost[i][j - m_first[i]] >= 0);
271 } else {
272 return false;
273 }
274 } else {
275 return m_otherMatcher->isAvailable(j, i);
276 }
277 }
278
252 double 279 double
253 Matcher::getValue(int i, int j, bool firstAttempt) 280 Matcher::getValue(int i, int j)
254 { 281 {
255 if (m_firstPM) 282 if (m_firstPM) {
283 if (!isAvailable(i, j)) {
284 if (!isInRange(i, j)) {
285 cerr << "ERROR: Matcher::getValue(" << i << ", " << j << "): "
286 << "Location is not in range" << endl;
287 } else {
288 cerr << "ERROR: Matcher::getValue(" << i << ", " << j << "): "
289 << "Location is in range, but value ("
290 << m_bestPathCost[i][j - m_first[i]]
291 << ") is invalid or has not been set" << endl;
292 }
293 throw "Value not available";
294 }
256 return m_bestPathCost[i][j - m_first[i]]; 295 return m_bestPathCost[i][j - m_first[i]];
257 else 296 } else {
258 return m_otherMatcher->m_bestPathCost[j][i - m_otherMatcher->m_first[j]]; 297 return m_otherMatcher->getValue(j, i);
259 } // getValue() 298 }
260 299 }
261 void 300
262 Matcher::setValue(int i, int j, Advance dir, double value, float dMN) 301 void
302 Matcher::setValue(int i, int j, double value)
303 {
304 if (m_firstPM) {
305 if (!isInRange(i, j)) {
306 cerr << "ERROR: Matcher::setValue(" << i << ", " << j << ", "
307 << value << "): Location is out of range" << endl;
308 throw "Indices out of range";
309 }
310 m_bestPathCost[i][j - m_first[i]] = value;
311 } else {
312 m_otherMatcher->setValue(j, i, value);
313 }
314 }
315
316 void
317 Matcher::updateValue(int i, int j, Advance dir, double value, float dMN)
263 { 318 {
264 if (m_firstPM) { 319 if (m_firstPM) {
265 320
266 int jdx = j - m_first[i]; 321 int jdx = j - m_first[i];
267 m_distance[i][jdx] = dMN; 322 m_distance[i][jdx] = dMN;
268 m_advance[i][jdx] = dir; 323 m_advance[i][jdx] = dir;
269 m_bestPathCost[i][jdx] = 324 setValue(i, j, value + (dir == AdvanceBoth ? dMN*2: dMN));
270 (value + (dir == AdvanceBoth ? dMN*2: dMN));
271 325
272 } else { 326 } else {
273 327
274 if (dir == AdvanceThis) { 328 if (dir == AdvanceThis) {
275 dir = AdvanceOther; 329 dir = AdvanceOther;
282 if (idx == (int)m_otherMatcher->m_distance[j].size()) { 336 if (idx == (int)m_otherMatcher->m_distance[j].size()) {
283 // This should never happen, but if we allow arbitrary 337 // This should never happen, but if we allow arbitrary
284 // pauses in either direction, and arbitrary lengths at 338 // pauses in either direction, and arbitrary lengths at
285 // end, it is better than a segmentation fault. 339 // end, it is better than a segmentation fault.
286 std::cerr << "Emergency resize: " << idx << " -> " << idx * 2 << std::endl; 340 std::cerr << "Emergency resize: " << idx << " -> " << idx * 2 << std::endl;
287 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, 0); 341 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, -1);
288 m_otherMatcher->m_distance[j].resize(idx * 2, 0); 342 m_otherMatcher->m_distance[j].resize(idx * 2, -1);
289 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone); 343 m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone);
290 } 344 }
291 345
292 m_otherMatcher->m_distance[j][idx] = dMN; 346 m_otherMatcher->m_distance[j][idx] = dMN;
293 m_otherMatcher->m_advance[j][idx] = dir; 347 m_otherMatcher->m_advance[j][idx] = dir;
294 m_otherMatcher->m_bestPathCost[j][idx] = 348 m_otherMatcher->setValue(j, i, value + (dir == AdvanceBoth ? dMN*2: dMN));
295 (value + (dir == AdvanceBoth ? dMN*2: dMN)); 349 }
296 } 350 }
297 } // setValue() 351
298