Changeset 2228 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Oct 28, 2004, 12:47:00 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (29 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r2221 r2228 9 9 * @author GLG, MHPCC 10 10 * 11 * @version $Revision: 1.7 2$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-10-2 7 23:31:43$11 * @version $Revision: 1.73 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-10-28 22:46:57 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 408 408 } 409 409 410 411 /****************************************************************************** 412 XXX: We assume unnormalized gaussians. 413 XXX: Currently, yErr is ignored. 414 *****************************************************************************/ 415 psVector *psMinimizeLMChi2Gauss1D(psImage *deriv, 416 const psVector *params, 417 const psArray *coords) 418 { 419 psTrace(".psLib.dataManip.psMinimize", 4, 420 "---- psMinimizeLMChi2Gauss1D() begin ----\n"); 421 422 PS_PTR_CHECK_NULL(coords, NULL); 423 PS_PTR_CHECK_NULL(params, NULL); 424 float x; 425 int i; 426 float mean = params->data.F32[0]; 427 float stdev = params->data.F32[1]; 428 psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32); 429 430 psTrace(".psLib.dataManip.psMinimize", 6, 431 "(mean, stdev) is (%f, %f)\n", mean, stdev); 432 433 if (deriv == NULL) { 434 deriv = psImageAlloc(params->n, coords->n, PS_TYPE_F32); 435 } 436 437 for (i=0;i<coords->n;i++) { 438 x = ((psVector *) (coords->data[i]))->data.F32[0]; 439 out->data.F32[i] = psGaussian(x, mean, stdev, false); 440 // psTrace(".psLib.dataManip.psMinimize", 6, 441 // "out->data.F32[%d]: (x, m, s) is (%f, %f, %f) is %f\n", i, x, mean, stdev, out->data.F32[i]); 442 } 443 444 for (i=0;i<coords->n;i++) { 445 x = ((psVector *) (coords->data[i]))->data.F32[0]; 446 float tmp = (x - mean) * psGaussian(x, mean, stdev, false); 447 deriv->data.F32[i][0] = tmp / (stdev * stdev); 448 449 tmp = (x - mean) * (x - mean) * 450 psGaussian(x, mean, stdev, 0); 451 deriv->data.F32[i][1] = tmp / (stdev * stdev * stdev); 452 } 453 454 psTrace(".psLib.dataManip.psMinimize", 4, 455 "---- psMinimizeLMChi2Gauss1D() end ----\n"); 456 return(out); 457 } 458 459 410 460 /****************************************************************************** 411 461 psMinimizeLMChi2(): This routine will take an procedure which calculates … … 429 479 XXX: This must work for both F32 and F64. F32 is currently implemented. 430 480 Note: since the LUD routines are only implemented in F64, then we 431 will have to convert all F32 input vectors to F64 regardless. So,481 > will have to convert all F32 input vectors to F64 regardless. So, 432 482 the F64 port might be. 433 483 *****************************************************************************/ … … 457 507 } 458 508 459 psTrace(".psLib.dataManip.psMinimize LMChi2", 4,509 psTrace(".psLib.dataManip.psMinimize", 4, 460 510 "---- psMinimizeLMChi2() begin ----\n"); 461 511 psS32 numData = y->n; … … 490 540 float newChi2 = 0.0; 491 541 float lamda = 0.00005; 492 493 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 542 lamda = 0.05; 543 544 psTrace(".psLib.dataManip.psMinimize", 6, 494 545 "min->maxIter is %d\n", min->maxIter); 495 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,546 psTrace(".psLib.dataManip.psMinimize", 6, 496 547 "min->tol is %f\n", min->tol); 497 548 … … 504 555 505 556 while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) { 506 psTrace(".psLib.dataManip.psMinimize LMChi2", 4,557 psTrace(".psLib.dataManip.psMinimize", 4, 507 558 "------------------------------------------------------\n"); 508 psTrace(".psLib.dataManip.psMinimize LMChi2", 4,559 psTrace(".psLib.dataManip.psMinimize", 4, 509 560 "Iteration %d. Delta is %f\n", min->iter, min->lastDelta); 510 561 … … 515 566 currValueVec = func(deriv, params, x); 516 567 for (n=0;n<numData;n++) { 517 currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]); 568 currChi2+= (currValueVec->data.F32[n] - y->data.F32[n]) * 569 (currValueVec->data.F32[n] - y->data.F32[n]); 570 psTrace(".psLib.dataManip.psMinimize", 6, 571 "data[%d], chi2 calculation+= (%f * %f)\n", n, 572 currValueVec->data.F32[n], y->data.F32[n]); 518 573 } 519 574 520 575 for (p=0;p<numParams;p++) { 521 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,576 psTrace(".psLib.dataManip.psMinimize", 6, 522 577 "params->data.F32[%d] is %f.\n", p, params->data.F32[p]); 523 578 } 524 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,579 psTrace(".psLib.dataManip.psMinimize", 6, 525 580 "Current chi-squared is (%f)\n", currChi2); 526 581 … … 548 603 // XXX: multiple by -1 here? 549 604 (beta->data.F64[p])*= -1.0; 550 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,605 psTrace(".psLib.dataManip.psMinimize", 6, 551 606 "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]); 552 607 } … … 580 635 } 581 636 for (j=0;j<numParams;j++) { 582 psTrace(".psLib.dataManip.psMinimize LMChi2", 6, "Matrix A[][]:\n");637 psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n"); 583 638 for (k=0;k<numParams;k++) { 584 psTrace(".psLib.dataManip.psMinimize LMChi2", 6, "%f ", A->data.F64[j][k]);585 } 586 psTrace(".psLib.dataManip.psMinimize LMChi2", 6, "Matrix A[][]:\n");639 psTrace(".psLib.dataManip.psMinimize", 6, "%f ", A->data.F64[j][k]); 640 } 641 psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n"); 587 642 } 588 643 … … 597 652 // 598 653 for (i=0;i<numParams;i++) { 599 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,654 psTrace(".psLib.dataManip.psMinimize", 6, 600 655 "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]); 601 656 if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) { … … 607 662 } 608 663 609 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,664 psTrace(".psLib.dataManip.psMinimize", 6, 610 665 "Calling func() with new parameters:\n"); 611 666 for (i=0;i<numParams;i++) { 612 psTrace(".psLib.dataManip.psMinimize LMChi2", 6,667 psTrace(".psLib.dataManip.psMinimize", 6, 613 668 "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]); 614 669 } … … 621 676 newValueVec = func(deriv, newParams, x); 622 677 for (n=0;n<numData;n++) { 623 newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]); 678 newChi2+= (newValueVec->data.F32[n] - y->data.F32[n]) * 679 (newValueVec->data.F32[n] - y->data.F32[n]); 680 624 681 } 625 682 psFree(newValueVec); 626 683 627 psTrace(".psLib.dataManip.psMinimize LMChi2", 4,684 psTrace(".psLib.dataManip.psMinimize", 4, 628 685 "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2); 629 686 … … 640 697 } 641 698 lamda*= 0.1; 699 psTrace(".psLib.dataManip.psMinimize", 4, "*** Reducing lamda by factor of 10\n"); 642 700 } else { 643 701 lamda*= 10.0; 644 } 645 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 702 psTrace(".psLib.dataManip.psMinimize", 4, "*** Increasing lamda by factor of 10\n"); 703 } 704 psTrace(".psLib.dataManip.psMinimize", 4, 646 705 "lamda is %f\n", lamda); 647 706 min->iter++; … … 662 721 } 663 722 664 psTrace(".psLib.dataManip.psMinimize LMChi2", 4,723 psTrace(".psLib.dataManip.psMinimize", 4, 665 724 "---- psMinimizeLMChi2() end (false) ----\n"); 666 725 return(false); … … 942 1001 } 943 1002 1003 #define PS_VECTOR_ADD_MULTIPLE(BASE, BASEMASK, LINE, OUT, MUL) \ 1004 for (int i=0;i<BASE->n;i++) { \ 1005 if (BASEMASK->data.U8[i] == 0) { \ 1006 OUT->data.F32[i] = BASE->data.F32[i] + (MUL * LINE->data.F32[i]); \ 1007 } else { \ 1008 OUT->data.F32[i] = BASE->data.F32[i]; \ 1009 } \ 1010 } \ 1011 1012 944 1013 /****************************************************************************** 945 1014 p_psDetermineBracket(): This routine takes as input an arbitrary function, … … 947 1016 function produces as output a bracket [a, b, c] such that 948 1017 949 f(param + b * line) is less than f(param + a * line) and 950 f(param + c * line). 951 952 Algorithm: XXX completely ad hoc: start with the user-supplied starting 1018 f(param + b * line) is less than f(param + a * line) and 1019 f(param + c * line). 1020 1021 Algorithm: 1022 XXX completely ad hoc: 1023 start with the user-supplied starting 953 1024 parameter and call that b. Calculate a/c as a fractional amount 954 1025 smaller/larger than b. Repeat this process until a local minimum is found. 955 1026 956 XXX: new algorithm: start at x=0, expand in one direction until the function 1027 XXX: 1028 new algorithm: 1029 start at x=0, expand in one direction until the function 957 1030 decreases. Then you have two points in the bracket. Keep going until it 958 1031 increases, or x is too large. If thst does not work, expand in the other 959 1032 direction. 960 1033 961 XXX: This is F32 only 962 *****************************************************************************/ 1034 XXX: 1035 This is F32 only. 1036 1037 XXX: 1038 output bracket vector should be an input as well. 1039 *****************************************************************************/ 963 1040 psVector *p_psDetermineBracket(psVector *params, 964 1041 psVector *line, … … 966 1043 const psArray *coords, 967 1044 psMinimizePowellFunc func) 1045 { 1046 float a = 0.0; 1047 float b = 0.0; 1048 float c = 0.0; 1049 float fa = 0.0; 1050 float fb = 0.0; 1051 float fc = 0.0; 1052 psS32 iter = 100; 1053 float aDir = 0.0; 1054 float cDir = 0.0; 1055 float new_aDir = 0.0; 1056 float new_cDir = 0.0; 1057 psVector *bracket = psVectorAlloc(3, PS_TYPE_F32); 1058 float stepSize = PS_DETERMINE_BRACKET_STEP_SIZE; 1059 psVector *tmp = NULL; 1060 psS32 i = 0; 1061 psS32 null = 0; 1062 1063 psTrace(".psLib.dataManip.p_psDetermineBracket", 4, 1064 "---- p_psDetermineBracket() begin ----\n"); 1065 1066 for (i=0;i<params->n;i++) { 1067 if (paramMask->data.U8[i] == 0) { 1068 if (line->data.F32[i] >= FLT_EPSILON) { 1069 null = 1; 1070 } 1071 } 1072 } 1073 1074 if (null == 0) { 1075 psTrace(".psLib.dataManip.p_psDetermineBracket", 2, 1076 "p_psDetermineBracket() called with zero line vector.\n"); 1077 psTrace(".psLib.dataManip.p_psDetermineBracket", 4, 1078 "---- p_psDetermineBracket() end (NULL) ----\n"); 1079 psFree(bracket); 1080 return(NULL); 1081 } 1082 1083 tmp = psVectorAlloc(params->n, PS_TYPE_F32); 1084 1085 b = 0; 1086 a = -stepSize; 1087 c = stepSize; 1088 1089 PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, a); 1090 fa = func(tmp, coords); 1091 1092 PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, b); 1093 fb = func(tmp, coords); 1094 1095 PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c); 1096 fc = func(tmp, coords); 1097 1098 if (fa < fb) { 1099 aDir = -1; 1100 } else { 1101 aDir = 1; 1102 } 1103 1104 if (fc < fb) { 1105 cDir = -1; 1106 } else { 1107 cDir = 1; 1108 } 1109 1110 psTrace(".psLib.dataManip.p_psDetermineBracket", 6, 1111 "(a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", a, b, c, fa, fb, fc); 1112 1113 while (iter > 0) { 1114 psTrace(".psLib.dataManip.p_psDetermineBracket", 6, 1115 "psDetermineBracket(): iteration %d\n", iter); 1116 if ((fb < fa) && (fb < fc)) { 1117 bracket->data.F32[0] = a; 1118 bracket->data.F32[1] = b; 1119 bracket->data.F32[2] = c; 1120 psFree(tmp); 1121 psTrace(".psLib.dataManip.p_psDetermineBracket", 6, 1122 "---- p_psDetermineBracket() end ----\n"); 1123 return(bracket); 1124 } 1125 stepSize*= (1.0 + stepSize); 1126 a =- stepSize; 1127 c =+ stepSize; 1128 1129 for (i=0;i<params->n;i++) { 1130 if (paramMask->data.U8[i] == 0) { 1131 tmp->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]); 1132 } else { 1133 tmp->data.F32[i] = params->data.F32[i]; 1134 } 1135 } 1136 fa = func(tmp, coords); 1137 1138 for (i=0;i<params->n;i++) { 1139 if (paramMask->data.U8[i] == 0) { 1140 tmp->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]); 1141 } else { 1142 tmp->data.F32[i] = params->data.F32[i]; 1143 } 1144 } 1145 fc = func(tmp, coords); 1146 1147 psTrace(".psLib.dataManip.p_psDetermineBracket", 6, 1148 "Iter(%d): (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", iter, a, b, c, fa, fb, fc); 1149 1150 if (fa < fb) { 1151 new_aDir = -1; 1152 } else { 1153 new_aDir = 1; 1154 } 1155 1156 if (fc < fb) { 1157 new_cDir = -1; 1158 } else { 1159 new_cDir = 1; 1160 } 1161 if ((new_aDir == 1) && (aDir == -1)) { 1162 bracket->data.F32[0] = a; 1163 bracket->data.F32[1] = b; 1164 bracket->data.F32[2] = c; 1165 psFree(tmp); 1166 psTrace(".psLib.dataManip.p_psDetermineBracket", 4, 1167 "---- p_psDetermineBracket() end ----\n"); 1168 return(bracket); 1169 } 1170 1171 if ((new_cDir == 1) && (cDir == -1)) { 1172 bracket->data.F32[0] = a; 1173 bracket->data.F32[1] = b; 1174 bracket->data.F32[2] = c; 1175 psFree(tmp); 1176 psTrace(".psLib.dataManip.p_psDetermineBracket", 4, 1177 "---- p_psDetermineBracket() end ----\n"); 1178 return(bracket); 1179 } 1180 aDir = new_aDir; 1181 cDir = new_cDir; 1182 iter--; 1183 } 1184 psFree(tmp); 1185 psFree(bracket); 1186 psTrace(".psLib.dataManip.p_psDetermineBracket", 4, 1187 "---- p_psDetermineBracket() end (NULL) ----\n"); 1188 return(NULL); 1189 } 1190 1191 psVector *p_psDetermineBracket2(psVector *params, 1192 psVector *line, 1193 const psVector *paramMask, 1194 const psArray *coords, 1195 psMinimizePowellFunc func) 968 1196 { 969 1197 float a = 0.0; … … 1365 1593 float fqp = 0.0; 1366 1594 float diff = 0.0; 1595 int iterationNumber = 0; 1367 1596 1368 1597 psTrace(".psLib.dataManip.psMinimizePowell", 4, … … 1407 1636 } 1408 1637 1409 min->iter = 0; 1410 while (min->iter < min->maxIter) { 1411 min->iter++; 1638 while (iterationNumber < min->maxIter) { 1639 iterationNumber++; 1412 1640 psTrace(".psLib.dataManip.psMinimizePowell", 6, 1413 "psMinimizePowell() iteration %d\n", min->iter);1641 "psMinimizePowell() iteration %d\n", iterationNumber); 1414 1642 1415 1643 // 3: For each dimension in params, move Q only in the vector v[i] to … … 1418 1646 baseFuncVal = func(Q, coords); 1419 1647 currFuncVal = baseFuncVal; 1648 psTrace(".psLib.dataManip.psMinimizePowell", 6, 1649 "Current function value is %f\n", currFuncVal); 1650 1420 1651 diff = 0.0; 1421 1652 biggestDiff = 0; … … 1423 1654 for (i=0;i<numDims;i++) { 1424 1655 if (myParamMask->data.U8[i] == 0) { 1425 dummyMin.maxIter = 100;1656 dummyMin.maxIter = 20; 1426 1657 dummyMin.tol = 0.01; 1427 1658 mul = p_psLineMin(&dummyMin, Q, v[i], myParamMask, coords, func); … … 1433 1664 } 1434 1665 } 1435 1666 psTrace(".psLib.dataManip.psMinimizePowell", 6, 1667 "New function value is %f\n", currFuncVal); 1436 1668 // 4: Set the vector u = Q - P 1437 1669 for (i=0;i<numDims;i++) { … … 1450 1682 1451 1683 // 5: Move Q only in the direction u, and minimize the function. 1452 psTrace(".psLib.dataManip.psMinimizePowell", 6, "HERE 01\n");1453 1684 for (i=0;i<numDims;i++) { 1454 1685 psTrace(".psLib.dataManip.psMinimizePowell", 6, … … 1470 1701 psFree(myParamMask); 1471 1702 } 1703 min->iter = iterationNumber; 1472 1704 psTrace(".psLib.dataManip.psMinimizePowell", 4, 1473 1705 "---- psMinimizePowell() end (true) ----\n"); … … 1513 1745 psFree(pQP); 1514 1746 psFree(Q); 1747 if (paramMask == NULL) { 1748 psFree(myParamMask); 1749 } 1750 min->iter = iterationNumber; 1515 1751 psTrace(".psLib.dataManip.psMinimizePowell", 4, 1516 1752 "---- psMinimizePowell() end (true) ----\n"); 1517 if (paramMask == NULL) {1518 psFree(myParamMask);1519 }1520 1753 return(true); 1521 1754 } … … 1532 1765 psFree(pQP); 1533 1766 psFree(Q); 1767 min->iter = iterationNumber; 1534 1768 psTrace(".psLib.dataManip.psMinimizePowell", 4, 1535 1769 "---- psMinimizePowell() end (false) ----\n"); … … 1549 1783 const psArray *coords) 1550 1784 { 1785 psTrace(".psLib.dataManip.myPowellChi2Func", 4, 1786 "---- myPowellChi2Func() begin ----\n"); 1787 PS_VECTOR_CHECK_NULL(params, NAN); 1788 PS_VECTOR_CHECK_EMPTY(params, NAN); 1789 PS_VECTOR_CHECK_NULL(myValue, NAN); 1790 PS_VECTOR_CHECK_EMPTY(myValue, NAN); 1791 PS_PTR_CHECK_NULL(coords, NAN); 1792 1551 1793 float chi2 = 0.0; 1552 1794 float d; … … 1555 1797 1556 1798 tmp = Chi2PowellFunc(params, coords); 1557 for (i=0;i<coords->n;i++) { 1558 d = (tmp->data.F32[i] - myValue->data.F32[i]) / myError->data.F32[i]; 1559 chi2+= d * d; 1799 if (myError == NULL) { 1800 for (i=0;i<coords->n;i++) { 1801 d = (tmp->data.F32[i] - myValue->data.F32[i]); 1802 chi2+= d * d; 1803 } 1804 } else { 1805 for (i=0;i<coords->n;i++) { 1806 d = (tmp->data.F32[i] - myValue->data.F32[i]) / myError->data.F32[i]; 1807 chi2+= d * d; 1808 } 1560 1809 } 1561 1810 psFree(tmp); 1811 psTrace(".psLib.dataManip.myPowellChi2Func", 4, 1812 "---- myPowellChi2Func() end (%f) ----\n", chi2); 1562 1813 return(chi2); 1563 1814 } … … 1584 1835 myValue = (psVector *) value; 1585 1836 myError = (psVector *) error; 1837 1586 1838 Chi2PowellFunc = func; 1587 1839
Note:
See TracChangeset
for help on using the changeset viewer.
