Changeset 2202 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Oct 26, 2004, 1:14:04 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r2197 r2202 9 9 * @author GLF, MHPCC 10 10 * 11 * @version $Revision: 1. 59$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-10-26 2 1:24:42$11 * @version $Revision: 1.60 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-10-26 23:14:04 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 393 393 394 394 /****************************************************************************** 395 psMinimizeLMChi2(): This routine will take an procedure which calculates an396 a rbitrary function and it's derivative and minimize the chi-squared match395 psMinimizeLMChi2(): This routine will take an procedure which calculates 396 an arbitrary function and it's derivative and minimize the chi-squared match 397 397 between that function at the specified coords and the specified value at 398 398 those coords. … … 417 417 *****************************************************************************/ 418 418 bool psMinimizeLMChi2(psMinimization *min, 419 psImage *covar, 419 420 psVector *params, 420 421 const psVector *paramMask, 421 psImage *covar,422 const ps Array *coords,423 const psVector * value,422 const psArray *x, 423 const psVector *y, 424 const psVector *yErr, 424 425 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 = Beta567 //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 calculates651 an arbitrary function and it's derivative and minimize the chi-squared match652 between that function at the specified coords and the specified value at653 those coords.654 655 XXX: Do this:656 After checking that all entries in the paramMask are 1 or 0, when657 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. Must662 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 we670 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)681 426 { 682 427 PS_CHECK_NULL_PTR_RETURN_NULL(min);
Note:
See TracChangeset
for help on using the changeset viewer.
