IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 28655


Ignore:
Timestamp:
Jul 11, 2010, 3:18:21 PM (16 years ago)
Author:
eugene
Message:

add maxTol and maxChisqDOF to psMin to allow for better control over fit success and convergence

Location:
branches/eam_branches/ipp-20100621/psLib/src/math
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20100621/psLib/src/math/psMinimizeLMM.c

    r26951 r28655  
    441441    }
    442442
     443    // number of degrees of freedom for this fit
     444    int nDOF = dy->n - params->n;
     445
    443446    // calculate initial alpha and beta, set chisq (min->value)
    444447    min->value = psMinLM_SetABX(alpha, beta, params, paramMask, x, y, dy, func);
     
    456459    }
    457460
    458     // iterate until the tolerance is reached, or give up
    459     while ((min->iter < min->maxIter) && ((min->lastDelta > min->tol) || !isfinite(min->lastDelta))) {
     461    // iterate until: (a) nIter = min->iter or (b) (chisq / ndof) < maxChisq and deltaChisq < minTol (but don't stop unless Chisq is finite)
     462    bool done = (min->iter >= min->maxIter);
     463    while (!done) {
    460464        psTrace("psLib.math", 5, "Iteration number %d.  (max iterations is %d).\n", min->iter, min->maxIter);
    461         psTrace("psLib.math", 5, "Last delta is %f.  Min->tol is %f.\n", min->lastDelta, min->tol);
     465        psTrace("psLib.math", 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol);
    462466
    463467        // set a new guess for Alpha, Beta, Params
    464468        if (!psMinLM_GuessABP(Alpha, Beta, Params, alpha, beta, params, paramMask, checkLimits, lambda, &dLinear)) {
    465469            min->iter ++;
     470            if (min->iter >=  min->maxIter) break;
    466471            lambda *= 10.0;
    467472            continue;
     
    482487        if (isnan(Chisq)) {
    483488            min->iter ++;
     489            if (min->iter >= min->maxIter) break;
    484490            lambda *= 10.0;
    485491            continue;
     
    492498        psF32 rho = (min->value - Chisq) / dLinear;
    493499
    494         psTrace("psLib.math", 5, "last chisq: %f, new chisq %f, delta: %f, dLinear: %f, rho: %f, lambda: %f\n", min->value,
    495                 Chisq, min->lastDelta, dLinear, rho, lambda);
    496 
    497         psTrace("psLib.math.dLinear", 5, "last chisq: %f, new chisq %f, delta: %f, dLinear: %f, rho: %f, lambda: %f\n", min->value,
    498                 Chisq, min->lastDelta, dLinear, rho, lambda);
     500        psTrace("psLib.math", 5, "last chisq: %f, new chisq %f, delta: %f, dLinear: %f, rho: %f, lambda: %f, nDOF: %d\n", min->value, Chisq, min->lastDelta, dLinear, rho, lambda, nDOF);
     501
     502        psTrace("psLib.math.dLinear", 5, "last chisq: %f, new chisq %f, delta: %f, dLinear: %f, rho: %f, lambda: %f\n", min->value, Chisq, min->lastDelta, dLinear, rho, lambda);
    499503
    500504        // dump some useful info if trace is defined
     
    506510        /* rho is positive if the new chisq is smaller; allow for some insignificant change (slight negative rho) */
    507511        if (rho >= -1e-6) {
    508             min->lastDelta = (min->value - Chisq) / (dy->n - params->n);
     512            min->lastDelta = (min->value - Chisq) / nDOF;
    509513            min->value = Chisq;
    510514            alpha  = psImageCopy(alpha, Alpha, PS_TYPE_F32);
     
    516520        }
    517521        min->iter++;
     522
     523        done = (min->iter >= min->maxIter);
     524       
     525        // check for convergence:
     526        float chisqDOF = Chisq / nDOF;
     527        if (!isfinite(min->maxChisqDOF) || ((chisqDOF < min->maxChisqDOF) && isfinite(min->lastDelta))) {
     528            done |= (min->lastDelta < min->minTol);
     529        }
    518530    }
    519531    psTrace("psLib.math", 5, "chisq: %f, last delta: %f, Niter: %d\n", min->value, min->lastDelta, min->iter);
     
    549561        psFree(dy);
    550562    }
    551     if (min->iter == min->maxIter) {
    552         psTrace("psLib.math", 3, "---- end (false) ----\n");
    553         return(false);
    554     }
    555     psTrace("psLib.math", 3, "---- end (true) ----\n");
    556     return(true);
     563
     564    // if the last improvement was at least as good as maxTol, accept the fit:
     565    if (min->lastDelta <= min->maxTol) {
     566        psTrace("psLib.math", 6, "---- end (true) ----\n");
     567        return(true);
     568    }
     569    psTrace("psLib.math", 6, "---- end (false) ----\n");
     570    return(false);
    557571}
    558572
     
    588602}
    589603
    590 psMinimization *psMinimizationAlloc(int maxIter,
    591                                     float tol)
     604psMinimization *psMinimizationAlloc(int maxIter, float minTol, float maxTol)
    592605{
    593606    PS_ASSERT_INT_NONNEGATIVE(maxIter, NULL);
     
    595608    psMinimization *min = psAlloc(sizeof(psMinimization));
    596609    psMemSetDeallocator(min, (psFreeFunc)minimizationFree);
     610
    597611    P_PSMINIMIZATION_SET_MAXITER(min,maxIter);
    598     P_PSMINIMIZATION_SET_TOL(min,tol);
     612    P_PSMINIMIZATION_SET_MIN_TOL(min,minTol);
     613    P_PSMINIMIZATION_SET_MAX_TOL(min,maxTol);
     614
    599615    min->value = 0.0;
    600616    min->iter = 0;
    601617    min->lastDelta = NAN;
     618    min->maxChisqDOF = NAN;
    602619
    603620    return(min);
  • branches/eam_branches/ipp-20100621/psLib/src/math/psMinimizeLMM.h

    r23486 r28655  
    3333#define PS_MAX_LMM_ITERATIONS 100
    3434#define PS_MAX_MINIMIZE_ITERATIONS 100
    35 #define P_PSMINIMIZATION_SET_MAXITER(m,val) *(int*)&m->maxIter = val
    36         #define P_PSMINIMIZATION_SET_TOL(m,val) *(float*)&m->tol = val
     35#define P_PSMINIMIZATION_SET_MAXITER(m,val) { *(int*)&m->maxIter  = val; }
     36#define P_PSMINIMIZATION_SET_MIN_TOL(m,val) { *(float*)&m->minTol = val; }
     37#define P_PSMINIMIZATION_SET_MAX_TOL(m,val) { *(float*)&m->maxTol = val; }
    3738
    3839                typedef enum {
     
    7576typedef struct
    7677{
    77     const int maxIter;                 ///< Convergence limit
    78     const float tol;                   ///< Error Tolerance
     78    const int maxIter;                  ///< Convergence limit
     79    const float minTol;                 ///< Convergence Tolerance (stop if we reach this value)
     80    const float maxTol;                 ///< Max Tolerance (accept fit if last improvement was this good)
    7981    float value;                       ///< Value of function at minimum
    8082    int iter;                          ///< Number of iterations to date
    8183    float lastDelta;                   ///< The last difference for the fit
     84    float maxChisqDOF;                 ///< for Chisq minimization, require that we reach here before checking tolerance
    8285}
    8386psMinimization;
     
    102105psMinimization *psMinimizationAlloc(
    103106    int maxIter,                       ///< Number of minimization iterations to perform.
    104     float tol                          ///< Requested error tolerance
     107    float minTol,                      ///< stop if tolerance is less than this
     108    float maxTol                       ///< accept fit if tolerance is less than this
    105109) PS_ATTR_MALLOC;
    106110
  • branches/eam_branches/ipp-20100621/psLib/src/math/psMinimizePowell.c

    r21183 r28655  
    457457
    458458        mul = bracket->data.F32[1];
    459         if ((fabs(a-b) < min->tol) && (fabs(b-c) < min->tol)) {
     459        if ((fabs(a-b) < min->minTol) && (fabs(b-c) < min->minTol)) {
    460460            PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, params, mul);
    461461            min->value = func(params, coords);
     
    524524    psTrace("psLib.math", 4, "---- psMinimizePowell() begin ----\n");
    525525    psTrace("psLib.math", 6, "min->maxIter is %d\n", min->maxIter);
    526     psTrace("psLib.math", 6, "min->tol is %f\n", min->tol);
     526    psTrace("psLib.math", 6, "min->minTol is %f\n", min->minTol);
    527527
    528528    if (paramMask == NULL) {
     
    573573        for (i=0;i<numDims;i++) {
    574574            if (myParamMask->data.PS_TYPE_VECTOR_MASK_DATA[i] == 0) {
     575
    575576                P_PSMINIMIZATION_SET_MAXITER((&dummyMin),PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS);
    576                 *(float*)&dummyMin.tol = PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE;
     577                P_PSMINIMIZATION_SET_MIN_TOL((&dummyMin),PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE);
     578
    577579                mul = LineMin(&dummyMin, Q, ((psVector *) v->data[i]),
    578580                              myParamMask, coords, func);
     
    677679
    678680        // 8: Go to step 3 until the change is less than some tolerance.
    679         if (fabs(baseFuncVal - currFuncVal) <= min->tol) {
     681        if (fabs(baseFuncVal - currFuncVal) <= min->minTol) {
    680682            psFree(v);
    681683            psFree(pQP);
  • branches/eam_branches/ipp-20100621/psLib/src/math/psStats.c

    r27334 r28655  
    12111211
    12121212        // Fit a Gaussian to the data.
    1213         psMinimization *minimizer = psMinimizationAlloc(100, 0.01); // The minimizer information
     1213        psMinimization *minimizer = psMinimizationAlloc(100, 0.01, 1.0); // The minimizer information
    12141214        psVector *params = psVectorAlloc(2, PS_TYPE_F32); // Parameters for the Gaussian
    12151215        // Initial guess for the mean (index 0) and var (index 1).
Note: See TracChangeset for help on using the changeset viewer.