IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 5801


Ignore:
Timestamp:
Dec 17, 2005, 10:26:29 AM (20 years ago)
Author:
magnier
Message:

adding the 3D and 4D fit polynomial functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_rel9_b1/psLib/src/math/psMinimize.c

    r5752 r5801  
    1010 *  @author EAM, IfA
    1111 *
    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 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    3232#include "psBinaryOp.h"
    3333#include "psLogMsg.h"
     34
    3435/*****************************************************************************/
    3536/* DEFINE STATEMENTS                                                         */
     
    14411442}
    14421443
    1443 // here is the definition for BuildSums4D.  ifdef'ed away until it is used
    1444 // by psPolynomial4DFit..
    1445 # if (0)
    1446     /******************************************************************************
     1444/******************************************************************************
     1445BuildSums3D(sums, x, y, z, nXterm, nYterm, nZterm): this routine calculates the powers of
     1446input parameter "x", "y", and "z" between 0 and input parameter nXterms*2,
     1447nYterm*2, and nZterm*2.  The result is returned as a psImage sums.
     1448 *****************************************************************************/
     1449static 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/******************************************************************************
    14471496    BuildSums4D(sums, x, y, z, t, nXterm, nYterm, nZterm, nTterm). equiv to
    14481497    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*****************************************************************************/
     1499static 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)
    14601509{
    14611510    psS32 nXsum = 0;
     
    15051554    return (sums);
    15061555}
    1507 # endif /* BuildSums4D */
    15081556
    15091557/******************************************************************************
     
    19612009        float maxClipValue = +maxClipSigma*stats->sampleStdev;
    19622010
     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
    19632014        // set mask if pts are not valid
    19642015        // we are masking out any point which is out of range
     
    21202171}
    21212172
    2122 
    21232173// XXX EAM : I have implemented a single function to handle the mask/nomask cases
    21242174//           this function can be deprecated
     
    24372487        float minClipValue = -minClipSigma*stats->sampleStdev;
    24382488        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);
    24392491
    24402492        // set mask if pts are not valid
     
    25262578    }
    25272579
    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);
    25302667}
    25312668
     
    27142851    PS_ASSERT_PTR_NON_NULL(stats, NULL);
    27152852    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);
    27172854    if (mask != NULL) {
    27182855        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     
    27212858    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
    27222859    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);
    27242861    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
    27252862    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);
    27272864    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);
    27302867    if (fErr != NULL) {
    27312868        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);
    27372942}
    2738 
    27392943
    27402944/******************************************************************************
     
    27922996    }
    27932997
    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);
    27963099}
    27973100
     
    30293332    }
    30303333
    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);
    30343404}
    3035 
    3036 
Note: See TracChangeset for help on using the changeset viewer.