IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 9, 2013, 3:27:54 PM (13 years ago)
Author:
eugene
Message:

choice of convergence method via user selections

File:
1 edited

Legend:

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

    r35629 r35637  
    680680    }
    681681
    682     psImage *alpha   = psImageAlloc(Alpha->numCols, Alpha->numRows, PS_TYPE_F32);
    683     psVector *beta   = psVectorAlloc(Beta->n, PS_TYPE_F32);
     682    int nFitParams = Beta->n;
     683    psImage *alpha   = psImageAlloc(nFitParams, nFitParams, PS_TYPE_F32);
     684    psVector *beta   = psVectorAlloc(nFitParams, PS_TYPE_F32);
    684685    psVector *Params = psVectorAlloc(params->n, PS_TYPE_F32);
    685686
     
    687688    psF32 Chisq = 0.0;
    688689    psF32 lambda = 0.001;
     690    psF32 dLinear = 0.0;
    689691    psF32 nu = 2.0;
    690     psF32 dLinear = 0.0;
    691692
    692693    // the user provides the error or NULL.  we need to convert
     
    700701
    701702    // number of degrees of freedom for this fit
    702     int nDOF = dy->n - params->n;
     703    int nDOF = dy->n - nFitParams;
    703704
    704705    // calculate initial alpha and beta, set chisq (min->value)
     
    722723    }
    723724
    724     // iterate until: (a) nIter = min->iter or (b) (chisq / ndof) < maxChisq and deltaChisq < minTol (but don't stop unless Chisq is finite)
    725725    bool done = (min->iter >= min->maxIter);
    726726    while (!done) {
    727727        psTrace("psLib.math", 5, "Iteration number %d.  (max iterations is %d).\n", min->iter, min->maxIter);
    728         psTrace("psLib.math", 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol);
     728
     729        if (min->chisqConvergence) {
     730          psTrace("psLib.math", 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol);
     731        } else {
     732          psTrace("psLib.math", 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->rParSigma, min->minTol*nFitParams, min->maxTol*nFitParams);
     733        }
    729734
    730735        // set a new guess for Alpha, Beta, Params
     
    732737            min->iter ++;
    733738            if (min->iter >=  min->maxIter) break;
    734             // lambda *= 10.0;
    735             lambda *= 2.0;
     739            lambda *= 10.0;
     740            // ALT? lambda *= 2.0;
    736741            continue;
    737742        }
     
    754759        // Beta is the actual parameter change for this pass
    755760
    756         // note that Alpha & Beta only represent unmasked parameters
     761        // note that Alpha & Beta only represent unmasked parameters, while params and Params have all
    757762
    758763        // dParSigma = Alpha[i][i] : error (squared) on parameter i
    759         // dParDelta = Beta[i]^2   : change (squared) in parameter i
     764        // dParDelta = Params->data.F32[i] - params->data.F32[i]     : change on parameter i
    760765        float rParSigma = 0.0;
    761         // for (int j = 0; j < Beta->n; j++) {
    762         //     rParSigma += PS_SQR(Beta->data.F32[j]) / Alpha->data.F32[j][j];
    763         // }
    764766        for (int j = 0, J = 0; j < Params->n; j++) {
    765767            if (paramMask && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[j])) {
    766768                continue;
    767769            }
    768             // fprintf (stderr, "del: %f  - %f  vs %f  : %f\n", Params->data.F32[j], params->data.F32[j], sqrt(Alpha->data.F32[J][J]), PS_SQR(Params->data.F32[j] - params->data.F32[j]) / Alpha->data.F32[J][J]);
    769770            rParSigma += PS_SQR(Params->data.F32[j] - params->data.F32[j]) / Alpha->data.F32[J][J];
    770771            J++;
     
    779780            min->iter ++;
    780781            if (min->iter >= min->maxIter) break;
    781             // lambda *= 10.0;
    782             lambda *= 2.0;
     782            lambda *= 10.0;
     783            // ALT lambda *= 2.0;
    783784            continue;
    784785        }
     
    807808        // XXX the old version of lambda changes:
    808809        // XXX : Madsen gives suggestion for better use of rho
    809 # if (0)
    810         if (rho >= -1e-6) {
    811             min->value = Chisq;
    812             alpha  = psImageCopy(alpha, Alpha, PS_TYPE_F32);
    813             beta   = psVectorCopy(beta, Beta, PS_TYPE_F32);
    814             params = psVectorCopy(params, Params, PS_TYPE_F32);
    815             lambda *= 0.25;
    816         } else {
    817             lambda *= 10.0;
    818         }
    819 # endif
    820 
    821810        // rho is positive if the new chisq is smaller
    822811        if (rho >= -1e-6) {
     
    826815            params = psVectorCopy(params, Params, PS_TYPE_F32);
    827816        }
    828 
    829 # if (0)
    830         // adjust the gain ratio (lambda) based on rho
    831         if (rho < 0.25) {
    832             lambda *= 2.0;
    833         }
    834         if (rho > 0.75) {
    835             lambda *= 0.333;
    836         }
    837 # else
    838         if (rho > 0.0) {
    839           lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0)));
    840           nu = 2.0;
    841         } else {
    842           lambda *= nu;
    843           nu *= 2.0;
     817        switch (min->gainFactorMode) {
     818          case 0:
     819            if (rho >= -1e-6) {
     820              lambda *= 0.25;
     821            } else {
     822              lambda *= 10.0;
     823            }
     824            break;
     825
     826          case 1:
     827            // adjust the gain ratio (lambda) based on rho
     828            if (rho < 0.25) {
     829              lambda *= 2.0;
     830            }
     831            if (rho > 0.75) {
     832              lambda *= 0.333;
     833            }
     834            break;
     835
     836          case 2:
     837            if (rho > 0.0) {
     838              lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0)));
     839              nu = 2.0;
     840            } else {
     841              lambda *= nu;
     842              nu *= 2.0;
     843            }
     844            break;
    844845        }
    845 # endif
    846846        min->iter++;
    847847
     
    850850        done = (min->iter >= min->maxIter);
    851851       
     852        // 2) require deltaChi > 1e-6 (ie, chisq is decreasing, but accept an insignificant change)
     853        if (min->lastDelta < -1e-6) {
     854            continue;
     855        }
     856
     857        // save this value in case we stop iterating
     858        min->rParSigma = rParSigma;
     859
    852860        // 2) require chisqDOF < maxChisqDOF (if maxChisqDOF is not NAN)
     861        // keep iterating regardless of rParSigma in this case
    853862        float chisqDOF = Chisq / nDOF;
    854863        if (isfinite(min->maxChisqDOF) && (chisqDOF > min->maxChisqDOF)) {
     
    856865        }
    857866
    858         // 3) require deltaChi > 1e-6 (ie, chisq is decreasing, but accept an insignificant change)
    859         if (min->lastDelta < -1e-6) {
    860             continue;
     867        // delta-chisq or rParSigma ?
     868        if (min->chisqConvergence) {
     869          done |= (min->lastDelta < min->minTol);
     870        } else {
     871          done |= (rParSigma < min->minTol*nFitParams);
    861872        }
    862 
    863         // 4) require rParDelta < \eta * rParSigma
    864         done |= (rParSigma < 0.01);
    865     }
    866     psTrace("psLib.math", 5, "chisq: %f, last delta: %f, Niter: %d\n", min->value, min->lastDelta, min->iter);
     873    }
     874    psTrace("psLib.math", 5, "chisq: %f, last delta: %f, rParSigma: %f, Niter: %d\n", min->value, min->lastDelta, min->rParSigma, min->iter);
    867875
    868876    // construct & return the covariance matrix (if requested)
     
    898906
    899907    // if the last improvement was at least as good as maxTol, accept the fit:
    900     // XXX : maybe re-work this to use rParSigma & maxTol
    901     if (min->lastDelta <= min->maxTol) {
     908    if (min->chisqConvergence) {
     909      if (min->lastDelta <= min->maxTol) {
    902910        psTrace("psLib.math", 6, "---- end (true) ----\n");
    903911        return(true);
     912      }
     913    } else {
     914      if (min->rParSigma <= min->maxTol*nFitParams) {
     915        psTrace("psLib.math", 6, "---- end (true) ----\n");
     916        return(true);
     917      }
    904918    }
    905919    psTrace("psLib.math", 6, "---- end (false) ----\n");
     
    952966    min->iter = 0;
    953967    min->lastDelta = NAN;
     968    min->rParSigma = NAN;
    954969    min->maxChisqDOF = NAN;
    955970
     971    // we default to the old algorithm for convergence
     972    min->chisqConvergence = true;
     973    min->gainFactorMode = 0;
     974   
    956975    return(min);
    957976}
Note: See TracChangeset for help on using the changeset viewer.