IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 26, 2004, 1:14:04 PM (22 years ago)
Author:
gusciora
Message:

Modified the prototype for the LM minimization routines.

File:
1 edited

Legend:

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

    r2197 r2202  
    99 *  @author GLF, MHPCC
    1010 *
    11  *  @version $Revision: 1.59 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-10-26 21:24:42 $
     11 *  @version $Revision: 1.60 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-10-26 23:14:04 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    393393
    394394/******************************************************************************
    395 psMinimizeLMChi2():  This routine will take an procedure which calculates an
    396 arbitrary function and it's derivative and minimize the chi-squared match
     395psMinimizeLMChi2():  This routine will take an procedure which calculates
     396an arbitrary function and it's derivative and minimize the chi-squared match
    397397between that function at the specified coords and the specified value at
    398398those coords.
     
    417417 *****************************************************************************/
    418418bool psMinimizeLMChi2(psMinimization *min,
     419                      psImage *covar,
    419420                      psVector *params,
    420421                      const psVector *paramMask,
    421                       psImage *covar,
    422                       const psArray *coords,
    423                       const psVector *value,
     422                      const psArray *x,
     423                      const psVector *y,
     424                      const psVector *yErr,
    424425                      psMinimizeLMChi2Func func)
    425 {
    426     PS_CHECK_NULL_PTR_RETURN_NULL(min);
    427     PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
    428     PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
    429     PS_CHECK_NULL_PTR_RETURN_NULL(coords);
    430     PS_CHECK_NULL_VECTOR_RETURN_NULL(value);
    431     PS_CHECK_EMPTY_VECTOR_RETURN_NULL(value);
    432     if (paramMask != NULL) {
    433         PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, paramMask);
    434     }
    435     psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    436             "---- psMinimizeLMChi2() begin ----\n");
    437     int numData = value->n;
    438     int numParams = params->n;
    439     int i;
    440     int j;
    441     int k;
    442     int l;
    443     int n;
    444     int p;
    445     psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
    446     psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64);
    447 
    448     psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64);
    449     psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32);
    450     psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32);
    451 
    452     psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32);
    453     psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64);
    454     psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64);
    455 
    456     psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *));
    457     for (i=0;i<numData;i++) {
    458         deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32);
    459     }
    460 
    461     psVector *currValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
    462     psVector *newValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
    463 
    464     float currChi2 = 0.0;
    465     float newChi2 = 0.0;
    466     float lamda = 0.00005;
    467 
    468     psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    469             "min->maxIter is %d\n", min->maxIter);
    470     psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    471             "min->tol is %f\n", min->tol);
    472 
    473     for (p=0;p<numParams;p++) {
    474         origParams->data.F32[p] = params->data.F32[p];
    475     }
    476 
    477     min->lastDelta = HUGE;
    478     min->iter = 0;
    479 
    480     while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
    481         psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    482                 "------------------------------------------------------\n");
    483         psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    484                 "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
    485 
    486         //
    487         // Calculate the current values and chi-squared of the function.
    488         //
    489         currChi2 = 0.0;
    490         for (n=0;n<numData;n++) {
    491             currValueVec->data.F32[n] = func(deriv[n],
    492                                              params,
    493                                              (psVector *) coords->data[n]);
    494             currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]);
    495         }
    496 
    497         for (p=0;p<numParams;p++) {
    498             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    499                     "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
    500         }
    501         psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    502                 "Current chi-squared is (%f)\n", currChi2);
    503 
    504         //
    505         // Mask elements of the derivative for each data point.
    506         //
    507         for (p=0;p<numParams;p++) {
    508             if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) {
    509                 for (n=0;n<numData;n++) {
    510                     (deriv[n])->data.F32[p] = 0.0;
    511                 }
    512             }
    513         }
    514 
    515         //
    516         // Calculate the BETA vector.
    517         //
    518         for (p=0;p<numParams;p++) {
    519             beta->data.F64[p] = 0.0;
    520             for (n=0;n<numData;n++) {
    521                 (beta->data.F64[p])+=
    522                     (value->data.F32[n] - currValueVec->data.F32[n]) *
    523                     (deriv[n])->data.F32[p];
    524             }
    525             // XXX: multiple by -1 here?
    526             (beta->data.F64[p])*= -1.0;
    527             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    528                     "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
    529         }
    530 
    531         //
    532         // Calculate the ALPHA matrix.
    533         //
    534         for (k=0;k<numParams;k++) {
    535             for (l=0;l<numParams;l++) {
    536                 alpha->data.F32[k][l] = 0.0;
    537                 for (n=0;n<numData;n++) {
    538                     alpha->data.F32[k][l]+= (deriv[n])->data.F32[k] *
    539                                             (deriv[n])->data.F32[l];
    540                 }
    541             }
    542         }
    543 
    544         //
    545         // Calculate the matrix A.
    546         //
    547         for (j=0;j<numParams;j++) {
    548             for (k=0;k<numParams;k++) {
    549                 if (j == k) {
    550                     A->data.F64[j][k] =
    551                         (double) ((1.0 + lamda) * alpha->data.F32[j][k]);
    552                 } else {
    553                     A->data.F64[j][k] = (double) alpha->data.F32[j][k];
    554                 }
    555             }
    556         }
    557         for (j=0;j<numParams;j++) {
    558             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
    559             for (k=0;k<numParams;k++) {
    560                 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]);
    561             }
    562             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
    563         }
    564 
    565         //
    566         // Solve A * alpha = Beta
    567         //
    568         aOut = psMatrixLUD(aOut, perm, A);
    569         paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
    570 
    571         //
    572         // Mask any masked parameters.
    573         //
    574         for (i=0;i<numParams;i++) {
    575             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    576                     "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]);
    577             if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) {
    578                 newParams->data.F32[i] = origParams->data.F32[i];
    579             } else {
    580                 newParams->data.F32[i] = params->data.F32[i] -
    581                                          (float) paramDeltasF64->data.F64[i];
    582             }
    583         }
    584 
    585         psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    586                 "Calling func() with new parameters:\n");
    587         for (i=0;i<numParams;i++) {
    588             psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
    589                     "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
    590         }
    591 
    592 
    593         //
    594         // Calculate new function values.
    595         //
    596         newChi2 = 0.0;
    597         for (n=0;n<numData;n++) {
    598             newValueVec->data.F32[n] = func(deriv[n], newParams,
    599                                             (psVector *) coords->data[n]);
    600             newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]);
    601         }
    602         psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    603                 "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2);
    604 
    605         //
    606         // If the new chi-squared is lower, then keep it.
    607         //
    608         if (currChi2 > newChi2) {
    609             min->lastDelta = currChi2 - newChi2;
    610             min->value = newChi2;
    611 
    612             // We already masked params.
    613             for (i=0;i<numParams;i++) {
    614                 params->data.F32[i] = (float) newParams->data.F32[i];
    615             }
    616             lamda*= 0.1;
    617         } else {
    618             lamda*= 10.0;
    619         }
    620         psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    621                 "lamda is %f\n", lamda);
    622         min->iter++;
    623     }
    624     psFree(beta);
    625     psFree(perm);
    626     psFree(paramDeltasF64);
    627     psFree(origParams);
    628     psFree(newParams);
    629     psFree(alpha);
    630     psFree(A);
    631     psFree(aOut);
    632     for (i=0;i<numData;i++) {
    633         psFree(deriv[i]);
    634     }
    635     psFree(deriv);
    636     psFree(currValueVec);
    637     psFree(newValueVec);
    638 
    639     if ((min->iter < min->maxIter) ||
    640             (min->lastDelta <= min->tol)) {
    641         return(true);
    642     }
    643 
    644     psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
    645             "---- psMinimizeLMChi2() end (false) ----\n");
    646     return(false);
    647 }
    648 
    649 /******************************************************************************
    650 psMyMinimizeLMChi2():  This routine will take an procedure which calculates
    651 an arbitrary function and it's derivative and minimize the chi-squared match
    652 between that function at the specified coords and the specified value at
    653 those coords.
    654  
    655 XXX: Do this:
    656  After checking that all entries in the paramMask are 1 or 0, when
    657  forming the A matrix from alpha, try this:
    658  
    659      A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i];
    660  
    661 XXX: This is very different from what is specified in the SDR.  Must
    662 coordinate with IfA on new SDR.
    663  
    664 XXX: Do vector/image recycles.
    665  
    666 XXX: probably yErr will be part of the SDR.
    667  
    668 XXX: This must work for both F32 and F64.  F32 is currently implemented.
    669      Note: since the LUD routines are only implemented in F64, then we
    670      will have to convert all F32 input vectors to F64 regardless.  So,
    671      the F64 port might be.
    672  *****************************************************************************/
    673 bool psMyMinimizeLMChi2(psMinimization *min,
    674                         psImage *covar,
    675                         psVector *params,
    676                         const psVector *paramMask,
    677                         const psArray *x,
    678                         const psVector *y,
    679                         const psVector *yErr,
    680                         psMyMinimizeLMChi2Func func)
    681426{
    682427    PS_CHECK_NULL_PTR_RETURN_NULL(min);
Note: See TracChangeset for help on using the changeset viewer.