IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 4, 2021, 6:10:51 PM (5 years ago)
Author:
eugene
Message:

merge changes from eam_branches/ipp-dev-20210817 (fix chebyshevs 1D, 2D, set DB field to NULL for inf, psFitsTableNew)

File:
1 edited

Legend:

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

    r41532 r41896  
    3535
    3636#include "psMinimizePolyFit.h"
     37#include "psAbort.h"
    3738#include "psAssert.h"
    3839#include "psMinimizeLMM.h"  // For Gauss-Jordan routines
     
    12251226
    12261227/******************************************************************************
     1228VectorFitPolynomial2DCheb(myPoly, *mask, maskValue, *f, *fErr, *x, *y): This is
     1229a private routine which will fit a 2-D polynomial to a set of (x, y)-(f)
     1230pairs.  All non-NULL vectors must be of type PS_TYPE_F64.
     1231 
     1232 *****************************************************************************/
     1233static bool VectorFitPolynomial2DCheb(
     1234    psPolynomial2D* myPoly,
     1235    const psVector *f,
     1236    const psVector *x,
     1237    const psVector *y)
     1238{
     1239    psTrace("psLib.math", 4, "---- %s() begin ----\n", __func__);
     1240    PS_ASSERT_POLY_NON_NULL(myPoly, false);
     1241    PS_ASSERT_INT_NONNEGATIVE(myPoly->nX, false);
     1242    PS_ASSERT_INT_NONNEGATIVE(myPoly->nY, false);
     1243    PS_ASSERT_VECTOR_NON_NULL(f, false);
     1244    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F64, false);
     1245    PS_ASSERT_VECTOR_NON_NULL(x, false);
     1246    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F64, false);
     1247    PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, false);
     1248    PS_ASSERT_VECTOR_NON_NULL(y, false);
     1249    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F64, false);
     1250    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, false);
     1251
     1252    // Number of polynomial terms
     1253    int nXterm = 1 + myPoly->nX;      // Number of terms in x
     1254    int nYterm = 1 + myPoly->nY;      // Number of terms in y
     1255    int nTerm = nXterm * nYterm;      // Total number of terms
     1256    if (nXterm > 9) {
     1257        psError(PS_ERR_UNKNOWN, false, "failed 2D chebyshev fit: orders higher than 9 are not yet coded\n");
     1258        return false;
     1259    }
     1260    if (nYterm > 9) {
     1261        psError(PS_ERR_UNKNOWN, false, "failed 2D chebyshev fit: orders higher than 9 are not yet coded\n");
     1262        return false;
     1263    }
     1264
     1265    // determine scale factors
     1266    if (!psChebyshevSetScale (myPoly, x, 0)) { psError(PS_ERR_UNKNOWN, false, "failed 2D chebyshev fit.\n"); return false; }
     1267    if (!psChebyshevSetScale (myPoly, y, 1)) { psError(PS_ERR_UNKNOWN, false, "failed 2D chebyshev fit.\n"); return false; }
     1268
     1269    // generate normalized vectors
     1270    psVector *xNorm = psChebyshevNormVector (myPoly, x, 0);
     1271    psVector *yNorm = psChebyshevNormVector (myPoly, y, 1);
     1272
     1273    // generate the N cheb polynomials based on xNorm, yNorm
     1274    psArray *xPolySet = psArrayAlloc (nXterm);
     1275    for (int i = 0; i < nXterm; i++) {
     1276        xPolySet->data[i] = psChebyshevPolyVector (xNorm, i);
     1277    }
     1278    psArray *yPolySet = psArrayAlloc (nYterm);
     1279    for (int i = 0; i < nYterm; i++) {
     1280        yPolySet->data[i] = psChebyshevPolyVector (yNorm, i);
     1281    }
     1282
     1283    psF64 *fData = f->data.F64;         // Dereference f
     1284
     1285    psImage *A = psImageAlloc(nTerm, nTerm, PS_TYPE_F64); // Least-squares matrix
     1286    psVector *B = psVectorAlloc(nTerm, PS_TYPE_F64); // Least-squares vector
     1287
     1288    // Initialize data structures (should not be able to fail)
     1289    psAssert (psImageInit(A, 0.0), "Could initialize data structures A");
     1290    psAssert (psVectorInit(B, 0.0), "Could initialize data structures B");
     1291
     1292    // Dereference stuff, to make the loop go faster
     1293    psF64 **matrix = A->data.F64;       // Dereference the least-squares matrix
     1294    psF64 *vector = B->data.F64;        // Dereference the least-squares vector
     1295
     1296    // loop over all elements of the data vector
     1297    for (int k = 0; k < x->n; k++) {
     1298
     1299        if (!finite(fData[k])) continue;
     1300   
     1301        // XXX can we only calculate the upper diagonal?
     1302        int nelem = 0;
     1303        for (int jx = 0; jx < nXterm; jx++) {
     1304            psVector *jxCheb = xPolySet->data[jx];
     1305            for (int jy = 0; jy < nYterm; jy++) {
     1306                psVector *jyCheb = yPolySet->data[jy];
     1307                psF64 chebValue = jxCheb->data.F64[k] * jyCheb->data.F64[k];
     1308               
     1309                vector[nelem] += fData[k] * chebValue;
     1310
     1311                int melem = 0;
     1312                for (int kx = 0; kx < nXterm; kx++) {
     1313                    psVector *kxCheb = xPolySet->data[kx];
     1314                    for (int ky = 0; ky < nYterm; ky++) {
     1315                        psVector *kyCheb = yPolySet->data[ky];
     1316                        matrix[nelem][melem] += chebValue * kxCheb->data.F64[k]*kyCheb->data.F64[k];
     1317                        melem++;
     1318                    }
     1319                }
     1320                nelem++;
     1321            }
     1322        }
     1323    }
     1324
     1325    if (psTraceGetLevel("psLib.math") >= 4) {
     1326        printf("Least-squares vector:\n");
     1327        for (int i = 0; i < nTerm; i++) {
     1328            printf("%f ", B->data.F64[i]);
     1329        }
     1330        printf("\n");
     1331        printf("Least-squares matrix:\n");
     1332        for (int i = 0; i < nTerm; i++) {
     1333            for (int j = 0; j < nTerm; j++) {
     1334                printf("%f ", A->data.F64[i][j]);
     1335            }
     1336            printf("\n");
     1337        }
     1338    }
     1339
     1340    bool status = false;
     1341    if (USE_GAUSS_JORDAN) {
     1342        status = psMatrixGJSolve(A, B);
     1343    } else {
     1344        status = psMatrixLUSolve(A, B);
     1345    }
     1346    if (!status) {
     1347        psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations.\n");
     1348        goto escape;
     1349    }
     1350
     1351    // unroll the result:
     1352    int nelem = 0;
     1353    for (int jx = 0; jx < nXterm; jx++) {
     1354        for (int jy = 0; jy < nYterm; jy++) {
     1355            myPoly->coeff[jx][jy]    = B->data.F64[nelem];
     1356            myPoly->coeffErr[jx][jy] = sqrt(A->data.F64[nelem][nelem]);
     1357            nelem ++;
     1358        }
     1359    }
     1360    psFree(A);
     1361    psFree(B);
     1362
     1363    psFree (xNorm);
     1364    psFree (yNorm);
     1365    psFree (xPolySet);
     1366    psFree (yPolySet);
     1367
     1368    return true;
     1369
     1370escape:
     1371    psFree (A);
     1372    psFree (B);
     1373    return false;
     1374}
     1375
     1376/******************************************************************************
    12271377psVectorFitPolynomial2D():  This routine fits a 2D polynomial of arbitrary
    12281378degree (specified in poly) to the data points (x, y)-(f) and returns that
     
    12401390{
    12411391    PS_ASSERT_POLY_NON_NULL(poly, false);
    1242     PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, false);
     1392    // PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, false);
    12431393
    12441394    PS_ASSERT_VECTOR_NON_NULL(f, false);
     
    12771427        break;
    12781428    case PS_POLYNOMIAL_CHEB:
    1279         if (mask != NULL) {
    1280             psLogMsg(__func__, PS_LOG_WARN, "WARNING: ignoring mask and maskValue with Chebyshev polynomials.\n");
    1281         }
    1282         psError(PS_ERR_UNKNOWN, true, "2-D Chebyshev polynomial vector fitting has not been implemented.  Returning NULL.\n");
    1283         result = false;
    1284         break;
     1429      if (mask != NULL) {
     1430          psLogMsg(__func__, PS_LOG_WARN, "WARNING: ignoring mask and maskValue with Chebyshev polynomials.\n");
     1431      }
     1432      if (fErr != NULL) {
     1433          psLogMsg(__func__, PS_LOG_WARN, "WARNING: ignoring error values for Chebyshev polynomials.\n");
     1434      }
     1435      result = VectorFitPolynomial2DCheb(poly, f64, x64, y64);
     1436      if (!result) {
     1437          psError(PS_ERR_UNKNOWN, true, "Could not fit polynomial.  Returning NULL.\n");
     1438      }
     1439      break;
    12851440    default:
    12861441        psError(PS_ERR_UNKNOWN, true, "Incorrect polynomial type.  Returning NULL.\n");
Note: See TracChangeset for help on using the changeset viewer.