IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6388


Ignore:
Timestamp:
Feb 8, 2006, 2:52:18 PM (20 years ago)
Author:
gusciora
Message:

The psPlaneTransformFit() was completely rewritten and simplified. We now
simply call the psVectorPolynomial2DFit() routines.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/astro/psCoord.c

    r6384 r6388  
    1010*  @author GLG, MHPCC
    1111*
    12 *  @version $Revision: 1.109 $ $Name: not supported by cvs2svn $
    13 *  @date $Date: 2006-02-08 21:52:05 $
     12*  @version $Revision: 1.110 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2006-02-09 00:52:18 $
    1414*
    1515*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2828#include "psErrorText.h"
    2929#include "psMatrix.h"
     30#include "psMinimizePolyFit.h"
    3031#include <math.h>
    3132#include <float.h>
     
    461462        out = psSphereAlloc();
    462463    } else {
     464        if ( !psMemCheckType(PS_DATA_SPHERE, outSphere) ) {
     465            psError(PS_ERR_UNKNOWN, true, "outSphere must be of type *psSphere.\n");
     466            return(NULL);
     467        }
    463468        out = outSphere;
    464         // XXX: Do a memory checkpointer.
    465469    }
    466470
     
    565569                for (psS32 t2x = 0 ; t2x < (1 + trans2->nX) ; t2x++) {
    566570                    for (psS32 t2y = 0 ; t2y < (1 + trans2->nY) ; t2y++) {
    567                         /* Possible debug-only macro which checks these coords?
    568                         if ((t1x+t2x) >= orderX)
    569                             printf("BAD 1\n");
    570                         if ((t1y+t2y) >= orderY)
    571                             printf("BAD 2\n");
    572                         */
    573571                        out->coeff[t1x+t2x][t1y+t2y]+= (trans1->coeff[t1x][t1y] * trans2->coeff[t2x][t2y]);
    574572                    }
     
    625623    // Allocate the new psPlaneTransform, if necessary.
    626624    //
    627     // XXX: rename, or verify, or recode, after the poly norder/nterm change.
    628625
    629626    psPlaneTransform *myPT = NULL;
     
    639636            // Initialize the new psPlaneTransform, if necessary.
    640637            //
    641             for (psS32 i = 0 ; i < orderX ; i++) {
    642                 for (psS32 j = 0 ; j < orderY ; j++) {
     638            for (psS32 i = 0 ; i < orderX+1 ; i++) {
     639                for (psS32 j = 0 ; j < orderY+1 ; j++) {
    643640                    myPT->x->coeff[i][j] = 0.0;
    644641                    myPT->x->mask[i][j] = 0;
     
    769766psPlaneTransformFit(trans, source, dest, nRejIter, sigmaClip)
    770767 
    771 XXX: What about nRejIter?  Iterations?
    772 XXX: This code has problems with data that corresponds to a non-linear fit.
     768XXX: This code ignores nRejIter and sigmaClip.
    773769 *****************************************************************************/
    774770bool psPlaneTransformFit(
     
    783779    PS_ASSERT_PTR_NON_NULL(dest, NULL);
    784780
    785     psBool rc = true;
     781    //
     782    // Create the x and y vectors for the psVectorFitPolynomial2D() function.
     783    //
    786784    psS32 numCoords = PS_MIN(source->n, dest->n);
    787     psS32 order = PS_MAX(trans->x->nX, trans->x->nY);
    788     order = PS_MAX(order, trans->y->nX);
    789     order = PS_MAX(order, trans->y->nY);
    790     // XXX: Verify, or recode, after the poly norder/nterm change.
    791     order++;
    792 
    793     //
    794     // Create fake polynomial to use in evaluation
    795     //
    796     // XXX: Verify this (poly order/nterm change)
    797     psPolynomial2D *fakePoly = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, order-1, order-1);
    798     for (int i = 0; i < order; i++) {
    799         for (int j = 0; j < order; j++) {
    800             fakePoly->coeff[i][j] = 1.0;
    801             fakePoly->mask[i][j] = 1;       // Mask all coefficients; unmask to evaluate
    802         }
    803     }
    804 
    805     //
    806     // Initialize the matrix and vectors
    807     //
    808     psS32 nCoeff = order * (order + 1) / 2; // Number of polynomial coefficients
    809     psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution
    810     psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x
    811     psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y
    812     for (psS32 i = 0; i < nCoeff; i++) {
    813         for (psS32 j = 0; j < nCoeff; j++) {
    814             matrix->data.F64[i][j] = 0.0;
    815         }
    816         xVector->data.F64[i] = 0.0;
    817         yVector->data.F64[i] = 0.0;
    818     }
    819 
    820     //
    821     // Iterate over the grid points
    822     //
     785    psVector *xIn = psVectorAlloc(numCoords, PS_TYPE_F64);
     786    psVector *yIn = psVectorAlloc(numCoords, PS_TYPE_F64);
     787    psVector *xOut = psVectorAlloc(numCoords, PS_TYPE_F64);
     788    psVector *yOut = psVectorAlloc(numCoords, PS_TYPE_F64);
    823789    for (psS32 g = 0; g < numCoords; g++) {
    824         // Iterate over the polynomial coefficients, accumulating the matrix and vectors
    825 
    826         for (psS32 i = 0, ijIndex = 0; i < order; i++) {
    827             for (psS32 j = 0; j < order - i; j++, ijIndex++) {
    828                 fakePoly->mask[i][j] = 0;
    829                 psF64 xIn = ((psPlane *) source->data[g])->x;
    830                 psF64 yIn = ((psPlane *) source->data[g])->y;
    831                 psF64 xOut = ((psPlane *) dest->data[g])->x;
    832                 psF64 yOut = ((psPlane *) dest->data[g])->y;
    833                 psF64 ijPoly = psPolynomial2DEval(fakePoly, xIn, yIn);
    834                 fakePoly->mask[i][j] = 1;
    835 
    836                 for (psS32 m = 0, mnIndex = 0; m < order; m++) {
    837                     for (psS32 n = 0; n < order - m; n++, mnIndex++) {
    838                         fakePoly->mask[m][n] = 0;
    839                         psF64 mnPoly = psPolynomial2DEval(fakePoly, xIn, yIn);
    840                         fakePoly->mask[m][n] = 1;
    841 
    842                         matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly;
    843                     }
    844                 }
    845 
    846                 xVector->data.F64[ijIndex] += ijPoly * xOut;
    847                 yVector->data.F64[ijIndex] += ijPoly * yOut;
    848             }
    849         }
    850     }
    851 
    852     //
    853     // Solution via LU Decomposition
    854     //
    855     psVector *xSolution;
    856     psVector *ySolution;
    857     psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition
    858     psImage *luMatrix = psMatrixLUD(NULL, &permutation, matrix); // LU decomposed matrix
    859     if (luMatrix == NULL) {
    860         rc = false;
    861         psError(PS_ERR_UNKNOWN, true, "psMatrixLUD() returned NULL.  Returning FALSE.\n");
    862     } else {
    863         xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x
    864         ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y
    865 
    866         if ((xSolution == NULL) || (ySolution == NULL)) {
    867             rc = false;
    868             psError(PS_ERR_UNKNOWN, true, "psMatrixLUSolve() returned NULL.  Returning FALSE.\n");
    869         } else {
    870             //
    871             // Stuff coefficients into transformation
    872             //
    873             for (psS32 i = 0, ijIndex = 0; i < order; i++) {
    874                 for (psS32 j = 0; j < order - i; j++, ijIndex++) {
    875                     trans->x->coeff[i][j] = xSolution->data.F64[ijIndex];
    876                     trans->y->coeff[i][j] = ySolution->data.F64[ijIndex];
    877                 }
    878             }
    879         }
    880     }
    881 
    882     psFree(fakePoly);
    883     psFree(permutation);
    884     psFree(luMatrix);
    885     psFree(xSolution);
    886     psFree(ySolution);
    887     psFree(matrix);
    888     psFree(xVector);
    889     psFree(yVector);
    890 
    891     return(rc);
    892 }
     790        xIn->data.F64[g] = ((psPlane *) source->data[g])->x;
     791        yIn->data.F64[g] = ((psPlane *) source->data[g])->y;
     792        xOut->data.F64[g] = ((psPlane *) dest->data[g])->x;
     793        yOut->data.F64[g] = ((psPlane *) dest->data[g])->y;
     794    }
     795
     796    trans->x = psVectorFitPolynomial2D(trans->x, NULL, 0, xOut, NULL, xIn, yIn);
     797    trans->y = psVectorFitPolynomial2D(trans->y, NULL, 0, yOut, NULL, xIn, yIn);
     798    psFree(xIn);
     799    psFree(yIn);
     800    psFree(xOut);
     801    psFree(yOut);
     802
     803    if ((trans->x == NULL) || (trans->y == NULL)) {
     804        psError( PS_ERR_UNKNOWN, true, "psVectorFitPolynomial2D() returned NULL: could not fit a 2-D polynomial to the data.\n");
     805        return(false);
     806    }
     807
     808    return(true);
     809}
     810
    893811
    894812
Note: See TracChangeset for help on using the changeset viewer.