IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 23, 2005, 3:04:37 PM (21 years ago)
Author:
gusciora
Message:

Added EAM changes to the polynomial structs. Not, poly->nX equals
the number of terms, not the order of the polynomial.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psMinimize.c

    r4760 r4858  
    99 *  @author GLG, MHPCC
    1010 *
    11  *  @version $Revision: 1.130 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2005-08-11 23:04:32 $
     11 *  @version $Revision: 1.131 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2005-08-24 01:04:37 $
    1313 *
    1414 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2828#include "psImage.h"
    2929#include "psImageStructManip.h"
     30#include "psBinaryOp.h"
    3031/*****************************************************************************/
    3132/* DEFINE STATEMENTS                                                         */
     
    21312132
    21322133
     2134/******************************************************************************
     2135EAM Code:
     2136 *****************************************************************************/
     2137
     2138// XXX EAM : my alternate EAMBuildSums1D
     2139static psVector *EAMBuildSums1D(
     2140    psVector* sums,
     2141    psF64 x,
     2142    psS32 nTerm)
     2143{
     2144    psS32 nSum = 0;
     2145    psF64 xSum = 0.0;
     2146
     2147    nSum = 2*nTerm;
     2148    if (sums == NULL) {
     2149        sums = psVectorAlloc(nSum, PS_TYPE_F64);
     2150    }
     2151    if (nSum > sums->n) {
     2152        sums = psVectorRealloc(sums, nSum);
     2153    }
     2154
     2155    xSum = 1.0;
     2156    for (int i = 0; i < nSum; i++) {
     2157        sums->data.F64[i] = xSum;
     2158        xSum *= x;
     2159    }
     2160    return (sums);
     2161}
     2162
     2163// XXX EAM : test version of 1d fitting
     2164psPolynomial1D* VectorFitPolynomial1DOrd_EAM(
     2165    psPolynomial1D* myPoly,
     2166    psVector *mask,
     2167    const psVector *x,
     2168    const psVector *y,
     2169    const psVector *yErr
     2170)
     2171{
     2172    // I think this is 1 dimension down
     2173    psImage*     A = NULL;
     2174    psVector*    B = NULL;
     2175    psVector* xSums = NULL;
     2176    psS32 nTerm;
     2177    psS32 nOrder;
     2178    psF64 wt;
     2179
     2180    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
     2181            "---- VectorFitPolynomial1DOrd() begin ----\n");
     2182
     2183    if (psTraceGetLevel (".psLib.dataManip.VectorFitPolynomial1DOrd") >= 5) {
     2184        FILE *f = psTraceGetDestination ();
     2185        fprintf (f, "VectorFitPolynomial1D()\n");
     2186        for (int i = 0; i < x->n; i++) {
     2187            fprintf (f, "(x, y, yErr) is (%f, %f, %f)\n", x->data.F64[i], y->data.F64[i], yErr->data.F64[i]);
     2188        }
     2189    }
     2190
     2191    nTerm = myPoly->n;
     2192    nOrder = nTerm - 1;
     2193
     2194    A     = psImageAlloc(nTerm, nTerm, PS_TYPE_F64);
     2195    B     = psVectorAlloc(nTerm, PS_TYPE_F64);
     2196
     2197    //
     2198    // Initialize data structures.
     2199    // XXX: Use psLib function.
     2200    //
     2201    PS_VECTOR_SET_F64(B, 0.0);
     2202    PS_IMAGE_SET_F64(A, 0.0);
     2203
     2204    // xSums look like: 1, x, x^2, ... x^(2n+1)
     2205    // Build the B and A data structs.
     2206    for (int k = 0; k < x->n; k++) {
     2207        if ((mask != NULL) && mask->data.U8[k])
     2208            continue;
     2209        xSums = EAMBuildSums1D(xSums, x->data.F64[k], nTerm);
     2210
     2211        if (yErr == NULL) {
     2212            wt = 1.0;
     2213        } else {
     2214            // this should filter yErr == 0 values
     2215            wt = 1.0 / PS_SQR(yErr->data.F64[k]);
     2216        }
     2217        for (int i = 0; i < nTerm; i++) {
     2218            B->data.F64[i] += y->data.F64[k] * xSums->data.F64[i] * wt;
     2219        }
     2220
     2221        // we could skip half of the array and assign at the end
     2222        // we must handle masked orders
     2223        for (int i = 0; i < nTerm; i++) {
     2224            for (int j = 0; j < nTerm; j++) {
     2225                A->data.F64[i][j] += xSums->data.F64[i + j] * wt;
     2226            }
     2227        }
     2228    }
     2229
     2230    // GaussJordan version
     2231    if (0) {
     2232        // does the solution in place
     2233        psGaussJordan (A, B);
     2234
     2235        // the first nTerm entries in B correspond directly to the desired
     2236        // polynomial coefficients.  this is only true for the 1D case
     2237        for (int k = 0; k < nTerm; k++) {
     2238            myPoly->coeff[k] = B->data.F64[k];
     2239        }
     2240    } else
     2241        // LUD version of the fit
     2242    {
     2243        psImage *ALUD = NULL;
     2244        psVector* outPerm = NULL;
     2245        psVector* coeffs = NULL;
     2246
     2247        ALUD = psImageAlloc(nTerm, nTerm, PS_TYPE_F64);
     2248        ALUD = psMatrixLUD(ALUD, &outPerm, A);
     2249        coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
     2250        for (int k = 0; k < nTerm; k++) {
     2251            myPoly->coeff[k] = coeffs->data.F64[k];
     2252        }
     2253    }
     2254
     2255    psFree(A);
     2256    psFree(B);
     2257    psFree(xSums);
     2258
     2259    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
     2260            "---- VectorFitPolynomial1DOrd() begin ----\n");
     2261    return (myPoly);
     2262}
     2263
     2264// XXX EAM : this version uses the F64 vectors
     2265psVector *Polynomial2DEvalVectorD(
     2266    const psPolynomial2D *myPoly,
     2267    const psVector *x,
     2268    const psVector *y
     2269)
     2270{
     2271    PS_ASSERT_POLY_NON_NULL(myPoly, NULL);
     2272    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2273    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F64, NULL);
     2274    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2275    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F64, NULL);
     2276
     2277    psVector *tmp;
     2278    psS32 vecLen=x->n;
     2279
     2280    // Determine the length of the output vector to by the minimum of the x,y vectors
     2281    if (y->n < vecLen) {
     2282        vecLen = y->n;
     2283    }
     2284
     2285    // Create output vector to return
     2286    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
     2287
     2288    // Evaluate the polynomial at the specified points
     2289    for (psS32 i=0; i<vecLen; i++) {
     2290        tmp->data.F64[i] = psPolynomial2DEval(myPoly, x->data.F64[i], y->data.F64[i]);
     2291    }
     2292
     2293    // Return output vector
     2294    return(tmp);
     2295}
     2296
     2297// XXX EAM : EAMBuildSums2D in analogy with EAMBuildSums1D
     2298static psImage *EAMBuildSums2D(
     2299    psImage *sums,
     2300    psF64 x,
     2301    psF64 y,
     2302    psS32 nXterm,
     2303    psS32 nYterm
     2304)
     2305{
     2306    psS32 nXsum = 0;
     2307    psS32 nYsum = 0;
     2308    psF64 xSum = 1.0;
     2309    psF64 ySum = 1.0;
     2310
     2311    nXsum = 2*nXterm;
     2312    nYsum = 2*nYterm;
     2313    if (sums == NULL) {
     2314        sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64);
     2315    }
     2316    if ((nXsum != sums->numCols) || (nYsum != sums->numRows)) {
     2317        psFree (sums);
     2318        sums = psImageAlloc(nXsum, nYsum, PS_TYPE_F64);
     2319    }
     2320
     2321    ySum = 1.0;
     2322    for (int j = 0; j < nYsum; j++) {
     2323        xSum = ySum;
     2324        for (int i = 0; i < nXsum; i++) {
     2325            sums->data.F64[i][j] = xSum;
     2326            xSum *= x;
     2327        }
     2328        ySum *= y;
     2329    }
     2330    return (sums);
     2331}
     2332
     2333// XXX EAM : test version of 2d fitting
     2334psPolynomial2D* VectorFitPolynomial2DOrd_EAM(
     2335    psPolynomial2D* myPoly,
     2336    psVector* mask,
     2337    const psVector* x,
     2338    const psVector* y,
     2339    const psVector* z,
     2340    const psVector* zErr
     2341)
     2342{
     2343    // I think this is 1 dimension down
     2344    psImage*     A = NULL;
     2345    psVector*    B = NULL;
     2346    psImage*   Sums = NULL;
     2347    psF64 wt;
     2348    psS32 nTerm;
     2349
     2350    // XXX:Watch for changes to the psPolys: nTerm != nOrder.
     2351    psS32 nXterm = myPoly->nX;
     2352    psS32 nYterm = myPoly->nY;
     2353    nTerm = nXterm * nYterm;
     2354
     2355    A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64);
     2356    B = psVectorAlloc(nTerm, PS_TYPE_F64);
     2357
     2358    //
     2359    // Initialize data structures.
     2360    // XXX: Use psLib function.
     2361    //
     2362    PS_VECTOR_SET_F64(B, 0.0);
     2363    PS_IMAGE_SET_F64(A, 0.0);
     2364
     2365    // Sums look like: 1, x, x^2, ... x^(2n+1), y, xy, x^2y, ... x^(2n+1)
     2366
     2367    // Build the B and A data structs.
     2368    for (int k  = 0; k < x->n; k++) {
     2369        if ((mask != NULL) && mask->data.U8[k])
     2370            continue;
     2371        Sums = EAMBuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm);
     2372
     2373        if (zErr == NULL) {
     2374            wt = 1.0;
     2375        } else {
     2376            // XXX: this should probably by zErr^2 !!
     2377            // this should filter zErr == 0 values
     2378            // XXX: Why isn't this zErr^2?
     2379            wt = 1.0 / zErr->data.F64[k];
     2380        }
     2381
     2382        // we could skip half of the array and assign at the end
     2383        // we must handle masked orders
     2384        for (int n = 0; n < nXterm; n++) {
     2385            for (int m = 0; m < nYterm; m++) {
     2386                B->data.F64[n+m*nXterm] += z->data.F64[k] * Sums->data.F64[n][m] * wt;
     2387            }
     2388        }
     2389
     2390        for (int i = 0; i < nXterm; i++) {
     2391            for (int j = 0; j < nYterm; j++) {
     2392                for (int n = 0; n < nXterm; n++) {
     2393                    for (int m = 0; m < nYterm; m++) {
     2394                        A->data.F64[i+j*nXterm][n+m*nXterm] += Sums->data.F64[i+n][j+m] * wt;
     2395                    }
     2396                }
     2397            }
     2398        }
     2399    }
     2400
     2401    // does the solution in place
     2402    // XXX: Check return codes!
     2403    psGaussJordan (A, B);
     2404
     2405    // XXX: Check return codes!
     2406    // ALUD = psMatrixLUD(ALUD, &outPerm, A);
     2407    // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
     2408
     2409    for (int n = 0; n < nXterm; n++) {
     2410        for (int m = 0; m < nYterm; m++) {
     2411            myPoly->coeff[n][m] = B->data.F64[n+m*nXterm];
     2412        }
     2413    }
     2414
     2415    psFree(A);
     2416    psFree(B);
     2417    psFree(Sums);
     2418
     2419    psTrace(".psLib.dataManip.VectorFitPolynomial2DOrd", 4,
     2420            "---- VectorFitPolynomial2DOrd() begin ----\n");
     2421    return (myPoly);
     2422}
     2423
     2424
     2425psPolynomial2D* RobustFit2D_nomask(
     2426    psPolynomial2D* poly,
     2427    const psVector* x,
     2428    const psVector* y,
     2429    const psVector* z,
     2430    const psVector* dz
     2431)
     2432{
     2433    psVector *X;
     2434    psVector *Y;
     2435    psVector *Z;
     2436    psVector *dZ;
     2437
     2438    psVector *zFit   = NULL;
     2439    psVector *zResid = NULL;
     2440    psStats  *stats  = NULL;
     2441
     2442    X  = psVectorCopy (NULL, x, PS_TYPE_F64);
     2443    Y  = psVectorCopy (NULL, y, PS_TYPE_F64);
     2444    Z  = psVectorCopy (NULL, z, PS_TYPE_F64);
     2445    dZ = psVectorCopy (NULL, dz, PS_TYPE_F64);
     2446
     2447    for (int N = 0; N < 3; N++) {
     2448        // XXX EAM : this would be better defined with an element mask
     2449        poly   = VectorFitPolynomial2DOrd_EAM(poly, NULL, X, Y, Z, dZ);
     2450        zFit   = Polynomial2DEvalVectorD(poly, x, y);
     2451        zResid = (psVector *) psBinaryOp(NULL, (void *) z, "-", (void *) zFit);
     2452
     2453        stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
     2454        stats  = psVectorStats (stats, zResid, NULL, NULL, 0);
     2455        psTrace (".psphot.RobustFit", 4, "residual stats for robust fit:  %g +/- %g (%d pts)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues);
     2456
     2457        // re-create X, Y, Z, dZ if pts are valid
     2458        int n = 0;
     2459        for (int i = 0; i < zResid->n; i++) {
     2460            if (fabs(zResid->data.F64[i] - stats->clippedMean) > 3*stats->clippedStdev) {
     2461                continue;
     2462            }
     2463            X->data.F64[n]  =  x->data.F64[i];
     2464            Y->data.F64[n]  =  y->data.F64[i];
     2465            Z->data.F64[n]  =  z->data.F64[i];
     2466            dZ->data.F64[n] = dz->data.F64[i];
     2467            n++;
     2468        }
     2469        X->n = n;
     2470        Y->n = n;
     2471        Z->n = n;
     2472        dZ->n = n;
     2473    }
     2474    return (poly);
     2475}
     2476
     2477// XXX EAM : be careful here with F32 vs F64 vectors
     2478psPolynomial2D* RobustFit2D(psPolynomial2D* poly,
     2479                            psVector* mask,
     2480                            const psVector* x,
     2481                            const psVector* y,
     2482                            const psVector* z,
     2483                            const psVector* dz)
     2484{
     2485    PS_ASSERT_VECTOR_NON_NULL(mask, NULL);
     2486    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2487    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2488    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     2489    PS_ASSERT_VECTOR_NON_NULL(dz, NULL);
     2490
     2491    psVector *zFit   = NULL;
     2492    psVector *zResid = psVectorAlloc (x->n, PS_TYPE_F64);
     2493    psStats  *stats  = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
     2494
     2495    for (int N = 0; N < 3; N++) {
     2496        poly   = VectorFitPolynomial2DOrd_EAM (poly, mask, x, y, z, dz);
     2497        zFit   = Polynomial2DEvalVectorD (poly, x, y);
     2498        zResid = (psVector *) psBinaryOp(zResid, (void *) z, "-", (void *) zFit);
     2499
     2500        stats  = psVectorStats (stats, zResid, NULL, mask, 1);
     2501        psTrace (".psphot.RobustFit", 4, "residual stats for robust fit:  %g +/- %g\n",
     2502                 stats->sampleMean, stats->sampleStdev);
     2503
     2504        // set mask if pts are not valid
     2505        // we are masking out any point which is out of range
     2506        // recovery is not allowed with this scheme
     2507        for (int i = 0; i < zResid->n; i++) {
     2508            if (mask->data.U8[i])
     2509                continue;
     2510            if (fabs(zResid->data.F64[i] - stats->sampleMean) > 3*stats->sampleStdev) {
     2511                mask->data.U8[i] = 1;
     2512                continue;
     2513            }
     2514        }
     2515        psFree (zFit);
     2516    }
     2517    psFree (zResid);
     2518    psFree (stats);
     2519    return (poly);
     2520}
     2521
     2522
Note: See TracChangeset for help on using the changeset viewer.