Changeset 19085
- Timestamp:
- Aug 16, 2008, 12:34:48 PM (18 years ago)
- Location:
- trunk/psLib/src/math
- Files:
-
- 2 edited
-
psPolynomialMD.c (modified) (9 diffs)
-
psPolynomialMD.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psPolynomialMD.c
r17447 r19085 27 27 ) 28 28 { 29 if (!poly) return; 29 30 psFree(poly->orders); 30 31 psFree(poly->coeff); 32 33 psFree(poly->fitMatrix); 34 psFree(poly->fitVector); 35 psFree(poly->tmpMatrix); 36 psFree(poly->tmpVector); 37 38 psFree(poly->fitBuffer); 39 40 psFree(poly->ownMask); 41 psFree(poly->deviations); 42 43 psFree(poly->LUperm); 44 psFree(poly->LU); 45 31 46 return; 32 47 } … … 111 126 } 112 127 113 // Accumulate and solve the least-squares equation114 static bool polynomialMDClipFit(psPolynomialMD *poly, // Polynomial115 psImage *matrix, // Least-squares matrix116 psVector *vector, // Least-squares vector117 psImage **lu, // LU-decomposed matrix118 psVector **perm, // Permutations vector119 const psArray *matrices, // Individual least-squares matrices120 const psArray *vectors, // Individual least-squares vectors121 const psVector *mask // Mask for values122 )123 {124 int numValues = vectors->n; // Number of values125 126 // Accumulate the least-squares matrix and vector127 psImageInit(matrix, 0.0);128 psVectorInit(vector, 0.0);129 for (int i = 0; i < numValues; i++) {130 if (mask->data.U8[i]) {131 continue;132 }133 134 psImage *newMatrix = matrices->data[i]; // Matrix to accumulate135 psVector *newVector = vectors->data[i]; // Vector to accumulate136 137 polynomialMDAccumulate(matrix, vector, newMatrix, newVector);138 }139 polynomialMDFill(matrix);140 141 // Solve least-squares equation142 *lu = psMatrixLUD(*lu, perm, matrix);143 if (!*lu) {144 psError(PS_ERR_UNKNOWN, false, "Unable to LU-Decompose least-squares matrix.");145 return false;146 }147 poly->coeff = psMatrixLUSolve(poly->coeff, *lu, vector, *perm);148 if (!poly->coeff) {149 psError(PS_ERR_UNKNOWN, false, "Unable to solve least-squares equation.");150 return false;151 }152 return true;153 }154 155 128 // Calculate the standard deviation of the fit 156 129 static void polynomialMDStdev(psPolynomialMD *poly, // Polynomial for which to measure stdev … … 158 131 const psArray *coords, // Array of coordinates 159 132 const psVector *values, // Measured values 160 const psVector *mask // Mask for values 133 const psVector *mask, // Mask for values 134 psMaskType maskVal 161 135 ) 162 136 { … … 169 143 int numGood = numValues; // Number of good values 170 144 for (int i = 0; i < numValues; i++) { 171 if (mask && mask->data.U8[i]) {145 if (mask && (mask->data.U8[i] & maskVal)) { 172 146 numGood--; 173 147 continue; … … 234 208 poly->coeff = psVectorAlloc(numTerms, PS_TYPE_F64); 235 209 210 // internal temporary variables so we can use this in a tight, threaded loop 211 poly->fitMatrix = NULL; 212 poly->fitVector = NULL; 213 poly->tmpMatrix = NULL; 214 poly->tmpVector = NULL; 215 216 poly->fitBuffer = NULL; 217 218 poly->ownMask = NULL; 219 poly->deviations = NULL; 220 221 poly->LUperm = NULL; 222 poly->LU = NULL; 223 236 224 return poly; 237 225 } … … 288 276 int numValues = values->n; // Number of values 289 277 int numTerms = poly->coeff->n; // Number of terms 290 psImage *matrix = psImageAlloc(numTerms, numTerms, PS_TYPE_F64); // Least-squares matrix 291 psImageInit(matrix, 0.0); 292 psVector *vector = psVectorAlloc(numTerms, PS_TYPE_F64); // Least-squares vector 293 psVectorInit(vector, 0.0); 294 295 psImage *newMatrix = psImageAlloc(numTerms, numTerms, PS_TYPE_F64); // Least-squares matrix for each term 296 psVector *newVector = psVectorAlloc(numTerms, PS_TYPE_F64); // Least-squares vector for each term 297 psVector *buffer = psVectorAlloc(numTerms, PS_TYPE_F64); // Buffer for evaluations of polynomial stages 278 279 // we recycle matrices and vectors carried by poly to avoid alloc / threading hits 280 poly->fitMatrix = psImageRecycle(poly->fitMatrix, numTerms, numTerms, PS_TYPE_F64); // Least-squares matrix 281 poly->fitVector = psVectorRecycle(poly->fitVector, numTerms, PS_TYPE_F64); // Least-squares vector 282 283 psImageInit(poly->fitMatrix, 0.0); 284 psVectorInit(poly->fitVector, 0.0); 285 286 poly->tmpMatrix = psImageRecycle (poly->tmpMatrix, numTerms, numTerms, PS_TYPE_F64); // Least-squares matrix for each term 287 poly->tmpVector = psVectorRecycle(poly->tmpVector, numTerms, PS_TYPE_F64); // Least-squares vector for each term 288 poly->fitBuffer = psVectorRecycle(poly->fitBuffer, numTerms, PS_TYPE_F64); // Buffer for evaluations of polynomial stages 298 289 299 290 for (int i = 0; i < numValues; i++) { … … 307 298 } 308 299 309 polynomialMDLeastSquares(poly, newMatrix, newVector, coords, values->data.F32[i], 310 errors ? errors->data.F32[i] : 0.0, buffer); 311 polynomialMDAccumulate(matrix, vector, newMatrix, newVector); 312 } 313 polynomialMDFill(matrix); 314 315 psFree(newMatrix); 316 psFree(newVector); 317 psFree(buffer); 318 319 psVector *perm = NULL; // Permutation vector 320 psImage *lu = psMatrixLUD(NULL, &perm, matrix); // LU-decomposed matrix 321 psFree(matrix); 322 if (!lu) { 300 float err = errors ? errors->data.F32[i] : 0.0; 301 polynomialMDLeastSquares(poly, poly->tmpMatrix, poly->tmpVector, coords, values->data.F32[i], err, poly->fitBuffer); 302 polynomialMDAccumulate(poly->fitMatrix, poly->fitVector, poly->tmpMatrix, poly->tmpVector); 303 } 304 polynomialMDFill(poly->fitMatrix); 305 306 poly->LU = psMatrixLUD(poly->LU, &poly->LUperm, poly->fitMatrix); // LU-decomposed matrix 307 if (!poly->LU) { 323 308 psError(PS_ERR_UNKNOWN, false, "Unable to LU-Decompose least-squares matrix."); 324 psFree(vector);325 309 return false; 326 310 } 327 poly->coeff = psMatrixLUSolve(poly->coeff, lu, vector, perm); 328 psFree(vector); 329 psFree(lu); 330 psFree(perm); 311 312 poly->coeff = psMatrixLUSolve(poly->coeff, poly->LU, poly->fitVector, poly->LUperm); 331 313 if (!poly->coeff) { 332 314 psError(PS_ERR_UNKNOWN, false, "Unable to solve least-squares equation."); … … 334 316 } 335 317 336 polynomialMDStdev(poly, NULL, coordsArray, values, NULL);318 polynomialMDStdev(poly, poly->deviations, coordsArray, values, mask, maskVal); 337 319 338 320 return true; 339 321 } 322 323 // XXX this function should take a (psMaskType markVal) argument 324 bool psPolynomialMDClipFit(psPolynomialMD *poly, const psVector *values, const psVector *errors, 325 const psVector *mask, psMaskType maskVal, const psArray *coordsArray, 326 int numIter, float rej) 327 { 328 329 PS_ASSERT_POLYNOMIALMD_NON_NULL(poly, false); 330 PS_ASSERT_VECTOR_NON_NULL(values, false); 331 PS_ASSERT_VECTOR_TYPE(values, PS_TYPE_F32, false); 332 if (errors) { 333 PS_ASSERT_VECTOR_NON_NULL(errors, false); 334 PS_ASSERT_VECTOR_TYPE(errors, PS_TYPE_F32, false); 335 PS_ASSERT_VECTORS_SIZE_EQUAL(values, errors, false); 336 } 337 if (maskVal == 0) { 338 mask = NULL; 339 } 340 if (mask) { 341 PS_ASSERT_VECTOR_NON_NULL(mask, false); 342 PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_MASK, false); 343 PS_ASSERT_VECTORS_SIZE_EQUAL(values, mask, false); 344 } 345 PS_ASSERT_ARRAY_NON_NULL(coordsArray, false); 346 PS_ASSERT_ARRAY_SIZE(coordsArray, (long)values->n, false); 347 PS_ASSERT_INT_NONNEGATIVE(numIter, false); 348 PS_ASSERT_FLOAT_LARGER_THAN(rej, 0.0, false); 349 350 int numValues = values->n; // Number of values 351 int numTerms = poly->coeff->n; // Number of terms 352 353 int numClipped = INT_MAX; // Number of values clipped int an interation 354 int numGood = numValues; // Number of good values 355 356 // copy the input mask to a local temporary mask 357 poly->ownMask = psVectorRecycle(poly->ownMask, numValues, PS_TYPE_U8); // Our own mask for input values 358 psVectorInit(poly->ownMask, 0); 359 for (int i = 0; mask && (i < numValues); i++) { 360 if (mask->data.PS_TYPE_MASK_DATA[i] & maskVal) { 361 poly->ownMask->data.U8[i] = 0xff; 362 numGood--; 363 } 364 } 365 366 // make sure we have storage for the residuals 367 poly->deviations = psVectorRecycle (poly->deviations, numValues, PS_TYPE_F32); 368 369 for (int iter = 0; (iter < numIter) && (numClipped > 0) && (numGood > numTerms); iter++) { 370 numClipped = 0; 371 372 // XXX raise error? 373 if (!psPolynomialMDFit(poly, values, errors, poly->ownMask, maskVal, coordsArray)) { 374 return false; 375 } 376 377 psTrace("psLib.math", 7, "RMS from %d points is %lf\n", numGood, poly->stdevFit); 378 379 // Reject 380 float limit = rej * poly->stdevFit; // Rejection limit 381 for (int i = 0; i < numValues; i++) { 382 383 # if (0) 384 fprintf (stderr, "coords: "); 385 psVector *coords = coordsArray->data[i]; 386 for (int j = 0; j < coords->n; j++) { 387 fprintf (stderr, "%f ", coords->data.F32[j]); 388 } 389 # endif 390 391 psTrace("psLib.math", 10, "point %d (%f,%f: %f > %f)\n", 392 i, values->data.F32[i], values->data.F32[i] - poly->deviations->data.F32[i], poly->deviations->data.F32[i], limit); 393 394 if (poly->ownMask->data.U8[i]) continue; 395 396 if (fabs(poly->deviations->data.F32[i]) > limit) { 397 psTrace("psLib.math", 9, "Rejected point %d (%f,%f: %f > %f)\n", 398 i, values->data.F32[i], values->data.F32[i] + poly->deviations->data.F32[i], 399 poly->deviations->data.F32[i], limit); 400 poly->ownMask->data.U8[i] = 0xff; 401 numClipped++; 402 numGood--; 403 } 404 } 405 psTrace("psLib.math", 7, "Rejected %d points (%d remaining)\n", numClipped, numGood); 406 } 407 408 if (numClipped > 0) { 409 // Need to do a final re-evaluation of the fit 410 if (!psPolynomialMDFit(poly, values, errors, poly->ownMask, maskVal, coordsArray)) { 411 return false; 412 } 413 } 414 415 return true; 416 } 417 418 // XXX EAM : This function was trying to save calculation time at the expense of a LOT of allocs. 419 # if (0) 420 // Accumulate and solve the least-squares equation 421 static bool polynomialMDClipFit(psPolynomialMD *poly, // Polynomial 422 psImage *matrix, // Least-squares matrix 423 psVector *vector, // Least-squares vector 424 psImage **lu, // LU-decomposed matrix 425 psVector **perm, // Permutations vector 426 const psArray *matrices, // Individual least-squares matrices 427 const psArray *vectors, // Individual least-squares vectors 428 const psVector *mask, // Mask for values 429 ) 430 { 431 int numValues = vectors->n; // Number of values 432 433 // Accumulate the least-squares matrix and vector 434 psImageInit(matrix, 0.0); 435 psVectorInit(vector, 0.0); 436 for (int i = 0; i < numValues; i++) { 437 if (mask->data.U8[i]) { 438 continue; 439 } 440 441 psImage *newMatrix = matrices->data[i]; // Matrix to accumulate 442 psVector *newVector = vectors->data[i]; // Vector to accumulate 443 444 polynomialMDAccumulate(matrix, vector, newMatrix, newVector); 445 } 446 polynomialMDFill(matrix); 447 448 // Solve least-squares equation 449 *lu = psMatrixLUD(*lu, perm, matrix); 450 if (!*lu) { 451 psError(PS_ERR_UNKNOWN, false, "Unable to LU-Decompose least-squares matrix."); 452 return false; 453 } 454 poly->coeff = psMatrixLUSolve(poly->coeff, *lu, vector, *perm); 455 if (!poly->coeff) { 456 psError(PS_ERR_UNKNOWN, false, "Unable to solve least-squares equation."); 457 return false; 458 } 459 return true; 460 } 461 340 462 341 463 bool psPolynomialMDClipFit(psPolynomialMD *poly, const psVector *values, const psVector *errors, … … 471 593 return true; 472 594 } 473 595 # endif -
trunk/psLib/src/math/psPolynomialMD.h
r17147 r19085 13 13 int numFit; ///< Number of values in fit 14 14 float stdevFit; ///< Standard deviation of fit 15 16 psImage *fitMatrix; 17 psVector *fitVector; 18 19 psImage *tmpMatrix; 20 psVector *tmpVector; 21 22 psVector *fitBuffer; 23 24 psVector *ownMask; 25 psVector *deviations; 26 27 psVector *LUperm; 28 psImage *LU; 29 15 30 } psPolynomialMD; 16 31
Note:
See TracChangeset
for help on using the changeset viewer.
