IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 5567


Ignore:
Timestamp:
Nov 22, 2005, 8:06:10 AM (21 years ago)
Author:
magnier
Message:

fixed PolyFit to handle NULL mask, errors, fixed clip fit to handle min/max

File:
1 edited

Legend:

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

    r5294 r5567  
    1010 *  @author EAM, IfA
    1111 *
    12  *  @version $Revision: 1.142 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2005-10-12 21:02:20 $
     12 *  @version $Revision: 1.142.6.1 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2005-11-22 18:06:10 $
    1414 *
    1515 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    14431443
    14441444/******************************************************************************
     1445BuildSums4D(sums, x, y, z, t, nXterm, nYterm, nZterm, nTterm). equiv to
     1446BuildSums2D(). The result is returned as a double ****
     1447 *****************************************************************************/
     1448static psImage *BuildSums4D(
     1449    psF64 ****sums,
     1450    psF64 x,
     1451    psF64 y,
     1452    psF64 z,
     1453    psF64 t,
     1454    psS32 nXterm,
     1455    psS32 nYterm,
     1456    psS32 nZterm,
     1457    psS32 nTterm)
     1458{
     1459    psS32 nXsum = 0;
     1460    psS32 nYsum = 0;
     1461    psS32 nZsum = 0;
     1462    psS32 nTsum = 0;
     1463    psF64 xSum = 1.0;
     1464    psF64 ySum = 1.0;
     1465    psF64 zSum = 1.0;
     1466    psF64 tSum = 1.0;
     1467
     1468    nXsum = 2*nXterm;
     1469    nYsum = 2*nYterm;
     1470    nZsum = 2*nZterm;
     1471    nTsum = 2*nTterm;
     1472    if (sums == NULL) {
     1473        sums = (psF64 ****) psAlloc (nXsum*PSELEMTYPE_SIZEOF(psF64));
     1474        for (int i = 0; i < nXsum; i++) {
     1475            sums[i] = (psF64 ***) psAlloc (nYsum*PSELEMTYPE_SIZEOF(psF64));
     1476            for (int j = 0; j < nYsum; j++) {
     1477                sums[i][j] = (psF64 **) psAlloc (nZsum*PSELEMTYPE_SIZEOF(psF64));
     1478                for (int k = 0; k < nZsum; k++) {
     1479                    sums[i][j][k] = (psF64 *) psAlloc (nTsum*PSELEMTYPE_SIZEOF(psF64));
     1480                }
     1481            }
     1482        }
     1483    }
     1484    // careful with this function: there is no size checking and realloc for reuse
     1485
     1486    tSum = 1.0;
     1487    for (int m = 0; m < nTsum; m++) {
     1488        zSum = tSum;
     1489        for (int k = 0; k < nZsum; k++) {
     1490            ySum = zSum;
     1491            for (int j = 0; j < nYsum; j++) {
     1492                xSum = ySum;
     1493                for (int i = 0; i < nXsum; i++) {
     1494                    sums[i][j][k][m] = xSum;
     1495                    xSum *= x;
     1496                }
     1497                ySum *= y;
     1498            }
     1499            zSum *= z;
     1500        }
     1501        tSum *= t;
     1502    }
     1503    return (sums);
     1504}
     1505
     1506/******************************************************************************
    14451507Polynomial2DEvalVectorD(myPoly, x, y): This routine takes as input two
    14461508psVectors x and y, and evaluates myPoly for each pair of (x, y), and stores it
     
    16581720    // xSums look like: 1, x, x^2, ... x^(2n+1)
    16591721    // Build the B and A data structs.
     1722    // XXX EAM : use temp pointers eg vB = B->data.F64 to save redirects
     1723    // XXX EAM : this function is only valid for data vectors of F64
    16601724    for (int k = 0; k < f->n; k++) {
    1661         if ((mask != NULL) && mask->data.U8[k])
     1725        if ((mask != NULL) && (mask->data.U8[k] && maskValue)) {
    16621726            continue;
     1727        }
    16631728        if (x != NULL) {
    16641729            xSums = BuildSums1D(xSums, x->data.F64[k], nTerm);
     
    16701735            wt = 1.0;
    16711736        } else {
    1672             // this should filter fErr == 0 values
    1673             wt = 1.0 / PS_SQR(fErr->data.F64[k]);
     1737            // this filters fErr == 0 values
     1738            wt = (fErr->data.F64[k] == 0) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]);
    16741739        }
    16751740        for (int i = 0; i < nTerm; i++) {
     
    16861751    }
    16871752
    1688     // GaussJordan version
    1689     if (0) {
    1690         // does the solution in place
    1691         psGaussJordan (A, B);
    1692 
    1693         // the first nTerm entries in B correspond directly to the desired
    1694         // polynomial coefficients.  this is only true for the 1D case
    1695         for (int k = 0; k < nTerm; k++) {
    1696             myPoly->coeff[k] = B->data.F64[k];
    1697         }
    1698     } else {
    1699         // LUD version of the fit
    1700         psImage *ALUD = NULL;
    1701         psVector* outPerm = NULL;
    1702         psVector* coeffs = NULL;
    1703 
    1704         ALUD = psImageAlloc(nTerm, nTerm, PS_TYPE_F64);
    1705         ALUD = psMatrixLUD(ALUD, &outPerm, A);
    1706         coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
    1707         for (int k = 0; k < nTerm; k++) {
    1708             myPoly->coeff[k] = coeffs->data.F64[k];
    1709         }
    1710         psFree(ALUD);
    1711         psFree(coeffs);
    1712         psFree(outPerm);
     1753    // does the solution in place
     1754    psGaussJordan (A, B);
     1755
     1756    // the first nTerm entries in B correspond directly to the desired
     1757    // polynomial coefficients.  this is only true for the 1D case
     1758    for (int k = 0; k < nTerm; k++) {
     1759        myPoly->coeff[k] = B->data.F64[k];
    17131760    }
    17141761
     
    18191866}
    18201867
    1821 
     1868// This function accepts F32 and F64 input vectors.
    18221869psPolynomial1D *psVectorClipFitPolynomial1D(
    18231870    psPolynomial1D *poly,
     
    18271874    const psVector *f,
    18281875    const psVector *fErr,
    1829     const psVector *x)
     1876    const psVector *xIn)
    18301877{
    18311878    // Internal pointers for possibly NULL vectors.
    1832     psVector *x32 = NULL;
     1879    psVector *x = NULL;
    18331880
    18341881    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     
    18361883    PS_ASSERT_PTR_NON_NULL(stats, NULL);
    18371884    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
    1838     PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     1885    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL);
    18391886    if (mask != NULL) {
    18401887        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
    18411888        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
    18421889    }
    1843     if (x != NULL) {
    1844         PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, NULL);
    1845         PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     1890    if (xIn != NULL) {
     1891        PS_ASSERT_VECTORS_SIZE_EQUAL(f, xIn, NULL);
     1892        PS_ASSERT_VECTOR_TYPE_F32_OR_F64(xIn, NULL);
    18461893    }
    18471894    if (fErr != NULL) {
    18481895        PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL);
    1849         PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
    1850     }
    1851 
    1852     psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     1896        PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL);
     1897    }
     1898
     1899    // assign sequence vector if xIn is NULL
     1900    if (xIn == NULL) {
     1901        x = psVectorCreate (NULL, 0, f->n, 1, f->type);
     1902    } else {
     1903        x = xIn;
     1904    }
     1905
     1906    // clipping range defined by min and max and/or clipSigma
     1907    float minClipSigma;
     1908    float maxClipSigma;
     1909    if (finite(stats->max)) {
     1910        maxClipSigma = fabs(stats->clipSigma);
     1911    } else {
     1912        maxClipSigma = fabs(stats->max);
     1913    }
     1914    if (finite(stats->min)) {
     1915        minClipSigma = fabs(stats->clipSigma);
     1916    } else {
     1917        minClipSigma = fabs(stats->min);
     1918    }
     1919    psVector *fit   = NULL;
     1920    psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64);
     1921
     1922    // eventual expansion: user supplies one of various stats option pairs,
     1923    // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to
     1924    // evaluate the clipping sigma
     1925    // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used
     1926    stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     1927
     1928    for (int N = 0; N < stats->clipIter; N++) {
     1929        int Nkeep = 0;
     1930
     1931        poly = psVectorFitPolynomial1D (poly, mask, maskValue, f, fErr, x);
     1932        fit = psPolynomial1DEvalVector (poly, x);
     1933        resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit);
     1934
     1935        stats  = psVectorStats (stats, resid, NULL, mask, maskValue);
     1936        float minClipValue = -minClipSigma*stats->sampleStdev;
     1937        float maxClipValue = +maxClipSigma*stats->sampleStdev;
     1938
     1939        // set mask if pts are not valid
     1940        // we are masking out any point which is out of range
     1941        // recovery is not allowed with this scheme
     1942        for (int i = 0; i < resid->n; i++) {
     1943            if ((mask != NULL) && (mask->data.U8[i] & maskValue)) {
     1944                continue;
     1945            }
     1946            if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) {
     1947                if (mask != NULL) {
     1948                    mask->data.U8[i] |= 0x01;
     1949                }
     1950                continue;
     1951            }
     1952            if (resid->data.F64[i] - stats->sampleMedian < minClipValue) {
     1953                if (mask != NULL) {
     1954                    mask->data.U8[i] |= 0x01;
     1955                }
     1956                continue;
     1957            }
     1958            Nkeep ++;
     1959        }
     1960
     1961        psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n",
     1962                 Nkeep, x->n);
     1963
     1964        psFree (fit);
     1965    }
    18531966    // Free psVectors that were created for NULL arguments.
    1854     if (x == NULL) {
    1855         psFree(x32);
    1856     }
    1857     return(NULL);
     1967    if (xIn == NULL) {
     1968        psFree(x);
     1969    }
     1970    // Free other local temporary variables
     1971    psFree (resid);
     1972
     1973    return (poly);
    18581974}
    18591975
     
    19292045    // Build the B and A data structs.
    19302046    for (int k  = 0; k < x->n; k++) {
    1931         if ((mask != NULL) && mask->data.U8[k])
     2047        if ((mask != NULL) && (mask->data.U8[k] & maskValue)) {
    19322048            continue;
     2049        }
     2050
    19332051        Sums = BuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm);
    19342052
     
    19362054            wt = 1.0;
    19372055        } else {
    1938             // XXX: this should probably by fErr^2 !!
    1939             // this should filter fErr == 0 values
    1940             // XXX: Why isn't this fErr^2?
    1941             wt = 1.0 / fErr->data.F64[k];
     2056            // this filters fErr == 0 values
     2057            wt = (fErr->data.F64[k] == ) ? 0.0 : 1.0 / PS_SQR(fErr->data.F64[k]);
    19422058        }
    19432059
     
    19622078
    19632079    // does the solution in place
    1964     // XXX: Check return codes!
    19652080    psGaussJordan (A, B);
    19662081
    1967     // XXX: Check return codes!
    1968     // ALUD = psMatrixLUD(ALUD, &outPerm, A);
    1969     // coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
    1970 
     2082    // select the appropriate solution entries
    19712083    for (int n = 0; n < nXterm; n++) {
    19722084        for (int m = 0; m < nYterm; m++) {
     
    22512363    PS_ASSERT_PTR_NON_NULL(stats, NULL);
    22522364    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
    2253     PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2365    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL);
    22542366    if (mask != NULL) {
    22552367        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     
    22582370    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
    22592371    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
    2260     PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2372    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL);
    22612373    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
    22622374    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
    2263     PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2375    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL);
    22642376    if (fErr != NULL) {
    22652377        PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL);
    2266         PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
    2267     }
    2268 
    2269     if (mask == NULL) {
    2270         // XXX: Change argument order.
    2271         poly = RobustFit2D_nomask(poly, x, y, f, fErr);
     2378        PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL);
     2379    }
     2380
     2381    // clipping range defined by min and max and/or clipSigma
     2382    float minClipSigma;
     2383    float maxClipSigma;
     2384    if (finite(stats->max)) {
     2385        maxClipSigma = fabs(stats->clipSigma);
    22722386    } else {
    2273         // XXX: Use maskValue.
    2274         // XXX: Change argument order.
    2275         poly = RobustFit2D(poly, mask, x, y, f, fErr);
    2276     }
     2387        maxClipSigma = fabs(stats->max);
     2388    }
     2389    if (finite(stats->min)) {
     2390        minClipSigma = fabs(stats->clipSigma);
     2391    } else {
     2392        minClipSigma = fabs(stats->min);
     2393    }
     2394    psVector *fit   = NULL;
     2395    psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64);
     2396
     2397    // eventual expansion: user supplies one of various stats option pairs,
     2398    // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to
     2399    // evaluate the clipping sigma
     2400    // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used
     2401    stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     2402
     2403    for (int N = 0; N < stats->clipIter; N++) {
     2404        int Nkeep = 0;
     2405
     2406        poly = psVectorFitPolynomial2D (poly, mask, maskValue, f, fErr, x, y);
     2407        fit = psPolynomial2DEvalVector (poly, x, y);
     2408        resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit);
     2409
     2410        stats  = psVectorStats (stats, resid, NULL, mask, maskValue);
     2411        float minClipValue = -minClipSigma*stats->sampleStdev;
     2412        float maxClipValue = +maxClipSigma*stats->sampleStdev;
     2413
     2414        // set mask if pts are not valid
     2415        // we are masking out any point which is out of range
     2416        // recovery is not allowed with this scheme
     2417        for (int i = 0; i < resid->n; i++) {
     2418            if ((mask != NULL) && (mask->data.U8[i] & maskValue)) {
     2419                continue;
     2420            }
     2421            if (resid->data.F64[i] - stats->sampleMedian > maxClipValue) {
     2422                if (mask != NULL) {
     2423                    mask->data.U8[i] |= 0x01;
     2424                }
     2425                continue;
     2426            }
     2427            if (resid->data.F64[i] - stats->sampleMedian < minClipValue) {
     2428                if (mask != NULL) {
     2429                    mask->data.U8[i] |= 0x01;
     2430                }
     2431                continue;
     2432            }
     2433            Nkeep ++;
     2434        }
     2435
     2436        psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n",
     2437                 Nkeep, x->n);
     2438
     2439        psFree (fit);
     2440    }
     2441    // Free local temporary variables
     2442    psFree (resid);
    22772443
    22782444    if (poly == NULL) {
Note: See TracChangeset for help on using the changeset viewer.