Changeset 5801 for branches/eam_rel9_b1/psLib/src/math/psMinimize.c
- Timestamp:
- Dec 17, 2005, 10:26:29 AM (20 years ago)
- File:
-
- 1 edited
-
branches/eam_rel9_b1/psLib/src/math/psMinimize.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_rel9_b1/psLib/src/math/psMinimize.c
r5752 r5801 10 10 * @author EAM, IfA 11 11 * 12 * @version $Revision: 1.147.4.1 $ $Name: not supported by cvs2svn $13 * @date $Date: 2005-12- 07 20:49:43$12 * @version $Revision: 1.147.4.1.2.1 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-12-17 20:26:29 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 32 32 #include "psBinaryOp.h" 33 33 #include "psLogMsg.h" 34 34 35 /*****************************************************************************/ 35 36 /* DEFINE STATEMENTS */ … … 1441 1442 } 1442 1443 1443 // here is the definition for BuildSums4D. ifdef'ed away until it is used 1444 // by psPolynomial4DFit.. 1445 # if (0) 1446 /****************************************************************************** 1444 /****************************************************************************** 1445 BuildSums3D(sums, x, y, z, nXterm, nYterm, nZterm): this routine calculates the powers of 1446 input parameter "x", "y", and "z" between 0 and input parameter nXterms*2, 1447 nYterm*2, and nZterm*2. The result is returned as a psImage sums. 1448 *****************************************************************************/ 1449 static psF64 ***BuildSums3D( 1450 psF64 ***sums, 1451 psF64 x, 1452 psF64 y, 1453 psF64 z, 1454 psS32 nXterm, 1455 psS32 nYterm, 1456 psS32 nZterm) 1457 { 1458 psS32 nXsum = 0; 1459 psS32 nYsum = 0; 1460 psS32 nZsum = 0; 1461 psF64 xSum = 1.0; 1462 psF64 ySum = 1.0; 1463 psF64 zSum = 1.0; 1464 1465 nXsum = 2*nXterm; 1466 nYsum = 2*nYterm; 1467 nZsum = 2*nZterm; 1468 if (sums == NULL) { 1469 sums = (psF64 ***) psAlloc (nXsum*sizeof(psF64)); 1470 for (int i = 0; i < nXsum; i++) { 1471 sums[i] = (psF64 **) psAlloc (nYsum*sizeof(psF64)); 1472 for (int j = 0; j < nYsum; j++) { 1473 sums[i][j] = (psF64 *) psAlloc (nZsum*sizeof(psF64)); 1474 } 1475 } 1476 } 1477 // careful with this function: there is no size checking and realloc for reuse 1478 1479 zSum = 1.0; 1480 for (int k = 0; k < nZsum; k++) { 1481 ySum = zSum; 1482 for (int j = 0; j < nYsum; j++) { 1483 xSum = ySum; 1484 for (int i = 0; i < nXsum; i++) { 1485 sums[i][j][k] = xSum; 1486 xSum *= x; 1487 } 1488 ySum *= y; 1489 } 1490 zSum *= z; 1491 } 1492 return (sums); 1493 } 1494 1495 /****************************************************************************** 1447 1496 BuildSums4D(sums, x, y, z, t, nXterm, nYterm, nZterm, nTterm). equiv to 1448 1497 BuildSums2D(). The result is returned as a double **** 1449 *****************************************************************************/1450 static double****BuildSums4D(1451 psF64 ****sums,1452 psF64 x,1453 psF64 y,1454 psF64 z,1455 psF64 t,1456 psS32 nXterm,1457 psS32 nYterm,1458 psS32 nZterm,1459 psS32 nTterm)1498 *****************************************************************************/ 1499 static psF64 ****BuildSums4D( 1500 psF64 ****sums, 1501 psF64 x, 1502 psF64 y, 1503 psF64 z, 1504 psF64 t, 1505 psS32 nXterm, 1506 psS32 nYterm, 1507 psS32 nZterm, 1508 psS32 nTterm) 1460 1509 { 1461 1510 psS32 nXsum = 0; … … 1505 1554 return (sums); 1506 1555 } 1507 # endif /* BuildSums4D */1508 1556 1509 1557 /****************************************************************************** … … 1961 2009 float maxClipValue = +maxClipSigma*stats->sampleStdev; 1962 2010 2011 psTrace (".psphot.VectorClipFit", 4, "residual stats for robust fit: %g +/- %g\n", stats->sampleMedian, stats->sampleStdev); 2012 psTrace (".psphot.VectorClipFit", 5, "min clip: %f, max clip: %f\n", minClipValue, maxClipValue); 2013 1963 2014 // set mask if pts are not valid 1964 2015 // we are masking out any point which is out of range … … 2120 2171 } 2121 2172 2122 2123 2173 // XXX EAM : I have implemented a single function to handle the mask/nomask cases 2124 2174 // this function can be deprecated … … 2437 2487 float minClipValue = -minClipSigma*stats->sampleStdev; 2438 2488 float maxClipValue = +maxClipSigma*stats->sampleStdev; 2489 psTrace (".psphot.VectorClipFit", 5, "resid stats: %f +/- %f\n", stats->sampleMedian, stats->sampleStdev); 2490 psTrace (".psphot.VectorClipFit", 5, "min clip: %f, max clip: %f\n", minClipValue, maxClipValue); 2439 2491 2440 2492 // set mask if pts are not valid … … 2526 2578 } 2527 2579 2528 psError(PS_ERR_UNKNOWN, true, "3-D Polynomial Fitting is not Implemented.\n"); 2529 return (NULL); 2580 psImage *A = NULL; 2581 psVector *B = NULL; 2582 psF64 ***Sums = NULL; 2583 psF64 wt; 2584 psS32 nTerm; 2585 2586 // XXX:Watch for changes to the psPolys: nTerm != nOrder. 2587 psS32 nXterm = 1 + myPoly->nX; 2588 psS32 nYterm = 1 + myPoly->nY; 2589 psS32 nZterm = 1 + myPoly->nZ; 2590 nTerm = nXterm * nYterm * nZterm; 2591 2592 A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64); 2593 B = psVectorAlloc(nTerm, PS_TYPE_F64); 2594 2595 // Initialize data structures. 2596 psVectorInit (B, 0.0); 2597 psImageInit (A, 0.0); 2598 2599 // Sums look like: 1, x, x^2, ... x^(2n+1), y, xy, x^2y, ... x^(2n+1)*y, ... 2600 2601 // Build the B and A data structs. 2602 for (int k = 0; k < x->n; k++) { 2603 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) { 2604 continue; 2605 } 2606 2607 Sums = BuildSums3D(Sums, x->data.F64[k], y->data.F64[k], z->data.F64[k], nXterm, nYterm, nZterm); 2608 2609 if (fErr == NULL) { 2610 wt = 1.0; 2611 } else { 2612 // this filters fErr == 0 values 2613 wt = (fErr->data.F64[k] == 0.0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 2614 } 2615 2616 // we could skip half of the array and assign at the end 2617 // we must handle masked orders 2618 for (int ix = 0; ix < nXterm; ix++) { 2619 for (int iy = 0; iy < nYterm; iy++) { 2620 for (int iz = 0; iz < nZterm; iz++) { 2621 B->data.F64[ix+iy*nXterm+iz*nXterm*nYterm] += f->data.F64[k] * Sums[ix][iy][iz] * wt; 2622 } 2623 } 2624 } 2625 2626 for (int ix = 0; ix < nXterm; ix++) { 2627 for (int iy = 0; iy < nYterm; iy++) { 2628 for (int iz = 0; iz < nZterm; iz++) { 2629 for (int jx = 0; jx < nXterm; jx++) { 2630 for (int jy = 0; jy < nYterm; jy++) { 2631 for (int jz = 0; jz < nZterm; jz++) { 2632 A->data.F64[ix+iy*nXterm+iz*nXterm*nYterm][ix+iy*nXterm+iz*nXterm*nYterm] += Sums[ix+jx][iy+jy][iz+jz] * wt; 2633 } 2634 } 2635 } 2636 } 2637 } 2638 } 2639 } 2640 2641 // does the solution in place 2642 psGaussJordan (A, B); 2643 2644 // select the appropriate solution entries 2645 for (int ix = 0; ix < nXterm; ix++) { 2646 for (int iy = 0; iy < nYterm; iy++) { 2647 for (int iz = 0; iz < nZterm; iz++) { 2648 myPoly->coeff[ix][iy][iz] = B->data.F64[ix+iy*nXterm+iz*nXterm*nYterm]; 2649 } 2650 } 2651 } 2652 2653 psFree(A); 2654 psFree(B); 2655 2656 for (int ix = 0; ix < nXterm; ix++) { 2657 for (int iy = 0; iy < nYterm; iy++) { 2658 psFree(Sums[ix][iy]); 2659 } 2660 psFree(Sums[ix]); 2661 } 2662 psFree(Sums); 2663 2664 psTrace(".psLib.dataManip.VectorFitPolynomial3DOrd", 4, 2665 "---- VectorFitPolynomial3DOrd() begin ----\n"); 2666 return (myPoly); 2530 2667 } 2531 2668 … … 2714 2851 PS_ASSERT_PTR_NON_NULL(stats, NULL); 2715 2852 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 2716 PS_ASSERT_VECTOR_TYPE (f, PS_TYPE_F32, NULL);2853 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 2717 2854 if (mask != NULL) { 2718 2855 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); … … 2721 2858 PS_ASSERT_VECTOR_NON_NULL(x, NULL); 2722 2859 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2723 PS_ASSERT_VECTOR_TYPE (x, PS_TYPE_F32, NULL);2860 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL); 2724 2861 PS_ASSERT_VECTOR_NON_NULL(y, NULL); 2725 2862 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 2726 PS_ASSERT_VECTOR_TYPE (y, PS_TYPE_F32, NULL);2863 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL); 2727 2864 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 2728 PS_ASSERT_VECTORS_SIZE_EQUAL(f, f, NULL);2729 PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);2865 // PS_ASSERT_VECTORS_SIZE_EQUAL(f, f, NULL); 2866 // PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 2730 2867 if (fErr != NULL) { 2731 2868 PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL); 2732 PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL); 2733 } 2734 2735 psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented. Returning NULL.\n"); 2736 return(NULL); 2869 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 2870 } 2871 2872 // clipping range defined by min and max and/or clipSigma 2873 float minClipSigma; 2874 float maxClipSigma; 2875 if (isfinite(stats->max)) { 2876 maxClipSigma = fabs(stats->max); 2877 } else { 2878 maxClipSigma = fabs(stats->clipSigma); 2879 } 2880 if (isfinite(stats->min)) { 2881 minClipSigma = fabs(stats->min); 2882 } else { 2883 minClipSigma = fabs(stats->clipSigma); 2884 } 2885 psVector *fit = NULL; 2886 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 2887 2888 // eventual expansion: user supplies one of various stats option pairs, 2889 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 2890 // evaluate the clipping sigma 2891 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 2892 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 2893 2894 for (int N = 0; N < stats->clipIter; N++) { 2895 int Nkeep = 0; 2896 2897 poly = psVectorFitPolynomial3D (poly, mask, maskValue, f, fErr, x, y, z); 2898 fit = psPolynomial3DEvalVector (poly, x, y, z); 2899 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 2900 2901 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 2902 float minClipValue = -minClipSigma*stats->sampleStdev; 2903 float maxClipValue = +maxClipSigma*stats->sampleStdev; 2904 psTrace (".psphot.VectorClipFit", 5, "resid stats: %f +/- %f\n", stats->sampleMedian, stats->sampleStdev); 2905 psTrace (".psphot.VectorClipFit", 5, "min clip: %f, max clip: %f\n", minClipValue, maxClipValue); 2906 2907 // set mask if pts are not valid 2908 // we are masking out any point which is out of range 2909 // recovery is not allowed with this scheme 2910 for (int i = 0; i < resid->n; i++) { 2911 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 2912 continue; 2913 } 2914 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 2915 if (mask != NULL) { 2916 mask->data.U8[i] |= 0x01; 2917 } 2918 continue; 2919 } 2920 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 2921 if (mask != NULL) { 2922 mask->data.U8[i] |= 0x01; 2923 } 2924 continue; 2925 } 2926 Nkeep ++; 2927 } 2928 2929 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 2930 Nkeep, x->n); 2931 2932 psFree (fit); 2933 } 2934 // Free local temporary variables 2935 psFree (resid); 2936 2937 if (poly == NULL) { 2938 psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data. Returning NULL.\n"); 2939 return(NULL); 2940 } 2941 return(poly); 2737 2942 } 2738 2739 2943 2740 2944 /****************************************************************************** … … 2792 2996 } 2793 2997 2794 psError(PS_ERR_UNKNOWN, true, "4-D Polynomial Fitting is not Implemented.\n"); 2795 return (NULL); 2998 // I think this is 1 dimension down 2999 psImage *A = NULL; 3000 psVector *B = NULL; 3001 psF64 ****Sums = NULL; 3002 psF64 wt; 3003 psS32 nTerm; 3004 3005 // XXX:Watch for changes to the psPolys: nTerm != nOrder. 3006 psS32 nXterm = 1 + myPoly->nX; 3007 psS32 nYterm = 1 + myPoly->nY; 3008 psS32 nZterm = 1 + myPoly->nZ; 3009 psS32 nTterm = 1 + myPoly->nZ; 3010 nTerm = nXterm * nYterm * nZterm * nTterm; 3011 3012 A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64); 3013 B = psVectorAlloc(nTerm, PS_TYPE_F64); 3014 3015 // Initialize data structures. 3016 psVectorInit (B, 0.0); 3017 psImageInit (A, 0.0); 3018 3019 // Sums look like: 1, x, x^2, ... x^(2n+1), y, xy, x^2y, ... x^(2n+1)*y, ... 3020 3021 // Build the B and A data structs. 3022 for (int k = 0; k < x->n; k++) { 3023 if ((mask != NULL) && (mask->data.U8[k] & maskValue)) { 3024 continue; 3025 } 3026 3027 Sums = BuildSums4D(Sums, x->data.F64[k], y->data.F64[k], z->data.F64[k], t->data.F64[k], nXterm, nYterm, nZterm, nTterm); 3028 3029 if (fErr == NULL) { 3030 wt = 1.0; 3031 } else { 3032 // this filters fErr == 0 values 3033 wt = (fErr->data.F64[k] == 0.0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]); 3034 } 3035 3036 // we could skip half of the array and assign at the end 3037 // we must handle masked orders 3038 for (int ix = 0; ix < nXterm; ix++) { 3039 for (int iy = 0; iy < nYterm; iy++) { 3040 for (int iz = 0; iz < nZterm; iz++) { 3041 for (int it = 0; it < nTterm; it++) { 3042 B->data.F64[ix+iy*nXterm+iz*nXterm*nYterm+it*nXterm*nYterm*nZterm] += f->data.F64[k] * Sums[ix][iy][iz][it] * wt; 3043 } 3044 } 3045 } 3046 } 3047 3048 for (int ix = 0; ix < nXterm; ix++) { 3049 for (int iy = 0; iy < nYterm; iy++) { 3050 for (int iz = 0; iz < nZterm; iz++) { 3051 for (int it = 0; it < nTterm; it++) { 3052 for (int jx = 0; jx < nXterm; jx++) { 3053 for (int jy = 0; jy < nYterm; jy++) { 3054 for (int jz = 0; jz < nZterm; jz++) { 3055 for (int jt = 0; jt < nTterm; jt++) { 3056 A->data.F64[ix+iy*nXterm+iz*nXterm*nYterm+it*nXterm*nYterm*nZterm][ix+iy*nXterm+iz*nXterm*nYterm+it*nXterm*nYterm*nZterm] 3057 += Sums[ix+jx][iy+jy][iz+jz][it+jt] * wt; 3058 } 3059 } 3060 } 3061 } 3062 } 3063 } 3064 } 3065 } 3066 } 3067 3068 // does the solution in place 3069 psGaussJordan (A, B); 3070 3071 // select the appropriate solution entries 3072 for (int ix = 0; ix < nXterm; ix++) { 3073 for (int iy = 0; iy < nYterm; iy++) { 3074 for (int iz = 0; iz < nZterm; iz++) { 3075 for (int it = 0; it < nTterm; it++) { 3076 myPoly->coeff[ix][iy][iz][it] = B->data.F64[ix+iy*nXterm+iz*nXterm*nYterm+iz*nXterm*nYterm*nZterm]; 3077 } 3078 } 3079 } 3080 } 3081 3082 psFree(A); 3083 psFree(B); 3084 3085 for (int ix = 0; ix < nXterm; ix++) { 3086 for (int iy = 0; iy < nYterm; iy++) { 3087 for (int iz = 0; iz < nZterm; iz++) { 3088 psFree(Sums[ix][iy][iz]); 3089 } 3090 psFree(Sums[ix][iy]); 3091 } 3092 psFree(Sums[ix]); 3093 } 3094 psFree(Sums); 3095 3096 psTrace(".psLib.dataManip.VectorFitPolynomial3DOrd", 4, 3097 "---- VectorFitPolynomial3DOrd() begin ----\n"); 3098 return (myPoly); 2796 3099 } 2797 3100 … … 3029 3332 } 3030 3333 3031 psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented. Returning NULL.\n"); 3032 3033 return(NULL); 3334 // clipping range defined by min and max and/or clipSigma 3335 float minClipSigma; 3336 float maxClipSigma; 3337 if (isfinite(stats->max)) { 3338 maxClipSigma = fabs(stats->max); 3339 } else { 3340 maxClipSigma = fabs(stats->clipSigma); 3341 } 3342 if (isfinite(stats->min)) { 3343 minClipSigma = fabs(stats->min); 3344 } else { 3345 minClipSigma = fabs(stats->clipSigma); 3346 } 3347 psVector *fit = NULL; 3348 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 3349 3350 // eventual expansion: user supplies one of various stats option pairs, 3351 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 3352 // evaluate the clipping sigma 3353 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 3354 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 3355 3356 for (int N = 0; N < stats->clipIter; N++) { 3357 int Nkeep = 0; 3358 3359 poly = psVectorFitPolynomial4D (poly, mask, maskValue, f, fErr, x, y, z, t); 3360 fit = psPolynomial4DEvalVector (poly, x, y, z, t); 3361 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 3362 3363 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 3364 float minClipValue = -minClipSigma*stats->sampleStdev; 3365 float maxClipValue = +maxClipSigma*stats->sampleStdev; 3366 psTrace (".psphot.VectorClipFit", 5, "resid stats: %f +/- %f\n", stats->sampleMedian, stats->sampleStdev); 3367 psTrace (".psphot.VectorClipFit", 5, "min clip: %f, max clip: %f\n", minClipValue, maxClipValue); 3368 3369 // set mask if pts are not valid 3370 // we are masking out any point which is out of range 3371 // recovery is not allowed with this scheme 3372 for (int i = 0; i < resid->n; i++) { 3373 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 3374 continue; 3375 } 3376 if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) { 3377 if (mask != NULL) { 3378 mask->data.U8[i] |= 0x01; 3379 } 3380 continue; 3381 } 3382 if (resid->data.F64[i] - stats->sampleMedian < minClipValue) { 3383 if (mask != NULL) { 3384 mask->data.U8[i] |= 0x01; 3385 } 3386 continue; 3387 } 3388 Nkeep ++; 3389 } 3390 3391 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 3392 Nkeep, x->n); 3393 3394 psFree (fit); 3395 } 3396 // Free local temporary variables 3397 psFree (resid); 3398 3399 if (poly == NULL) { 3400 psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data. Returning NULL.\n"); 3401 return(NULL); 3402 } 3403 return(poly); 3034 3404 } 3035 3036
Note:
See TracChangeset
for help on using the changeset viewer.
