IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 26, 2010, 9:18:39 AM (16 years ago)
Author:
Serge CHASTEL
Message:

Merging trunk in branch

Location:
branches/sc_branches/trunkTest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/sc_branches/trunkTest

  • branches/sc_branches/trunkTest/psLib/src/math/psMinimizeLMM.c

    r26951 r29060  
    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);
Note: See TracChangeset for help on using the changeset viewer.