Changeset 37827
- Timestamp:
- Jan 12, 2015, 12:35:53 PM (12 years ago)
- Location:
- branches/eam_branches/ipp-pv3-20140717-merge/psLib
- Files:
-
- 8 edited
-
share/tai_utc.dat (modified) (1 diff)
-
share/tai_utc.raw (modified) (1 diff)
-
src/imageops/psImageMapFit.c (modified) (9 diffs)
-
src/imageops/psImageMapFit.h (modified) (1 diff)
-
src/math/psEllipse.c (modified) (1 diff)
-
src/math/psEllipse.h (modified) (1 diff)
-
src/math/psMinimizePolyFit.c (modified) (5 diffs, 1 prop)
-
src/mathtypes/psImage.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-pv3-20140717-merge/psLib/share/tai_utc.dat
r34664 r37827 51 51 2453736.5 33.0000000 41317.0 0.0000000 52 52 2454832.5 34.0000000 41317.0 0.0000000 53 2456109.5 35.0000000 41317.0 0.0000000 53 2456109.5 35.0000000 41317.0 0.0000000 54 2457204.5 36.0000000 41317.0 0.0000000 -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/share/tai_utc.raw
r34664 r37827 38 38 2009 JAN 1 =JD 2454832.5 TAI-UTC= 34.0 S + (MJD - 41317.) X 0.0 S 39 39 2012 JUL 1 =JD 2456109.5 TAI-UTC= 35.0 S + (MJD - 41317.) X 0.0 S 40 2015 JUL 1 =JD 2457204.5 TAI-UTC= 36.0 S + (MJD - 41317.) X 0.0 S -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/imageops/psImageMapFit.c
r34153 r37827 18 18 19 19 #include <stdio.h> 20 #include <stdlib.h> 20 21 #include "psError.h" 21 22 #include "psAbort.h" … … 35 36 #include "psImageStructManip.h" 36 37 #include "psImageMap.h" 38 #include "psSparse.h" 37 39 // #include "psImagePixelInterpolate.h" 38 40 // #include "psImageUnbin.h" … … 118 120 psImageInit (A, 0.0); 119 121 psVectorInit (B, 0.0); 120 122 121 123 // we are looping over the Nx,Ny image map elements; 122 124 // the matrix equation contains Nx*Ny rows and columns … … 262 264 int I = n + Nx * m; 263 265 B->data.F32[I] = fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py; 264 266 265 267 // insert these values into their corresponding locations in A, B 266 268 // float Sum = 0.0; … … 273 275 int J = (n + jn) + Nx * (m + jm); 274 276 A->data.F32[J][I] = sA[jn][jm]; 277 275 278 // fprintf (stderr, "A %d %d (%d %d : %d %d): %f\n", I, J, n, m, n + jn, m + jm, sA[jn][jm]); 276 279 // Sum += sA[jn][jm]; … … 282 285 } 283 286 // fprintf (stderr, "Total: %f\n", Total); 287 288 double MaxPivot = 0.0; 289 for (int i = 0; i < Nx*Ny; i++) { 290 MaxPivot = PS_MAX(MaxPivot, fabs(A->data.F32[i][i])); 291 // fprintf (stderr, "piv, max: %f : %f\n", A->data.F32[i][i], MaxPivot); 292 } 284 293 285 294 // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0 286 295 psVector *Empty = psVectorAlloc (Nx*Ny, PS_TYPE_S8); 287 296 psVectorInit (Empty, 0); 297 double MinPivot = 0.025*MaxPivot; 288 298 for (int i = 0; i < Nx*Ny; i++) { 289 if (A->data.F32[i][i] == 0.0) {299 if (fabs(A->data.F32[i][i]) < MinPivot) { 290 300 Empty->data.S8[i] = 1; 291 301 for (int j = 0; j < Nx*Ny; j++) { … … 320 330 return true; 321 331 } 322 332 323 333 // set bad values to NaN 324 334 for (int i = 0; i < Nx*Ny; i++) { … … 341 351 psFree (B); 342 352 psFree (Empty); 343 344 353 *pGoodFit = true; 345 354 return true; … … 402 411 psS32 Nkeep = 0; 403 412 if (!psImageMapFit(pGoodFit, map, mask, maskValue, x, y, f, df)) { 413 psError(PS_ERR_UNKNOWN, false, "Could not fit image map.\n"); 414 psFree(resid); 415 if (!inMask) psFree (mask); 416 return false; 417 } 418 if (!*pGoodFit) { 419 psWarning ("bad fit to image map, try something else"); 420 psFree(resid); 421 if (!inMask) psFree (mask); 422 return true; 423 } 424 425 psVector *fit = psImageMapEvalVector(map, mask, maskValue, x, y); 426 if (fit == NULL) { 427 psError(PS_ERR_UNKNOWN, false, "Failure in psImageMapEvalVector().\n"); 428 psFree(resid); 429 if (!inMask) psFree (mask); 430 return false; 431 } 432 for (int i = 0 ; i < f->n ; i++) { 433 resid->data.F32[i] = (f->data.F32[i] - fit->data.F32[i]); 434 } 435 436 if (!psVectorStats(stats, resid, NULL, mask, maskValue)) { 437 psError(PS_ERR_UNKNOWN, false, "Failure to compute statistics on the resid vector.\n"); 438 psFree(resid); 439 psFree(fit); 440 if (!inMask) psFree (mask); 441 return false; 442 } 443 444 double meanValue = psStatsGetValue (stats, meanOption); 445 double stdevValue = psStatsGetValue (stats, stdevOption); 446 447 psTrace("psLib.imageops", 5, "Mean is %f\n", meanValue); 448 psTrace("psLib.imageops", 5, "Stdev is %f\n", stdevValue); 449 psF32 minClipValue = -minClipSigma*stdevValue; 450 psF32 maxClipValue = +maxClipSigma*stdevValue; 451 452 // set mask if pts are not valid 453 // we are masking out any point which is out of range 454 // recovery is not allowed with this scheme 455 for (psS32 i = 0; i < resid->n; i++) { 456 // XXX this prevents recovery of previously masked values 457 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue) { 458 continue; 459 } 460 461 if ((resid->data.F32[i] - meanValue > maxClipValue) || (resid->data.F32[i] - meanValue < minClipValue)) { 462 psTrace("psLib.imageops", 6, "Masking element %d : %f vs %f : resid is %f\n", i, f->data.F32[i], fit->data.F32[i], resid->data.F32[i]); 463 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= 0x01; 464 continue; 465 } 466 Nkeep++; 467 } 468 469 // We should probably exit this loop if no new elements were masked since the fit won't 470 // change. 471 psTrace("psLib.imageops", 6, "keeping %d of %ld pts for fit\n", Nkeep, x->n); 472 stats->clippedNvalues = Nkeep; 473 psFree(fit); 474 } 475 476 // Free local temporary variables 477 psFree(resid); 478 if (!inMask) psFree (mask); 479 *pGoodFit = true; // XXX probably don't need to set this (set by psImageMapFit) 480 return true; 481 } 482 483 // CZW: 2014-10-09 484 // Sparse versions of MapFit and MapFitClip that assume the matrices are not filled. 485 bool psImageMapFitSparse(bool *pGoodFit, psImageMap *map, const psVector *mask, psVectorMaskType maskValue, 486 const psVector *x, const psVector *y, const psVector *f, const psVector *df) 487 { 488 // XXX Add Asserts 489 490 *pGoodFit = false; 491 492 // dimensions of the output map image 493 int Nx = map->binning->nXruff; 494 int Ny = map->binning->nYruff; 495 496 497 // no spatial information, just calculate mean & stdev 498 if ((Nx == 1) && (Ny == 1)) { 499 psStatsInit(map->stats); 500 501 // the user has supplied one of various stats option pairs, 502 psStatsOptions mean = psStatsMeanOption(map->stats->options); 503 psStatsOptions stdev = psStatsStdevOption(map->stats->options); 504 if (!psStatsSingleOption(mean)) { 505 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); 506 return false; 507 } 508 if (!psStatsSingleOption(stdev)) { 509 psError(PS_ERR_UNKNOWN, true, "no valid stdev stats option selected"); 510 return false; 511 } 512 513 // XXX does ROBUST_MEDIAN work with weight? 514 if (!psVectorStats(map->stats, f, NULL, mask, maskValue)) { 515 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 516 return false; 517 } 518 519 map->map->data.F32[0][0] = psStatsGetValue(map->stats, mean); 520 map->error->data.F32[0][0] = psStatsGetValue(map->stats, stdev); 521 if (isfinite(map->map->data.F32[0][0]) && isfinite( map->error->data.F32[0][0])) { 522 *pGoodFit = true; 523 } 524 return true; 525 } 526 527 if (Nx == 1) { 528 bool status; 529 status = psImageMapFit1DinY (pGoodFit, map, mask, maskValue, x, y, f, df); 530 return status; 531 } 532 if (Ny == 1) { 533 bool status; 534 status = psImageMapFit1DinX (pGoodFit, map, mask, maskValue, x, y, f, df); 535 return status; 536 } 537 538 // set up the redirection table so we can use sA[-1][-1], etc 539 // XXX psKernel does this for you --- PAP. 540 float SAm[3][3], *SAv[3], **sA; 541 542 for (int i = 0; i < 3; i++) { 543 SAv[i] = SAm[i] + 1; 544 } 545 sA = SAv + 1; 546 547 // elements of the matrix equation Ax = B; we are solving for the vector x 548 // psImage *A = psImageAlloc (Nx*Ny, Nx*Ny, PS_TYPE_F32); 549 // psVector *B = psVectorAlloc (Nx*Ny, PS_TYPE_F32); 550 551 // psImageInit (A, 0.0); 552 // psVectorInit (B, 0.0); 553 554 // CZW: call to psSparseAlloc 555 // It should match old A, and each element of that should only touch four others. 556 psSparse *Asparse = psSparseAlloc(Nx * Ny, 4 * Nx * Ny); 557 558 // we are looping over the Nx,Ny image map elements; 559 // the matrix equation contains Nx*Ny rows and columns 560 561 for (int n = 0; n < Nx; n++) { 562 for (int m = 0; m < Ny; m++) { 563 // define & init summing variables 564 float rx_rx_ry_ry = 0; 565 float rx_rx_dy_ry = 0; 566 float dx_rx_ry_ry = 0; 567 float dx_rx_dy_ry = 0; 568 float fi_rx_ry = 0; 569 float rx_rx_py_py = 0; 570 float rx_rx_qy_py = 0; 571 float dx_rx_py_py = 0; 572 float dx_rx_qy_py = 0; 573 float fi_rx_py = 0; 574 float px_px_ry_ry = 0; 575 float px_px_dy_ry = 0; 576 float qx_px_ry_ry = 0; 577 float qx_px_dy_ry = 0; 578 float fi_px_ry = 0; 579 float px_px_py_py = 0; 580 float px_px_qy_py = 0; 581 float qx_px_py_py = 0; 582 float qx_px_qy_py = 0; 583 float fi_px_py = 0; 584 585 // generate the sums for the fitting matrix element I,J 586 // I = n + nX*m 587 // J = (n + jn) + nX*(m + jm) 588 for (int i = 0; i < x->n; i++) { 589 590 if (mask && (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue)) continue; 591 592 // base coordinate offset for this point (x,y) relative to this map element (n,m) 593 float dx = psImageBinningGetRuffX (map->binning, x->data.F32[i]) - (n + 0.5); 594 float dy = psImageBinningGetRuffY (map->binning, y->data.F32[i]) - (m + 0.5); 595 596 // edge cases to include: 597 bool edgeX = false; 598 edgeX |= ((n == 1) && (dx < -1.0)); 599 edgeX |= ((n == Nx - 2) && (dx > +1.0)); 600 601 bool edgeY = false; 602 edgeY |= ((m == 1) && (dy < -1.0)); 603 edgeY |= ((m == Ny - 2) && (dy > +1.0)); 604 605 // skip points outside of 2x2 grid centered on n,m: 606 if (!edgeX && (fabs(dx) > 1.0)) continue; 607 if (!edgeY && (fabs(dy) > 1.0)) continue; 608 609 // related offset values 610 float rx = 1.0 - dx; 611 float ry = 1.0 - dy; 612 float px = 1.0 + dx; 613 float py = 1.0 + dy; 614 float qx = -dx; 615 float qy = -dy; 616 617 // data value & weight for this point 618 float fi = f->data.F32[i]; 619 if (!isfinite(fi)) continue; 620 621 float wt = 1.0; 622 if (df != NULL) { 623 if (df->data.F32[i] == 0.0) { 624 wt = 0.0; 625 } else { 626 if (!isfinite(df->data.F32[i])) continue; 627 wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0 628 } 629 } 630 631 // sum the appropriate elements for the different quadrants 632 633 int Qx = (dx >= 0) ? 1 : 0; 634 if (n == 0) Qx = 1; 635 if (n == Nx - 1) Qx = 0; 636 637 int Qy = (dy >= 0) ? 1 : 0; 638 if (m == 0) Qy = 1; 639 if (m == Ny - 1) Qy = 0; 640 641 assert (isfinite(fi)); 642 assert (isfinite(wt)); 643 assert (isfinite(rx)); 644 assert (isfinite(ry)); 645 646 // points at offset 1,1 647 if ((Qx == 1) && (Qy == 1)) { 648 rx_rx_ry_ry += rx*rx*ry*ry*wt; 649 rx_rx_dy_ry += rx*rx*dy*ry*wt; 650 dx_rx_ry_ry += dx*rx*ry*ry*wt; 651 dx_rx_dy_ry += dx*rx*dy*ry*wt; 652 fi_rx_ry += fi*rx*ry*wt; 653 } 654 // points at offset 1,0 655 if ((Qx == 1) && (Qy == 0)) { 656 rx_rx_py_py += rx*rx*py*py*wt; 657 rx_rx_qy_py += rx*rx*qy*py*wt; 658 dx_rx_py_py += dx*rx*py*py*wt; 659 dx_rx_qy_py += dx*rx*qy*py*wt; 660 fi_rx_py += fi*rx*py*wt; 661 } 662 // points at offset 0,1 663 if ((Qx == 0) && (Qy == 1)) { 664 px_px_ry_ry += px*px*ry*ry*wt; 665 px_px_dy_ry += px*px*dy*ry*wt; 666 qx_px_ry_ry += qx*px*ry*ry*wt; 667 qx_px_dy_ry += qx*px*dy*ry*wt; 668 fi_px_ry += fi*px*ry*wt; 669 } 670 // points at offset 0,0 671 if ((Qx == 0) && (Qy == 0)) { 672 px_px_py_py += px*px*py*py*wt; 673 px_px_qy_py += px*px*qy*py*wt; 674 qx_px_py_py += qx*px*py*py*wt; 675 qx_px_qy_py += qx*px*qy*py*wt; 676 fi_px_py += fi*px*py*wt; 677 } 678 } 679 680 // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm), 681 // jn,jm = -1 to +1. Convert the sums above into the correct coefficients 682 sA[-1][-1] = qx_px_qy_py; 683 sA[-1][ 0] = qx_px_ry_ry + qx_px_py_py; 684 sA[-1][+1] = qx_px_dy_ry; 685 sA[ 0][-1] = rx_rx_qy_py + px_px_qy_py; 686 sA[ 0][ 0] = rx_rx_ry_ry + px_px_ry_ry + rx_rx_py_py + px_px_py_py; 687 sA[ 0][+1] = rx_rx_dy_ry + px_px_dy_ry; 688 sA[+1][-1] = dx_rx_qy_py; 689 sA[+1][ 0] = dx_rx_ry_ry + dx_rx_py_py; 690 sA[+1][+1] = dx_rx_dy_ry; 691 692 // I[ 0][ 0] = index for this n,m element: 693 int I = n + Nx * m; 694 // B->data.F32[I] = fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py; 695 // CZW: call to psSparseVector Element 696 if (fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py == 0.0) { 697 psSparseVectorElement(Asparse, I, 1.0); 698 } 699 else { 700 psSparseVectorElement(Asparse, I, fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py); 701 } 702 703 // printf("ADDING: %d %g \n",I, fi_rx_ry + fi_rx_py + fi_px_ry + fi_px_py); 704 // insert these values into their corresponding locations in A, B 705 for (int jn = -1; jn <= +1; jn++) { 706 if (n + jn < 0) continue; 707 if (n + jn >= Nx) continue; 708 for (int jm = -1; jm <= +1; jm++) { 709 if (m + jm < 0) continue; 710 if (m + jm >= Ny) continue; 711 int J = (n + jn) + Nx * (m + jm); 712 // printf("A: %d %d %g\n",J,I,sA[jn][jm]); 713 // A->data.F32[J][I] = sA[jn][jm]; 714 // CZW: call to psSparseMatrixElement 715 if (J < I) { continue; } 716 psSparseMatrixElement(Asparse,J,I,sA[jn][jm]); // Ensure J < I? 717 718 } 719 } 720 } 721 } 722 723 // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0 724 // CZW: I'm not totally sure how to check these in the sparse context. 725 // Iterate over all ii pairs, and manually check the structure? 726 #if (0) 727 psVector *Empty = psVectorAlloc (Nx*Ny, PS_TYPE_S8); 728 psVectorInit (Empty, 0); 729 for (int i = 0; i < Nx*Ny; i++) { 730 if (A->data.F32[i][i] == 0.0) { 731 Empty->data.S8[i] = 1; 732 for (int j = 0; j < Nx*Ny; j++) { 733 A->data.F32[i][j] = 0.0; 734 A->data.F32[j][i] = 0.0; 735 } 736 A->data.F32[i][i] = 1.0; 737 B->data.F32[i] = 0.0; 738 } 739 } 740 #endif 741 742 // CZW: call to psSparseSolve 743 psVector *solution = psVectorAlloc(Nx*Ny, PS_TYPE_F32); 744 psSparseConstraint Constraint; 745 Constraint.paramDelta = 1e-3; 746 Constraint.paramMin = -1e5; 747 Constraint.paramMax = 1e5; 748 solution = psSparseSolve(solution, Constraint, Asparse, 1000); 749 if (!solution) { 750 psFree(solution); 751 psFree(Asparse); 752 return(false); 753 } 754 755 #if (0) 756 // CZW: This is a continuation of the above information 757 // set bad values to NaN 758 for (int i = 0; i < Nx*Ny; i++) { 759 if (Empty->data.S8[i]) { 760 B->data.F32[i] = NAN; 761 A->data.F32[i][i] = 0; 762 } 763 } 764 #endif 765 766 for (int n = 0; n < Nx; n++) { 767 for (int m = 0; m < Ny; m++) { 768 int I = n + Nx * m; 769 map->map->data.F32[m][n] = solution->data.F32[I]; 770 map->error->data.F32[m][n] = NAN; // sqrt(A->data.F32[I][I]); // CZW: fix this to be a real error. 771 } 772 } 773 774 // psFree (A); 775 // psFree (B); 776 // psFree (Empty); 777 // CZW: free things 778 psFree(solution); 779 psFree(Asparse); 780 781 *pGoodFit = true; 782 return true; 783 } 784 785 // measure residuals on each pass and clip outliers based on stats 786 bool psImageMapClipFitSparse(bool *pGoodFit, psImageMap *map, psStats *stats, psVector *inMask, psVectorMaskType maskValue, 787 const psVector *x, const psVector *y, const psVector *f, const psVector *df) 788 { 789 // XXX add in full PS_ASSERTS 790 psAssert(map, "impossible"); 791 psAssert(stats, "impossible"); 792 psAssert(x, "impossible"); 793 psAssert(y, "impossible"); 794 psAssert(f, "impossible"); 795 796 *pGoodFit = false; 797 798 // the user supplies one of various stats option pairs, 799 // determine the desired mean and stdev STATS options: 800 psStatsOptions meanOption = psStatsMeanOption(stats->options); 801 psStatsOptions stdevOption = psStatsStdevOption(stats->options); 802 if (!psStatsSingleOption(meanOption)) { 803 psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected"); 804 return false; 805 } 806 if (!psStatsSingleOption(stdevOption)) { 807 psError(PS_ERR_UNKNOWN, true, "no valid stdev stats option selected"); 808 return false; 809 } 810 811 // clipping range defined by min and max and/or clipSigma 812 psF32 minClipSigma; 813 psF32 maxClipSigma; 814 if (isfinite(stats->max)) { 815 maxClipSigma = fabs(stats->max); 816 } else { 817 maxClipSigma = fabs(stats->clipSigma); 818 } 819 if (isfinite(stats->min)) { 820 minClipSigma = fabs(stats->min); 821 } else { 822 minClipSigma = fabs(stats->clipSigma); 823 } 824 825 psVector *mask = inMask; 826 if (!inMask) { 827 mask = psVectorAlloc (x->n, PS_TYPE_VECTOR_MASK); 828 psVectorInit (mask, 0); 829 } 830 831 // vector to store residuals 832 psVector *resid = psVectorAlloc(f->n, PS_TYPE_F32); 833 834 psTrace("psLib.imageops", 4, "stats->clipIter is %d\n", stats->clipIter); 835 psTrace("psLib.imageops", 4, "(minClipSigma, maxClipSigma) is (%.2f, %.2f)\n", minClipSigma, maxClipSigma); 836 837 for (psS32 N = 0; N < stats->clipIter; N++) { 838 psTrace("psLib.imageops", 6, "Loop iteration %d. Calling psImageMapFit()\n", N); 839 psS32 Nkeep = 0; 840 if (!psImageMapFitSparse(pGoodFit, map, mask, maskValue, x, y, f, df)) { 404 841 psError(PS_ERR_UNKNOWN, false, "Could not fit image map.\n"); 405 842 psFree(resid); -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/imageops/psImageMapFit.h
r30044 r37827 20 20 // fit the image map to a set of points 21 21 bool psImageMapClipFit(bool *pGoodFit, 22 psImageMap *map, 23 psStats *stats, 24 psVector *mask, // WARNING: Mask is modified! 25 psVectorMaskType maskValue, 26 const psVector *x, 27 const psVector *y, 28 const psVector *f, 29 const psVector *df 30 ); 31 32 33 // fit the image map to a set of points, using sparse matrix tools 34 bool psImageMapFitSparse(bool *pGoodFit, 35 psImageMap *map, 36 const psVector *mask, 37 psVectorMaskType maskValue, // 38 const psVector *x, 39 const psVector *y, 40 const psVector *f, 41 const psVector *df 42 ); 43 44 // fit the image map to a set of points using sparse matrix tools 45 bool psImageMapClipFitSparse(bool *pGoodFit, 22 46 psImageMap *map, 23 47 psStats *stats, -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/math/psEllipse.c
r36375 r37827 134 134 assert (isfinite(axes.major)); 135 135 assert (isfinite(axes.minor)); 136 137 return axes; 138 } 139 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta) 140 psEllipseAxes psEllipseShapeToAxesWithErrors(psEllipseShape shape, psEllipseShape shapeErrors, double maxAR, psEllipseAxes *pShapeErrors) 141 { 142 psEllipseAxes axes; 143 psEllipseAxes errors; 144 145 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx); 146 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx); 147 148 double f32 = PS_SQR(f2) + 4*PS_SQR(shape.sxy); 149 double f3 = sqrt(f32); 150 151 double df1 = - 2.0 * shapeErrors.sy / (PS_SQR(shape.sy) * shape.sy) 152 - 2.0 * shapeErrors.sx / (PS_SQR(shape.sx) * shape.sx); 153 double df2 = - 2.0 * shapeErrors.sy / (PS_SQR(shape.sy) * shape.sy) 154 + 2.0 * shapeErrors.sx / (PS_SQR(shape.sx) * shape.sx); 155 156 // df3 = 0.5 * df32 / sqrt(f32) = 0.5 * df32 / f3 157 double df3 = 0.5 * (2.0*f2*df2 + 2 * 4 * shape.sxy * shapeErrors.sxy) / f3; 158 159 double f13 = f1 + f3; 160 axes.minor = sqrt (2.0 / f13); 161 162 // dminor = -0.5 * sqrt (2) * df13 * f13**-3/2 = - 0.5 * df13 * minor / f13 163 errors.minor = - 0.5 * (df1 + df3) * axes.minor / f13; 164 165 axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2); 166 167 // according to wikipedia the derivitive of atan2(y, x) is 168 // 169 // dAtan2(y, x) = - y * dx / (x**2 + y**2)) + x * dy / (x**2 + y**2) (for x > 0 and y!=0) 170 // where 171 // y = 2 * sxy dy = 2 * dsxy x = f2 so dx = df2 172 173 // dtheta = -0.5 * dAtan2(y, x) 174 175 errors.theta = -0.5 * ( -2.0 * shape.sxy * df2 + f2 * 2 *shapeErrors.sxy ) / 176 (PS_SQR(f2) + 4 * PS_SQR(shape.sxy)) ; 177 178 // long, thin objects are likely to have a poorly measured major axis 179 // the angle and minor axis are likely to be ok. 180 // restrict the axis ratio 181 double rAR2 = (f1 - f3) / (f1 + f3); 182 if (rAR2 < 1.0/PS_SQR(maxAR)) { 183 axes.major = axes.minor * maxAR; 184 errors.major = errors.minor * maxAR; 185 } else { 186 axes.major = sqrt (2.0 / (f1 - f3)); 187 188 // dmajor = -0.5 * (df1 - df3) * sqrt(2) * (f1 - f3)**-3/2 189 // = -0.5 * (df2 - df3) * major / (f1 - f3) 190 errors.major = -0.5 * axes.major * (df1 - df3) / (f1 - f3); 191 } 192 193 assert (isfinite(axes.theta)); 194 assert (isfinite(axes.major)); 195 assert (isfinite(axes.minor)); 196 197 *pShapeErrors = errors; 136 198 137 199 return axes; -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/math/psEllipse.h
r36375 r37827 65 65 ); 66 66 67 /// Convert shape to axes representation and compute errors 68 psEllipseAxes psEllipseShapeToAxesWithErrors(psEllipseShape shape, ///< Shape of ellipse 69 psEllipseShape errors, ///<errors on shape params 70 double maxAR, ///< Maximum allowed axis ratio 71 psEllipseAxes *pShapeErrors ///< propagated errors on axes 72 ); 73 67 74 /// Convert axes to polarization representation 68 75 psEllipsePol psEllipseAxesToPol(psEllipseAxes axes ///< Axes of ellipse -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/math/psMinimizePolyFit.c
- Property svn:mergeinfo set to
r36296 r37827 700 700 701 701 // Define values that may be used by PS_POLYNOMIAL_ORD form. 702 // these scaling values put the dynamic range of the data into some vaguely sensible location 702 703 bool scale = false; 704 bool median_zero = false; 703 705 double median = 0.0; 704 706 double sigma = 1.0; 705 psVector *sorted = NULL; 706 psVector *z64 = NULL; 707 707 708 708 switch (poly->type) { 709 709 case PS_POLYNOMIAL_ORD: 710 710 if ((f64->n < 10000)&&(poly->nX > 1)) { 711 711 scale = true; 712 sorted = psVectorSort(NULL,x64); 712 713 // generate a subset of the unmasked values: 714 psVector *tmp = psVectorAllocEmpty (x64->n, PS_TYPE_F64); 715 for (int itmp = 0; itmp < x64->n; itmp++) { 716 if (mask && (mask->data.PS_TYPE_VECTOR_MASK_DATA[itmp] && maskValue)) continue; 717 psVectorAppend (tmp, x64->data.F64[itmp]); 718 } 719 psVector *sorted = psVectorSort(NULL,tmp); 713 720 median = sorted->data.F64[sorted->n / 2]; 714 721 // CZW: I'm not bothering to scale this because it doesn't really matter. 715 722 sigma = (sorted->data.F64[3 * sorted->n / 4] - sorted->data.F64[sorted->n / 4]); 716 723 psFree(sorted); 724 psFree(tmp); 717 725 718 726 if ((!isfinite(median))|| … … 721 729 sigma = 1.0; 722 730 } 723 if ((median == 0.0)&&(sigma == 1.0)) { 724 scale = false; 731 if (fabs(median) < 1e-10) { 732 // CZW 2014-10-21: This median is small and close to zero. This can cause issues with the 733 // scaling, 734 median_zero = true; 735 if ((sigma == 1.0)||(fabs(sigma) <= 1e-10)) { 736 // Don't bother scaling if sigma is unity (it's already scaled) or if the sigma calculation has gone wrong. 737 scale = false; 738 } 725 739 } 740 726 741 // I can't see a way to not clobber x if it's already F64, so make a copy.x 727 z64 = psVectorCopy(NULL,x64,PS_TYPE_F64);742 psVector *z64 = psVectorCopy(NULL,x64,PS_TYPE_F64); 728 743 psBinaryOp(z64,z64,"-",psScalarAlloc(median,PS_TYPE_F64)); 729 744 psBinaryOp(z64,z64,"/",psScalarAlloc(sigma,PS_TYPE_F64)); … … 733 748 #endif 734 749 735 736 750 result = VectorFitPolynomial1DOrd(poly, mask, maskValue, f64, fErr64, z64); 737 751 psFree(z64); // Done with this. … … 758 772 #endif 759 773 } 774 760 775 for (psS32 i = 0; i <= poly->nX; i++) { 761 776 poly->coeff[i] = 0.0; 762 777 poly->coeffErr[i] = 0.0; 763 764 for (psS32 j = 0; j <= poly->nX; j++) { 778 if (median_zero) { // If the median is zero, the obtained solution just needs to be scaled by the sigma values. 779 poly->coeff[i] = Zcoeff[i] * pow(1.0 / sigma,i); 780 poly->coeffErr[i] = ZcoeffErr[i] * pow(1.0 / sigma,i); 781 } 782 else { // Otherwise, do the correct transformations by expanding the (x-m)/s terms. 783 for (psS32 j = 0; j <= poly->nX; j++) { 765 784 #if (CZW) 766 printf(" %d %d %f %f %f %f => %f\n",767 i,j,Zcoeff[j],768 pow(1.0 / sigma,j) * pow(-1,j - i),769 pow(median,j - i),770 1.0 * psBinomialCoeff(j,i),771 Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j -i) * pow(median,j - i) * 1.0 * psBinomialCoeff(j,i)772 );785 printf(" %d %d %f %f %f %f => %f\n", 786 i,j,Zcoeff[j], 787 pow(1.0 / sigma,j) * pow(-1,j - i), 788 pow(median,j - i), 789 1.0 * psBinomialCoeff(j,i), 790 Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j -i) * pow(median,j - i) * 1.0 * psBinomialCoeff(j,i) 791 ); 773 792 #endif 774 poly->coeff[i] += Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - i) * psBinomialCoeff(j,i); 775 poly->coeffErr[i] += pow(ZcoeffErr[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - 1) * psBinomialCoeff(j,i),2); 793 poly->coeff[i] += Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - i) * psBinomialCoeff(j,i); 794 poly->coeffErr[i] += pow(ZcoeffErr[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - 1) * psBinomialCoeff(j,i),2); 795 } 796 poly->coeffErr[i] = sqrt(poly->coeffErr[i]); 776 797 } 777 poly->coeffErr[i] = sqrt(poly->coeffErr[i]);778 798 #if (CZW) 779 799 printf("poly1d: unscaled parameters: %d %f %f\n", … … 784 804 psFree(ZcoeffErr); 785 805 786 } 806 } // End scaling block. 787 807 788 808 break; -
branches/eam_branches/ipp-pv3-20140717-merge/psLib/src/mathtypes/psImage.c
r23443 r37827 91 91 } 92 92 93 long numBytes = numRows * numCols *elementSize;93 size_t numBytes = (size_t) numRows * (size_t) numCols * (size_t) elementSize; 94 94 95 95 psImage* image = (psImage* ) p_psAlloc(file, lineno, func, sizeof(psImage));
Note:
See TracChangeset
for help on using the changeset viewer.
