Changeset 1831 for trunk/psLib/src/dataManip/psMinimize.c
- Timestamp:
- Sep 17, 2004, 3:50:45 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/dataManip/psMinimize.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/dataManip/psMinimize.c
r1819 r1831 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1. 39$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09-1 6 19:30:24$11 * @version $Revision: 1.40 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-18 01:50:45 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 844 844 return (initialGuess); 845 845 } 846 846 847 /****************************************************************************** 847 848 This routine will take an procedure which calculates an arbitrary function 848 849 and it's derivative and minimize it. 849 850 850 GUS851 852 851 XXX: Do this: 853 852 After checking that all entries in the paramMask are 1 or 0, when … … 855 854 856 855 A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i]; 857 858 859 856 *****************************************************************************/ 860 857 bool psMinimizeLM(psMinimization *min, … … 982 979 983 980 oldValue = min->value; 984 newValue = func( newDeriv, NRparams, coords);981 newValue = func(deriv, NRparams, coords); 985 982 psTrace(".psLib.dataManip.psMinimizeLM", 4, 986 983 "old/new values are (%f, %f)\n", oldValue, newValue); … … 1029 1026 psTrace(".psLib.dataManip.psMinimizeLM", 4, 1030 1027 "---- psMinimizeLM() end (false) ----\n"); 1028 return(false); 1029 } 1030 1031 /****************************************************************************** 1032 This routine will take an procedure which calculates an arbitrary function 1033 and it's derivative and minimize the chi-squared match between that function 1034 at the specified coords and the specified value at those coords. 1035 1036 XXX: Do this: 1037 After checking that all entries in the paramMask are 1 or 0, when 1038 forming the A matrix from alpha, try this: 1039 1040 A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i]; 1041 *****************************************************************************/ 1042 bool psMinimizeLMChi2(psMinimization *min, 1043 psVector *params, 1044 const psVector *paramMask, 1045 psImage *covar, 1046 const psArray *coords, 1047 const psVector *value, 1048 psMinimizeLMChi2Func func) 1049 { 1050 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1051 "---- psMinimizeLMChi2() begin ----\n"); 1052 int numData = value->n; 1053 int numParams = params->n; 1054 int i; 1055 int j; 1056 int k; 1057 int l; 1058 int n; 1059 int p; 1060 psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64); 1061 psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64); 1062 1063 psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64); 1064 psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32); 1065 psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32); 1066 1067 psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32); 1068 psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64); 1069 psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64); 1070 1071 psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *)); 1072 for (i=0;i<numData;i++) { 1073 deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32); 1074 } 1075 1076 psVector *currValueVec = psVectorAlloc(value->n, PS_TYPE_F32); 1077 psVector *newValueVec = psVectorAlloc(value->n, PS_TYPE_F32); 1078 1079 float currChi2 = 0.0; 1080 float newChi2 = 0.0; 1081 float lamda = 0.00005; 1082 1083 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1084 "min->maxIter is %d\n", min->maxIter); 1085 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1086 "min->tol is %f\n", min->tol); 1087 1088 for (p=0;p<numParams;p++) { 1089 origParams->data.F32[p] = params->data.F32[p]; 1090 } 1091 1092 min->lastDelta = HUGE; 1093 min->lastDelta = 12345.0; 1094 min->iter = 0; 1095 1096 while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) { 1097 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1098 "------------------------------------------------------\n"); 1099 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1100 "Iteration %d. Delta is %f\n", min->iter, min->lastDelta); 1101 1102 // 1103 // Calculate the current values and chi-squared of the function. 1104 // 1105 currChi2 = 0.0; 1106 for (n=0;n<numData;n++) { 1107 currValueVec->data.F32[n] = func(deriv[n], 1108 params, 1109 (psVector *) coords->data[n]); 1110 currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]); 1111 } 1112 1113 for (p=0;p<numParams;p++) { 1114 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1115 "params->data.F32[%d] is %f.\n", p, params->data.F32[p]); 1116 } 1117 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1118 "Current chi-squared is (%f)\n", currChi2); 1119 1120 // 1121 // Mask elements of the derivative for each data point. 1122 // 1123 for (p=0;p<numParams;p++) { 1124 if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) { 1125 for (n=0;n<numData;n++) { 1126 (deriv[n])->data.F32[p] = 0.0; 1127 } 1128 } 1129 } 1130 1131 // 1132 // Calculate the BETA vector. 1133 // 1134 for (p=0;p<numParams;p++) { 1135 beta->data.F64[p] = 0.0; 1136 for (n=0;n<numData;n++) { 1137 (beta->data.F64[p])+= 1138 (value->data.F32[n] - currValueVec->data.F32[n]) * 1139 (deriv[n])->data.F32[p]; 1140 } 1141 // XXX: multiple by -1 here? 1142 (beta->data.F64[p])*= -1.0; 1143 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1144 "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]); 1145 } 1146 1147 // 1148 // Calculate the ALPHA matrix. 1149 // 1150 for (k=0;k<numParams;k++) { 1151 for (l=0;l<numParams;l++) { 1152 alpha->data.F32[k][l] = 0.0; 1153 for (n=0;n<numData;n++) { 1154 alpha->data.F32[k][l]+= (deriv[n])->data.F32[k] * 1155 (deriv[n])->data.F32[l]; 1156 } 1157 } 1158 } 1159 1160 // 1161 // Calculate the matrix A. 1162 // 1163 for (j=0;j<numParams;j++) { 1164 for (k=0;k<numParams;k++) { 1165 if (j == k) { 1166 A->data.F64[j][k] = 1167 (double) ((1.0 + lamda) * alpha->data.F32[j][k]); 1168 } else { 1169 A->data.F64[j][k] = (double) alpha->data.F32[j][k]; 1170 } 1171 } 1172 } 1173 for (j=0;j<numParams;j++) { 1174 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n"); 1175 for (k=0;k<numParams;k++) { 1176 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]); 1177 } 1178 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n"); 1179 } 1180 1181 // 1182 // Solve A * alpha = Beta 1183 // 1184 aOut = psMatrixLUD(aOut, perm, A); 1185 paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm); 1186 1187 // 1188 // Mask any masked parameters. 1189 // 1190 for (i=0;i<numParams;i++) { 1191 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1192 "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]); 1193 if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) { 1194 newParams->data.F32[i] = origParams->data.F32[i]; 1195 } else { 1196 newParams->data.F32[i] = params->data.F32[i] - 1197 (float) paramDeltasF64->data.F64[i]; 1198 } 1199 } 1200 1201 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1202 "Calling func() with new parameters:\n"); 1203 for (i=0;i<numParams;i++) { 1204 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, 1205 "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]); 1206 } 1207 1208 1209 // 1210 // Calculate new function values. 1211 // 1212 newChi2 = 0.0; 1213 for (n=0;n<numData;n++) { 1214 newValueVec->data.F32[n] = func(deriv[n], newParams, 1215 (psVector *) coords->data[n]); 1216 newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]); 1217 } 1218 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1219 "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2); 1220 1221 // 1222 // If the new chi-squared is lower, then keep it. 1223 // 1224 if (currChi2 > newChi2) { 1225 min->lastDelta = currChi2 - newChi2; 1226 min->value = newChi2; 1227 1228 // We already masked params. 1229 for (i=0;i<numParams;i++) { 1230 params->data.F32[i] = (float) newParams->data.F32[i]; 1231 } 1232 lamda*= 0.1; 1233 } else { 1234 lamda*= 10.0; 1235 } 1236 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1237 "lamda is %f\n", lamda); 1238 min->iter++; 1239 } 1240 psFree(beta); 1241 psFree(perm); 1242 psFree(paramDeltasF64); 1243 psFree(origParams); 1244 psFree(newParams); 1245 psFree(alpha); 1246 psFree(A); 1247 psFree(aOut); 1248 for (i=0;i<numData;i++) { 1249 psFree(deriv[i]); 1250 } 1251 psFree(deriv); 1252 psFree(currValueVec); 1253 psFree(newValueVec); 1254 1255 if ((min->iter < min->maxIter) || 1256 (min->lastDelta <= min->tol)) { 1257 return(true); 1258 } 1259 1260 psTrace(".psLib.dataManip.psMinimizeLMChi2", 4, 1261 "---- psMinimizeLMChi2() end (false) ----\n"); 1031 1262 return(false); 1032 1263 }
Note:
See TracChangeset
for help on using the changeset viewer.
