Changeset 15041 for trunk/psLib/src/imageops/psImageMapFit.c
- Timestamp:
- Sep 26, 2007, 6:27:03 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageMapFit.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageMapFit.c
r15001 r15041 7 7 * @author Eugene Magnier, IfA 8 8 * 9 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $10 * @date $Date: 2007-09-2 4 21:29:10$9 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-09-27 04:27:03 $ 11 11 * 12 12 * Copyright 2007 Institute for Astronomy, University of Hawaii … … 68 68 69 69 if (Nx == 1) { 70 psAbort ("un-implemented edge case"); 71 goto insert; 70 bool status; 71 status = psImageMapFit1DinY (map, mask, maskValue, x, y, f, df); 72 return status; 72 73 } 73 74 if (Ny == 1) { 74 psAbort ("un-implemented edge case"); 75 goto insert; 75 bool status; 76 status = psImageMapFit1DinX (map, mask, maskValue, x, y, f, df); 77 return status; 76 78 } 77 79 … … 231 233 sA[+1][+1] = dx_rx_dy_ry; 232 234 233 insert:234 235 // I[ 0][ 0] = index for this n,m element: 235 236 I = n + Nx * m; … … 271 272 } 272 273 273 # if (0)274 # if (0) 274 275 psFits *fits = psFitsOpen ("Agj.fits", "w"); 275 276 psFitsWriteImage (fits, NULL, A, 0, NULL); … … 285 286 psFitsClose (fits); 286 287 psFree (vector); 287 # endif288 # endif 288 289 289 290 if (!psMatrixGJSolveF32(A, B)) { … … 433 434 return true; 434 435 } 436 437 // map defines the output image dimensions and scaling. 438 bool psImageMapFit1DinY (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) { 439 440 int I, J; 441 442 // XXX Add Asserts 443 assert (map->binning->nXruff == 1); 444 445 // dimensions of the output map image 446 int Ny = map->binning->nYruff; 447 448 // set up the redirection table so we can use sA[-1][-1], etc 449 float SAv[3], *sA; 450 451 sA = SAv + 1; 452 453 // elements of the matrix equation Ax = B; we are solving for the vector x 454 psImage *A = psImageAlloc (Ny, Ny, PS_TYPE_F32); 455 psVector *B = psVectorAlloc (Ny, PS_TYPE_F32); 456 457 psImageInit (A, 0.0); 458 psVectorInit (B, 0.0); 459 460 for (int m = 0; m < Ny; m++) { 461 // define & init summing variables 462 float ry_ry = 0; 463 float dy_ry = 0; 464 float fi_ry = 0; 465 float py_py = 0; 466 float qy_py = 0; 467 float fi_py = 0; 468 469 // generate the sums for the fitting matrix element I,J 470 // I = m 471 // J = m + jm 472 for (int i = 0; i < y->n; i++) { 473 474 if (mask && (mask->data.U8[i] & maskValue)) continue; 475 476 float dy = psImageBinningGetRuffY (map->binning, y->data.F32[i]) - (m + 0.5); 477 478 bool edgeY = false; 479 edgeY |= ((m == 1) && (dy < -1.0)); 480 edgeY |= ((m == Ny - 2) && (dy > +1.0)); 481 482 // skip points outside of 2x2 grid centered on n,m: 483 if (!edgeY && (fabs(dy) > 1.0)) continue; 484 485 // related offset values 486 float ry = 1.0 - dy; 487 float py = 1.0 + dy; 488 float qy = -dy; 489 490 // data value & weight for this point 491 float fi = f->data.F32[i]; 492 float wt = 1.0; 493 if (df != NULL) { 494 if (df->data.F32[i] == 0.0) { 495 wt = 0.0; 496 } else { 497 wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0 498 } 499 } 500 501 // sum the appropriate elements for the different quadrants 502 int Qy = (dy >= 0) ? 1 : 0; 503 if (m == 0) Qy = 1; 504 if (m == Ny - 1) Qy = 0; 505 506 assert (isfinite(fi)); 507 assert (isfinite(wt)); 508 assert (isfinite(ry)); 509 510 // points at offset 1,1 511 if (Qy == 1) { 512 ry_ry += ry*ry*wt; 513 dy_ry += dy*ry*wt; 514 fi_ry += fi*ry*wt; 515 } 516 // points at offset 1,0 517 if (Qy == 0) { 518 py_py += py*py*wt; 519 qy_py += qy*py*wt; 520 fi_py += fi*py*wt; 521 } 522 } 523 524 // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm), 525 // jn,jm = -1 to +1. Convert the sums above into the correct coefficients 526 sA[-1] = qy_py; 527 sA[ 0] = ry_ry + py_py; 528 sA[+1] = dy_ry; 529 530 // I[ 0][ 0] = index for this n,m element: 531 I = m; 532 B->data.F32[I] = fi_ry + fi_py; 533 534 // insert these values into their corresponding locations in A, B 535 for (int jm = -1; jm <= +1; jm++) { 536 if (m + jm < 0) continue; 537 if (m + jm >= Ny) continue; 538 J = (m + jm); 539 A->data.F32[J][I] = sA[jm]; 540 } 541 } 542 543 // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0 544 psVector *Empty = psVectorAlloc (Ny, PS_TYPE_S8); 545 psVectorInit (Empty, 0); 546 for (int i = 0; i < Ny; i++) { 547 if (A->data.F32[i][i] == 0.0) { 548 Empty->data.S8[i] = 1; 549 for (int j = 0; j < Ny; j++) { 550 A->data.F32[i][j] = 0.0; 551 A->data.F32[j][i] = 0.0; 552 } 553 A->data.F32[i][i] = 1.0; 554 B->data.F32[i] = 0.0; 555 } 556 } 557 558 if (!psMatrixGJSolveF32(A, B)) { 559 psAbort ("failed on linear equations"); 560 psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations. Returning NULL.\n"); 561 psFree (A); 562 psFree (B); 563 return false; 564 } 565 566 // set bad values to NaN 567 for (int i = 0; i < Ny; i++) { 568 if (Empty->data.S8[i]) { 569 B->data.F32[i] = NAN; 570 } 571 } 572 573 for (int m = 0; m < Ny; m++) { 574 map->map->data.F32[m][0] = B->data.F32[m]; 575 map->error->data.F32[m][0] = sqrt(A->data.F32[m][m]); 576 } 577 578 psFree (A); 579 psFree (B); 580 psFree (Empty); 581 582 return true; 583 } 584 585 // map defines the output image dimensions and scaling. 586 bool psImageMapFit1DinX (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) { 587 588 int I, J; 589 590 // XXX Add Asserts 591 assert (map->binning->nXruff == 1); 592 593 // dimensions of the output map image 594 int Nx = map->binning->nXruff; 595 596 // set up the redirection table so we can use sA[-1][-1], etc 597 float SAv[3], *sA; 598 599 sA = SAv + 1; 600 601 // elements of the matrix equation Ax = B; we are solving for the vector x 602 psImage *A = psImageAlloc (Nx, Nx, PS_TYPE_F32); 603 psVector *B = psVectorAlloc (Nx, PS_TYPE_F32); 604 605 psImageInit (A, 0.0); 606 psVectorInit (B, 0.0); 607 608 for (int m = 0; m < Nx; m++) { 609 // define & init summing variables 610 float rx_rx = 0; 611 float dx_rx = 0; 612 float fi_rx = 0; 613 float px_px = 0; 614 float qx_px = 0; 615 float fi_px = 0; 616 617 // generate the sums for the fitting matrix element I,J 618 // I = m 619 // J = m + jm 620 for (int i = 0; i < x->n; i++) { 621 622 if (mask && (mask->data.U8[i] & maskValue)) continue; 623 624 float dx = psImageBinningGetRuffX (map->binning, x->data.F32[i]) - (m + 0.5); 625 626 bool edgeX = false; 627 edgeX |= ((m == 1) && (dx < -1.0)); 628 edgeX |= ((m == Nx - 2) && (dx > +1.0)); 629 630 // skip points outside of 2x2 grid centered on n,m: 631 if (!edgeX && (fabs(dx) > 1.0)) continue; 632 633 // related offset values 634 float rx = 1.0 - dx; 635 float px = 1.0 + dx; 636 float qx = -dx; 637 638 // data value & weight for this point 639 float fi = f->data.F32[i]; 640 float wt = 1.0; 641 if (df != NULL) { 642 if (df->data.F32[i] == 0.0) { 643 wt = 0.0; 644 } else { 645 wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0 646 } 647 } 648 649 // sum the appropriate elements for the different quadrants 650 int Qx = (dx >= 0) ? 1 : 0; 651 if (m == 0) Qx = 1; 652 if (m == Nx - 1) Qx = 0; 653 654 assert (isfinite(fi)); 655 assert (isfinite(wt)); 656 assert (isfinite(rx)); 657 658 // points at offset 1,1 659 if (Qx == 1) { 660 rx_rx += rx*rx*wt; 661 dx_rx += dx*rx*wt; 662 fi_rx += fi*rx*wt; 663 } 664 // points at offset 1,0 665 if (Qx == 0) { 666 px_px += px*px*wt; 667 qx_px += qx*px*wt; 668 fi_px += fi*px*wt; 669 } 670 } 671 672 // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm), 673 // jn,jm = -1 to +1. Convert the sums above into the correct coefficients 674 sA[-1] = qx_px; 675 sA[ 0] = rx_rx + px_px; 676 sA[+1] = dx_rx; 677 678 // I[ 0][ 0] = index for this n,m element: 679 I = m; 680 B->data.F32[I] = fi_rx + fi_px; 681 682 // insert these values into their corresponding locations in A, B 683 for (int jm = -1; jm <= +1; jm++) { 684 if (m + jm < 0) continue; 685 if (m + jm >= Nx) continue; 686 J = (m + jm); 687 A->data.F32[J][I] = sA[jm]; 688 } 689 } 690 691 // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0 692 psVector *Empty = psVectorAlloc (Nx, PS_TYPE_S8); 693 psVectorInit (Empty, 0); 694 for (int i = 0; i < Nx; i++) { 695 if (A->data.F32[i][i] == 0.0) { 696 Empty->data.S8[i] = 1; 697 for (int j = 0; j < Nx; j++) { 698 A->data.F32[i][j] = 0.0; 699 A->data.F32[j][i] = 0.0; 700 } 701 A->data.F32[i][i] = 1.0; 702 B->data.F32[i] = 0.0; 703 } 704 } 705 706 if (!psMatrixGJSolveF32(A, B)) { 707 psAbort ("failed on linear equations"); 708 psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations. Returning NULL.\n"); 709 psFree (A); 710 psFree (B); 711 return false; 712 } 713 714 // set bad values to NaN 715 for (int i = 0; i < Nx; i++) { 716 if (Empty->data.S8[i]) { 717 B->data.F32[i] = NAN; 718 } 719 } 720 721 for (int m = 0; m < Nx; m++) { 722 map->map->data.F32[0][m] = B->data.F32[I]; 723 map->error->data.F32[0][m] = sqrt(A->data.F32[I][I]); 724 } 725 726 psFree (A); 727 psFree (B); 728 psFree (Empty); 729 730 return true; 731 } 732
Note:
See TracChangeset
for help on using the changeset viewer.
