IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 26, 2004, 11:25:59 AM (22 years ago)
Author:
gusciora
Message:

...

File:
1 edited

Legend:

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

    r2106 r2197  
    99 *  @author GLF, MHPCC
    1010 *
    11  *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-10-14 01:44:48 $
     11 *  @version $Revision: 1.59 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-10-26 21:24:42 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    636636    psFree(currValueVec);
    637637    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/******************************************************************************
     650psMyMinimizeLMChi2():  This routine will take an procedure which calculates
     651an arbitrary function and it's derivative and minimize the chi-squared match
     652between that function at the specified coords and the specified value at
     653those coords.
     654 
     655XXX: 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 
     661XXX: This is very different from what is specified in the SDR.  Must
     662coordinate with IfA on new SDR.
     663 
     664XXX: Do vector/image recycles.
     665 
     666XXX: probably yErr will be part of the SDR.
     667 
     668XXX: 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 *****************************************************************************/
     673bool 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)
     681{
     682    PS_CHECK_NULL_PTR_RETURN_NULL(min);
     683    PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
     684    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
     685    PS_CHECK_NULL_PTR_RETURN_NULL(x);
     686    PS_CHECK_NULL_VECTOR_RETURN_NULL(y);
     687    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(y);
     688    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x, y);
     689    if (paramMask != NULL) {
     690        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, paramMask);
     691    }
     692    if (yErr != NULL) {
     693        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(y, yErr);
     694    }
     695
     696    psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
     697            "---- psMinimizeLMChi2() begin ----\n");
     698    int numData = y->n;
     699    int numParams = params->n;
     700    int i;
     701    int j;
     702    int k;
     703    int l;
     704    int n;
     705    int p;
     706    psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
     707    psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64);
     708
     709    psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64);
     710    psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32);
     711    psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32);
     712
     713    psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32);
     714    psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64);
     715    psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64);
     716
     717    //    psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *));
     718    //    for (i=0;i<numData;i++) {
     719    //        deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32);
     720    //    }
     721    psImage *deriv = psImageAlloc(numParams, numData, PS_TYPE_F32);
     722
     723    psVector *currValueVec;
     724    psVector *newValueVec;
     725
     726    float currChi2 = 0.0;
     727    float newChi2 = 0.0;
     728    float lamda = 0.00005;
     729
     730    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     731            "min->maxIter is %d\n", min->maxIter);
     732    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     733            "min->tol is %f\n", min->tol);
     734
     735    for (p=0;p<numParams;p++) {
     736        origParams->data.F32[p] = params->data.F32[p];
     737    }
     738
     739    min->lastDelta = HUGE;
     740    min->iter = 0;
     741
     742    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
     743        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
     744                "------------------------------------------------------\n");
     745        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
     746                "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
     747
     748        //
     749        // Calculate the current values and chi-squared of the function.
     750        //
     751        currChi2 = 0.0;
     752        currValueVec = func(deriv, params, x);
     753        for (n=0;n<numData;n++) {
     754            currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]);
     755        }
     756
     757        for (p=0;p<numParams;p++) {
     758            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     759                    "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
     760        }
     761        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     762                "Current chi-squared is (%f)\n", currChi2);
     763
     764        //
     765        // Mask elements of the derivative for each data point.
     766        //
     767        for (p=0;p<numParams;p++) {
     768            if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) {
     769                for (n=0;n<numData;n++) {
     770                    deriv->data.F32[n][p] = 0.0;
     771                }
     772            }
     773        }
     774
     775        //
     776        // Calculate the BETA vector.
     777        //
     778        for (p=0;p<numParams;p++) {
     779            beta->data.F64[p] = 0.0;
     780            for (n=0;n<numData;n++) {
     781                (beta->data.F64[p])+=
     782                    (y->data.F32[n] - currValueVec->data.F32[n]) *
     783                    deriv->data.F32[n][p];
     784            }
     785            // XXX: multiple by -1 here?
     786            (beta->data.F64[p])*= -1.0;
     787            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     788                    "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
     789        }
     790        psFree(currValueVec);
     791
     792        //
     793        // Calculate the ALPHA matrix.
     794        //
     795        for (k=0;k<numParams;k++) {
     796            for (l=0;l<numParams;l++) {
     797                alpha->data.F32[k][l] = 0.0;
     798                for (n=0;n<numData;n++) {
     799                    alpha->data.F32[k][l]+= deriv->data.F32[n][k] *
     800                                            deriv->data.F32[n][l];
     801                }
     802            }
     803        }
     804
     805        //
     806        // Calculate the matrix A.
     807        //
     808        for (j=0;j<numParams;j++) {
     809            for (k=0;k<numParams;k++) {
     810                if (j == k) {
     811                    A->data.F64[j][k] =
     812                        (double) ((1.0 + lamda) * alpha->data.F32[j][k]);
     813                } else {
     814                    A->data.F64[j][k] = (double) alpha->data.F32[j][k];
     815                }
     816            }
     817        }
     818        for (j=0;j<numParams;j++) {
     819            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
     820            for (k=0;k<numParams;k++) {
     821                psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]);
     822            }
     823            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
     824        }
     825
     826        //
     827        // Solve A * alpha = Beta
     828        //
     829        aOut = psMatrixLUD(aOut, perm, A);
     830        paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
     831
     832        //
     833        // Mask any masked parameters.
     834        //
     835        for (i=0;i<numParams;i++) {
     836            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     837                    "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]);
     838            if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) {
     839                newParams->data.F32[i] = origParams->data.F32[i];
     840            } else {
     841                newParams->data.F32[i] = params->data.F32[i] -
     842                                         (float) paramDeltasF64->data.F64[i];
     843            }
     844        }
     845
     846        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     847                "Calling func() with new parameters:\n");
     848        for (i=0;i<numParams;i++) {
     849            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
     850                    "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
     851        }
     852
     853
     854        //
     855        // Calculate new function values.
     856        //
     857        newChi2 = 0.0;
     858        newValueVec = func(deriv, newParams, x);
     859        for (n=0;n<numData;n++) {
     860            newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]);
     861        }
     862        psFree(newValueVec);
     863
     864        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
     865                "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2);
     866
     867        //
     868        // If the new chi-squared is lower, then keep it.
     869        //
     870        if (currChi2 > newChi2) {
     871            min->lastDelta = currChi2 - newChi2;
     872            min->value = newChi2;
     873
     874            // We already masked params.
     875            for (i=0;i<numParams;i++) {
     876                params->data.F32[i] = (float) newParams->data.F32[i];
     877            }
     878            lamda*= 0.1;
     879        } else {
     880            lamda*= 10.0;
     881        }
     882        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
     883                "lamda is %f\n", lamda);
     884        min->iter++;
     885    }
     886    psFree(beta);
     887    psFree(perm);
     888    psFree(paramDeltasF64);
     889    psFree(origParams);
     890    psFree(newParams);
     891    psFree(alpha);
     892    psFree(A);
     893    psFree(aOut);
     894    psFree(deriv);
    638895
    639896    if ((min->iter < min->maxIter) ||
Note: See TracChangeset for help on using the changeset viewer.