Changeset 4977 for trunk/psphot/src/psPolynomials.c
- Timestamp:
- Sep 7, 2005, 6:32:40 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psPolynomials.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psPolynomials.c
r4954 r4977 1 # include "psphot.h" 1 # include <pslib.h> 2 # include "psLibUtils.h" 2 3 3 4 // XXX EAM : this file defines alternate versions of the polynomial fitting … … 9 10 10 11 // write out the terms of the given 1D polynomial 11 void psPolynomial1DDump(psPolynomial1D *poly) {12 void Polynomial1DDump_EAM (psPolynomial1D *poly) { 12 13 13 14 for (int i = 0; i < poly->n + 1; i++) { … … 16 17 } 17 18 18 psF64 Polynomial1DEval_EAM(psF64 x, const psPolynomial1D* myPoly) 19 { 20 psS32 loop_x = 0; 21 psF64 polySum = 0.0; 22 psF64 xSum = 1.0; 23 24 for (loop_x = 0; loop_x < myPoly->n + 1; loop_x++) { 25 if (myPoly->mask[loop_x] == 0) { 26 polySum += xSum * myPoly->coeff[loop_x]; 27 } 28 xSum *= x; 29 } 30 31 return(polySum); 32 } 33 34 psVector *Polynomial1DEvalVector_EAM(const psPolynomial1D *myPoly, 35 const psVector *x) 36 { 37 // PS_POLY_CHECK_NULL(myPoly, NULL); 38 // PS_VECTOR_CHECK_NULL(x, NULL); 39 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL); 40 41 psVector *tmp; 42 43 tmp = psVectorAlloc(x->n, PS_TYPE_F64); 44 for (psS32 i=0;i<x->n;i++) { 45 tmp->data.F64[i] = Polynomial1DEval_EAM(x->data.F64[i], myPoly); 46 } 47 48 return(tmp); 49 } 50 51 static void psPolynomial1DFree (psPolynomial1D *poly) { 52 53 if (poly == NULL) return; 54 psFree (poly->coeff); 55 psFree (poly->coeffErr); 56 psFree (poly->mask); 57 return; 19 static void Polynomial1DFree_EAM (psPolynomial1D *poly) { 20 21 if (poly == NULL) return; 22 psFree (poly->coeff); 23 psFree (poly->coeffErr); 24 psFree (poly->mask); 25 return; 58 26 } 59 27 60 28 // XXX EAM : use Nterm = Norder + 1 definition 61 29 // XXX EAM : should we provide both order and nterms in struct? 62 psPolynomial1D* Polynomial1DAlloc (psS32 nOrder,63 psPolynomialType type)30 psPolynomial1D* Polynomial1DAlloc_EAM(psPolynomialType type, 31 psS32 nOrder) 64 32 { 65 33 // PS_INT_CHECK_NON_NEGATIVE(nOrder, NULL); … … 80 48 newPoly->mask[i] = 0; 81 49 } 82 psMemSetDeallocator(newPoly, (psFreeFunc) psPolynomial1DFree);50 psMemSetDeallocator(newPoly, (psFreeFunc) Polynomial1DFree_EAM); 83 51 return(newPoly); 84 52 } 85 53 54 psF64 Polynomial1DEval_EAM(const psPolynomial1D* myPoly, psF64 x) 55 { 56 psS32 loop_x = 0; 57 psF64 polySum = 0.0; 58 psF64 xSum = 1.0; 59 60 for (loop_x = 0; loop_x < myPoly->n + 1; loop_x++) { 61 if (myPoly->mask[loop_x] == 0) { 62 polySum += xSum * myPoly->coeff[loop_x]; 63 } 64 xSum *= x; 65 } 66 67 return(polySum); 68 } 69 70 psVector *Polynomial1DEvalVector_EAM(const psPolynomial1D *myPoly, 71 const psVector *x) 72 { 73 // PS_POLY_CHECK_NULL(myPoly, NULL); 74 // PS_VECTOR_CHECK_NULL(x, NULL); 75 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL); 76 77 psVector *tmp; 78 79 tmp = psVectorAlloc(x->n, PS_TYPE_F64); 80 for (psS32 i=0;i<x->n;i++) { 81 tmp->data.F64[i] = Polynomial1DEval_EAM(myPoly, x->data.F64[i]); 82 } 83 84 return(tmp); 85 } 86 86 87 // XXX EAM : my alternate BuildSums1D 87 static psVector *BuildSums1D (psVector* sums,88 psF64 x,89 psS32 nTerm)88 static psVector *BuildSums1D_EAM(psVector* sums, 89 psF64 x, 90 psS32 nTerm) 90 91 { 91 92 psS32 nSum = 0; … … 109 110 110 111 // XXX EAM : test version of 1d fitting 111 psPolynomial1D* VectorFitPolynomial1DOrd_EAM(psPolynomial1D* myPoly, 112 psVector *mask, 113 const psVector *x, 114 const psVector *y, 115 const psVector *yErr) 112 psPolynomial1D* VectorFitPolynomial1D_EAM(psPolynomial1D* myPoly, 113 psVector *mask, 114 psMaskType maskValue, 115 const psVector *y, 116 const psVector *yErr, 117 const psVector *x) 116 118 { 117 119 // I think this is 1 dimension down … … 130 132 // XXX EAM : change from FILE to fd breaks this code: 131 133 if (psTraceGetLevel (".psLib.dataManip.VectorFitPolynomial1DOrd") >= 5) { 132 FILE *f = psTraceGetDestination ();133 fprintf (f, "VectorFitPolynomial1D()\n");134 for (int i = 0; i < x->n; i++) {135 fprintf (f, "(x, y, yErr) is (%f, %f, %f)\n", x->data.F64[i], y->data.F64[i], yErr->data.F64[i]);136 }134 FILE *f = psTraceGetDestination (); 135 fprintf (f, "VectorFitPolynomial1D()\n"); 136 for (int i = 0; i < x->n; i++) { 137 fprintf (f, "(x, y, yErr) is (%f, %f, %f)\n", x->data.F64[i], y->data.F64[i], yErr->data.F64[i]); 138 } 137 139 } 138 140 # endif … … 155 157 // Build the B and A data structs. 156 158 for (int k = 0; k < x->n; k++) { 157 if ((mask != NULL) && mask->data.U8[k]) continue;158 xSums = BuildSums1D (xSums, x->data.F64[k], nTerm);159 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) continue; 160 xSums = BuildSums1D_EAM(xSums, x->data.F64[k], nTerm); 159 161 160 162 if (yErr == NULL) { … … 190 192 } 191 193 else 192 // LUD version of the fit194 // LUD version of the fit 193 195 { 194 196 psImage *ALUD = NULL; … … 218 220 // ********************** 2D polynomial functions ****************** 219 221 220 // XXX EAM : this version uses myPoly->nX as Norder, not Nterms 221 psVector *Polynomial2DEvalVector(const psPolynomial2D *myPoly, 222 const psVector *x, 223 const psVector *y) 224 225 { 226 // PS_POLY_CHECK_NULL(myPoly, NULL); 227 // PS_VECTOR_CHECK_NULL(x, NULL); 228 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL); 229 // PS_VECTOR_CHECK_NULL(y, NULL); 230 // PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL); 231 232 psVector *tmp; 233 psS32 vecLen=x->n; 234 235 // Determine the length of the output vector to by the minimum of the x,y vectors 236 if (y->n < vecLen) { 237 vecLen = y->n; 238 } 239 240 // Create output vector to return 241 tmp = psVectorAlloc(vecLen, PS_TYPE_F32); 242 243 // Evaluate the polynomial at the specified points 244 for (psS32 i=0; i<vecLen; i++) { 245 tmp->data.F32[i] = Polynomial2DEval(myPoly,x->data.F32[i],y->data.F32[i]); 246 } 247 248 // Return output vector 249 return(tmp); 250 } 251 252 // XXX EAM : this version uses the F64 vectors 253 psVector *Polynomial2DEvalVectorD(const psPolynomial2D *myPoly, 254 const psVector *x, 255 const psVector *y) 256 257 { 258 // PS_POLY_CHECK_NULL(myPoly, NULL); 259 // PS_VECTOR_CHECK_NULL(x, NULL); 260 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL); 261 // PS_VECTOR_CHECK_NULL(y, NULL); 262 // PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL); 263 264 psVector *tmp; 265 psS32 vecLen=x->n; 266 267 // Determine the length of the output vector to by the minimum of the x,y vectors 268 if (y->n < vecLen) { 269 vecLen = y->n; 270 } 271 272 // Create output vector to return 273 tmp = psVectorAlloc(vecLen, PS_TYPE_F64); 274 275 // Evaluate the polynomial at the specified points 276 for (psS32 i=0; i<vecLen; i++) { 277 tmp->data.F64[i] = Polynomial2DEval(myPoly,x->data.F64[i],y->data.F64[i]); 278 } 279 280 // Return output vector 281 return(tmp); 282 } 283 284 static void psPolynomial2DFree(psPolynomial2D *poly) { 285 286 if (poly == NULL) return; 287 for (int i = 0; i < poly->nX + 1; i++) { 288 psFree (poly->coeff[i]); 289 psFree (poly->coeffErr[i]); 290 psFree (poly->mask[i]); 291 } 292 psFree (poly->coeff); 293 psFree (poly->coeffErr); 294 psFree (poly->mask); 295 return; 222 static void Polynomial2DFree_EAM(psPolynomial2D *poly) { 223 224 if (poly == NULL) return; 225 for (int i = 0; i < poly->nX + 1; i++) { 226 psFree (poly->coeff[i]); 227 psFree (poly->coeffErr[i]); 228 psFree (poly->mask[i]); 229 } 230 psFree (poly->coeff); 231 psFree (poly->coeffErr); 232 psFree (poly->mask); 233 return; 296 234 } 297 235 298 236 // XXX EAM : use Nterm = Norder + 1 definition 299 237 // the user requests a polynomial of order Norder 300 psPolynomial2D* Polynomial2DAlloc(psS32 nXorder, psS32 nYorder, 301 psPolynomialType type) 238 psPolynomial2D* Polynomial2DAlloc_EAM(psPolynomialType type, 239 psS32 nXorder, 240 psS32 nYorder) 302 241 { 303 242 // PS_INT_CHECK_NON_NEGATIVE(nXorder, NULL); … … 332 271 } 333 272 } 334 psMemSetDeallocator(newPoly, (psFreeFunc) psPolynomial2DFree);273 psMemSetDeallocator(newPoly, (psFreeFunc) Polynomial2DFree_EAM); 335 274 return(newPoly); 336 275 } 337 276 338 // XXX EAM : BuildSums2D in analogy with BuildSums1D339 static psImage *BuildSums2D(psImage* sums,340 psF64 x, psF64 y,341 psS32 nXterm, psS32 nYterm)342 {343 psS32 nXsum = 0;344 psS32 nYsum = 0;345 psF64 xSum = 1.0;346 psF64 ySum = 1.0;347 348 nXsum = 2*nXterm;349 nYsum = 2*nYterm;350 if (sums == NULL) {351 sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64);352 }353 if ((nXsum != sums->numCols) || (nYsum != sums->numRows)) {354 psFree (sums);355 sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64);356 }357 358 ySum = 1.0;359 for (int j = 0; j < nYsum; j++) {360 xSum = ySum;361 for (int i = 0; i < nXsum; i++) {362 sums->data.F64[i][j] = xSum;363 xSum *= x;364 }365 ySum *= y;366 }367 return (sums);368 }369 370 // XXX EAM : test version of 2d fitting371 psPolynomial2D* VectorFitPolynomial2DOrd_EAM(psPolynomial2D* myPoly,372 psVector* mask,373 const psVector* x,374 const psVector* y,375 const psVector* z,376 const psVector* zErr)377 {378 // I think this is 1 dimension down379 psImage* A = NULL;380 psVector* B = NULL;381 psImage* Sums = NULL;382 psF64 wt;383 psS32 nTerm, nXterm, nYterm;384 385 nXterm = myPoly->nX + 1;386 nYterm = myPoly->nY + 1;387 nTerm = nXterm * nYterm;388 389 A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64);390 B = psVectorAlloc(nTerm, PS_TYPE_F64);391 392 // Initialize data structures (why is this not a function!)393 for (int i = 0; i < nTerm; i++) {394 B->data.F64[i] = 0.0;395 for (int j = 0; j < nTerm; j++) {396 A->data.F64[i][j] = 0.0;397 }398 }399 400 // Sums look like: 1, x, x^2, ... x^(2n+1), y, xy, x^2y, ... x^(2n+1)401 402 // Build the B and A data structs.403 for (int k = 0; k < x->n; k++) {404 if ((mask != NULL) && mask->data.U8[k]) continue;405 Sums = BuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm);406 407 if (zErr == NULL) {408 wt = 1.0;409 } else {410 // this should probably by zErr^2 !!411 // this should filter zErr == 0 values412 wt = 1.0 / zErr->data.F64[k];413 }414 415 // we could skip half of the array and assign at the end416 // we must handle masked orders417 for (int n = 0; n < nXterm; n++) {418 for (int m = 0; m < nYterm; m++) {419 B->data.F64[n+m*nXterm] += z->data.F64[k] * Sums->data.F64[n][m] * wt;420 }421 }422 423 for (int i = 0; i < nXterm; i++) {424 for (int j = 0; j < nYterm; j++) {425 for (int n = 0; n < nXterm; n++) {426 for (int m = 0; m < nYterm; m++) {427 A->data.F64[i+j*nXterm][n+m*nXterm] += Sums->data.F64[i+n][j+m] * wt;428 }429 }430 }431 }432 }433 434 // does the solution in place435 psGaussJordan (A, B);436 437 // XXX: How do we know if these routines were successful?438 // ALUD = psMatrixLUD(ALUD, &outPerm, A);439 // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);440 441 for (int n = 0; n < nXterm; n++) {442 for (int m = 0; m < nYterm; m++) {443 myPoly->coeff[n][m] = B->data.F64[n+m*nXterm];444 }445 }446 447 psFree(A);448 psFree(B);449 psFree(Sums);450 451 psTrace(".psLib.dataManip.VectorFitPolynomial2DOrd", 4,452 "---- VectorFitPolynomial2DOrd() begin ----\n");453 return (myPoly);454 }455 456 277 // write out the terms of the given 2D polynomial 457 void psPolynomial2DDump(psPolynomial2D *poly) {278 void Polynomial2DDump_EAM (psPolynomial2D *poly) { 458 279 459 280 for (int i = 0; i < poly->nX + 1; i++) { … … 464 285 } 465 286 466 psPolynomial2D* RobustFit2D_nomask(psPolynomial2D* poly, 467 const psVector* x, 468 const psVector* y, 469 const psVector* z, 470 const psVector* dz) 471 { 472 psVector *X; 473 psVector *Y; 474 psVector *Z; 475 psVector *dZ; 476 477 psVector *zFit = NULL; 478 psVector *zResid = NULL; 479 psStats *stats = NULL; 480 481 X = psVectorCopy (NULL, x, PS_TYPE_F64); 482 Y = psVectorCopy (NULL, y, PS_TYPE_F64); 483 Z = psVectorCopy (NULL, z, PS_TYPE_F64); 484 dZ = psVectorCopy (NULL, dz, PS_TYPE_F64); 485 486 for (int N = 0; N < 3; N++) { 487 // XXX EAM : this would be better defined with an element mask 488 poly = VectorFitPolynomial2DOrd_EAM (poly, NULL, X, Y, Z, dZ); 489 zFit = Polynomial2DEvalVectorD (poly, x, y); 490 zResid = (psVector *) psBinaryOp (NULL, (void *) z, "-", (void *) zFit); 491 492 stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 493 stats = psVectorStats (stats, zResid, NULL, NULL, 0); 494 psTrace (".psphot.RobustFit", 4, "residual stats for robust fit: %g +/- %g (%d pts)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues); 495 496 // re-create X, Y, Z, dZ if pts are valid 497 int n = 0; 498 for (int i = 0; i < zResid->n; i++) { 499 if (fabs(zResid->data.F64[i] - stats->clippedMean) > 3*stats->clippedStdev) { 500 continue; 501 } 502 X->data.F64[n] = x->data.F64[i]; 503 Y->data.F64[n] = y->data.F64[i]; 504 Z->data.F64[n] = z->data.F64[i]; 505 dZ->data.F64[n] = dz->data.F64[i]; 506 n++; 507 } 508 X->n = n; 509 Y->n = n; 510 Z->n = n; 511 dZ->n = n; 512 } 513 return (poly); 514 } 515 516 // XXX EAM : be careful here with F32 vs F64 vectors 517 psPolynomial2D* RobustFit2D(psPolynomial2D* poly, 518 psVector* mask, 519 const psVector* x, 520 const psVector* y, 521 const psVector* z, 522 const psVector* dz) 523 { 524 // PS_VECTOR_CHECK_NULL(mask, NULL); 525 // PS_VECTOR_CHECK_NULL(x, NULL); 526 // PS_VECTOR_CHECK_NULL(y, NULL); 527 // PS_VECTOR_CHECK_NULL(z, NULL); 528 // PS_VECTOR_CHECK_NULL(dz, NULL); 529 530 psVector *zFit = NULL; 531 psVector *zResid = psVectorAlloc (x->n, PS_TYPE_F64); 532 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 533 534 for (int N = 0; N < 3; N++) { 535 poly = VectorFitPolynomial2DOrd_EAM (poly, mask, x, y, z, dz); 536 zFit = Polynomial2DEvalVectorD (poly, x, y); 537 zResid = (psVector *) psBinaryOp (zResid, (void *) z, "-", (void *) zFit); 538 539 stats = psVectorStats (stats, zResid, NULL, mask, 1); 540 psTrace (".psphot.RobustFit", 4, "residual stats for robust fit: %g +/- %g\n", 541 stats->sampleMean, stats->sampleStdev); 542 543 // set mask if pts are not valid 544 // we are masking out any point which is out of range 545 // recovery is not allowed with this scheme 546 for (int i = 0; i < zResid->n; i++) { 547 if (mask->data.U8[i]) continue; 548 if (fabs(zResid->data.F64[i] - stats->sampleMean) > 3*stats->sampleStdev) { 549 mask->data.U8[i] = 1; 550 continue; 551 } 552 } 553 psFree (zFit); 554 } 555 psFree (zResid); 556 psFree (stats); 557 return (poly); 558 } 559 560 // XXX EAM : VectorFitPolynomial2DOrd and Polynomial2DEvalVector require different types (F32 vs F64) 561 562 psF64 Polynomial2DEval(const psPolynomial2D* myPoly, 563 psF64 x, 564 psF64 y) 287 psF64 Polynomial2DEval_EAM(const psPolynomial2D* myPoly, 288 psF64 x, 289 psF64 y) 565 290 { 566 291 // PS_POLY_CHECK_NULL(myPoly, NAN); … … 587 312 return(polySum); 588 313 } 314 315 // XXX EAM : this version uses myPoly->nX as Norder, not Nterms 316 psVector *Polynomial2DEvalVector_EAM(const psPolynomial2D *myPoly, 317 const psVector *x, 318 const psVector *y) 319 320 { 321 // PS_POLY_CHECK_NULL(myPoly, NULL); 322 // PS_VECTOR_CHECK_NULL(x, NULL); 323 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL); 324 // PS_VECTOR_CHECK_NULL(y, NULL); 325 // PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL); 326 327 psVector *tmp; 328 psS32 vecLen=x->n; 329 330 // Determine the length of the output vector to by the minimum of the x,y vectors 331 if (y->n < vecLen) { 332 vecLen = y->n; 333 } 334 335 // Create output vector to return 336 tmp = psVectorAlloc(vecLen, PS_TYPE_F32); 337 338 // Evaluate the polynomial at the specified points 339 for (psS32 i=0; i<vecLen; i++) { 340 tmp->data.F32[i] = Polynomial2DEval_EAM(myPoly, x->data.F32[i], y->data.F32[i]); 341 } 342 343 // Return output vector 344 return(tmp); 345 } 346 347 // XXX EAM : this version uses the F64 vectors 348 psVector *Polynomial2DEvalVectorD_EAM(const psPolynomial2D *myPoly, 349 const psVector *x, 350 const psVector *y) 351 352 { 353 // PS_POLY_CHECK_NULL(myPoly, NULL); 354 // PS_VECTOR_CHECK_NULL(x, NULL); 355 // PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL); 356 // PS_VECTOR_CHECK_NULL(y, NULL); 357 // PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL); 358 359 psVector *tmp; 360 psS32 vecLen=x->n; 361 362 // Determine the length of the output vector to by the minimum of the x,y vectors 363 if (y->n < vecLen) { 364 vecLen = y->n; 365 } 366 367 // Create output vector to return 368 tmp = psVectorAlloc(vecLen, PS_TYPE_F64); 369 370 // Evaluate the polynomial at the specified points 371 for (psS32 i=0; i<vecLen; i++) { 372 tmp->data.F64[i] = Polynomial2DEval_EAM(myPoly,x->data.F64[i],y->data.F64[i]); 373 } 374 375 // Return output vector 376 return(tmp); 377 } 378 379 // XXX EAM : BuildSums2D in analogy with BuildSums1D 380 static psImage *BuildSums2D_EAM(psImage* sums, 381 psF64 x, psF64 y, 382 psS32 nXterm, psS32 nYterm) 383 { 384 psS32 nXsum = 0; 385 psS32 nYsum = 0; 386 psF64 xSum = 1.0; 387 psF64 ySum = 1.0; 388 389 nXsum = 2*nXterm; 390 nYsum = 2*nYterm; 391 if (sums == NULL) { 392 sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64); 393 } 394 if ((nXsum != sums->numCols) || (nYsum != sums->numRows)) { 395 psFree (sums); 396 sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64); 397 } 398 399 ySum = 1.0; 400 for (int j = 0; j < nYsum; j++) { 401 xSum = ySum; 402 for (int i = 0; i < nXsum; i++) { 403 sums->data.F64[i][j] = xSum; 404 xSum *= x; 405 } 406 ySum *= y; 407 } 408 return (sums); 409 } 410 411 // XXX EAM : test version of 2d fitting 412 psPolynomial2D* VectorFitPolynomial2D_EAM(psPolynomial2D* myPoly, 413 psVector* mask, 414 psMaskType maskValue, 415 const psVector* z, 416 const psVector* zErr, 417 const psVector* x, 418 const psVector* y) 419 { 420 // I think this is 1 dimension down 421 psImage* A = NULL; 422 psVector* B = NULL; 423 psImage* Sums = NULL; 424 psF64 wt; 425 psS32 nTerm, nXterm, nYterm; 426 427 nXterm = myPoly->nX + 1; 428 nYterm = myPoly->nY + 1; 429 nTerm = nXterm * nYterm; 430 431 A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64); 432 B = psVectorAlloc(nTerm, PS_TYPE_F64); 433 434 // Initialize data structures (why is this not a function!) 435 for (int i = 0; i < nTerm; i++) { 436 B->data.F64[i] = 0.0; 437 for (int j = 0; j < nTerm; j++) { 438 A->data.F64[i][j] = 0.0; 439 } 440 } 441 442 // Sums look like: 1, x, x^2, ... x^(2n+1), y, xy, x^2y, ... x^(2n+1) 443 444 // Build the B and A data structs. 445 for (int k = 0; k < x->n; k++) { 446 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) continue; 447 Sums = BuildSums2D_EAM(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm); 448 449 if (zErr == NULL) { 450 wt = 1.0; 451 } else { 452 // this should probably by zErr^2 !! 453 // this should filter zErr == 0 values 454 wt = 1.0 / zErr->data.F64[k]; 455 } 456 457 // we could skip half of the array and assign at the end 458 // we must handle masked orders 459 for (int n = 0; n < nXterm; n++) { 460 for (int m = 0; m < nYterm; m++) { 461 B->data.F64[n+m*nXterm] += z->data.F64[k] * Sums->data.F64[n][m] * wt; 462 } 463 } 464 465 for (int i = 0; i < nXterm; i++) { 466 for (int j = 0; j < nYterm; j++) { 467 for (int n = 0; n < nXterm; n++) { 468 for (int m = 0; m < nYterm; m++) { 469 A->data.F64[i+j*nXterm][n+m*nXterm] += Sums->data.F64[i+n][j+m] * wt; 470 } 471 } 472 } 473 } 474 } 475 476 // does the solution in place 477 psGaussJordan (A, B); 478 479 // XXX: How do we know if these routines were successful? 480 // ALUD = psMatrixLUD(ALUD, &outPerm, A); 481 // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm); 482 483 for (int n = 0; n < nXterm; n++) { 484 for (int m = 0; m < nYterm; m++) { 485 myPoly->coeff[n][m] = B->data.F64[n+m*nXterm]; 486 } 487 } 488 489 psFree(A); 490 psFree(B); 491 psFree(Sums); 492 493 psTrace(".psLib.dataManip.VectorFitPolynomial2DOrd", 4, 494 "---- VectorFitPolynomial2DOrd() begin ----\n"); 495 return (myPoly); 496 } 497 498 // XXX EAM : be careful here with F32 vs F64 vectors 499 psPolynomial2D* VectorClipFitPolynomial2D_EAM(psPolynomial2D* poly, 500 psStats *stats, 501 psVector* mask, 502 psMaskType maskValue, 503 const psVector* z, 504 const psVector* dz, 505 const psVector* x, 506 const psVector* y) 507 { 508 psVector *zFit = NULL; 509 psVector *zResid = psVectorAlloc (x->n, PS_TYPE_F64); 510 511 // XXX EAM : use SAMPLE_MEAN and SAMPLE_STDEV for stats: 512 stats->options |= (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 513 514 for (int N = 0; N < 3; N++) { 515 poly = VectorFitPolynomial2D_EAM (poly, mask, maskValue, z, dz, x, y); 516 zFit = Polynomial2DEvalVectorD_EAM (poly, x, y); 517 zResid = (psVector *) psBinaryOp (zResid, (void *) z, "-", (void *) zFit); 518 519 stats = psVectorStats (stats, zResid, NULL, mask, maskValue); 520 psTrace (".psphot.RobustFit", 4, "residual stats for robust fit: %g +/- %g\n", 521 stats->sampleMean, stats->sampleStdev); 522 523 // set mask if pts are not valid 524 // we are masking out any point which is out of range 525 // recovery is not allowed with this scheme 526 for (int i = 0; i < zResid->n; i++) { 527 if (mask->data.U8[i]) continue; 528 if (fabs(zResid->data.F64[i] - stats->sampleMean) > 3*stats->sampleStdev) { 529 mask->data.U8[i] &= 0x01; 530 continue; 531 } 532 } 533 psFree (zFit); 534 } 535 psFree (zResid); 536 return (poly); 537 } 538 539 // XXX EAM : VectorFitPolynomial2D and Polynomial2DEvalVector require different types (F32 vs F64)
Note:
See TracChangeset
for help on using the changeset viewer.
