61 SET_STARTFROMPREVIOUS,
70char *option[N_OPTIONS] = {
88 "Usage: sddsgenericfit [OPTIONS] [<inputfile>] [<outputfile>]\n"
90 " -pipe=[input][,output]\n"
91 " -equation=<rpnString>[,algebraic]\n"
92 " -expression=<string>[,<columnName>] [-expression=...]\n"
94 " -tolerance=<value>\n"
95 " -simplex=[restarts=<nRestarts>][,cycles=<nCycles>][,evaluations=<nEvals>][,no1DScans]\n"
96 " -variable=name=<name>,lowerLimit=<value|parameter-name>,upperLimit=<value|parameter-name>,\n"
97 " stepsize=<value|parameter-name>,startingValue=<value|parametername>[,units=<string>][,heat=<value|parameter-name>]\n"
98 " -verbosity=<integer>\n"
99 " -startFromPrevious\n"
100 " -majorOrder=row|column\n"
101 " -copy=<list of column names>\n"
102 " -ycolumn=ycolumn_name[,ySigma=<sy-name>]\n"
103 " -logFile=<filename>[,<flushInterval(500)>]\n"
105 " Uses the Simplex method to find a fit to <y-name> as a function of <x-name> by varying the given\n"
106 " variables, which are assumed to appear in the <rpnString>.\n"
107 "\nDetailed Options:\n"
109 " Specify the name of the dependent data column and optionally <sy-name> to weight the fit.\n"
110 " This option replaces the old -columns option.\n"
112 " Provide a list of column names to copy from the input file to the output file.\n"
114 " If provided, the intermediate fitting results will be written to the specified log file.\n"
116 " Specify an RPN expression for the equation used in fitting. This equation can use the names\n"
117 " of any of the columns or parameters in the file, just as in sddsprocess. It is expected\n"
118 " to return a value that will be compared to the data in column <y-name>.\n"
120 " Specify an RPN expression to evaluate before the main equation is evaluated. Can be used\n"
121 " to prepare quantities on the stack or in variables when the equation is complicated.\n"
122 " If the <columnName> is given, values of the expression are stored in the output file\n"
123 " under the given name.\n"
125 " Specify the value of the (weighted) RMS residual that is acceptably small to consider the\n"
128 " Specify the minimum change in the (weighted) RMS residual that is considered significant\n"
129 " enough to justify continuing optimization.\n"
131 " Configure simplex optimization parameters such as restarts, cycles, evaluations, and disabling 1D scans.\n"
132 " Defaults are 10 restarts, 10 cycles, and 5000 evaluations.\n"
134 " Define a fitting variable with its name, lower limit, upper limit, step size, starting value,\n"
135 " units, and an optional heat parameter. The variable name must not match any existing column\n"
136 " or parameter in the input file.\n"
138 " Set the verbosity level of output during optimization. Higher values result in more detailed output.\n"
139 " -startFromPrevious\n"
140 " Use the final values from the previous fit as starting values for the next fit.\n"
142 " Specify the output file's data order as row-major or column-major.\n"
143 "\nProgram Information:\n"
144 " Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
146void report(
double res,
double *a,
long pass,
long n_eval,
long n_dimen);
147void setupOutputFile(
SDDS_DATASET *OutputTable,
long *fitIndex,
long *residualIndex,
char *output,
148 SDDS_DATASET *InputTable,
char *xName,
char *yName,
char *syName,
char **variableName,
149 char **variableUnits,
long variables,
char **colMatch, int32_t colMatches,
150 char **expression,
char **expressionColumn,
long nExpressions,
151 SDDS_DATASET *logData,
char *logFile,
short columnMajorOrder);
153double fitFunction(
double *a,
long *invalid);
156static double *xData = NULL, *yData = NULL, *syData = NULL, *yFit = NULL, *yResidual = NULL;
157static int64_t nData = 0;
158static char *equation;
159static long *variableMem, nVariables, verbosity;
160static char **expression = NULL;
161static char **expressionColumn = NULL;
162static long nExpressions = 0;
163static double **expressionValue = NULL;
164static char **variableName = NULL;
165static int64_t step = 0;
166static char *logFile = NULL;
168static int32_t maxLogRows = 500;
170#define VARNAME_GIVEN 0x0001U
171#define LOWER_GIVEN 0x0002U
172#define UPPER_GIVEN 0x0004U
173#define STEP_GIVEN 0x0008U
174#define START_GIVEN 0x0010U
175#define VARUNITS_GIVEN 0x0020U
177static short abortRequested = 0;
179void optimizationInterruptHandler(
int signal) {
182 fprintf(stderr,
"Aborting minimization\n");
185int main(
int argc,
char **argv) {
190 char *input, *output, *xName, *yName, *syName, **colMatch;
191 long fitIndex, residualIndex, retval;
193 double rmsResidual, chiSqr, sigLevel;
194 unsigned long pipeFlags, dummyFlags, majorOrderFlag;
195 int32_t nEvalMax = 5000, nPassMax = 10, nRestartMax = 10;
196 long nEval, iRestart;
197 double tolerance, target;
198 char **variableUnits;
199 double *lowerLimit, *upperLimit, *stepSize, *startingValue, *paramValue, *paramDelta = NULL, *paramDelta0 = NULL;
200 char **startingPar = NULL, **lowerLimitPar = NULL, **upperLimitPar = NULL, **heatPar = NULL, **stepPar = NULL;
201 double *heat, *bestParamValue, bestResult = 0;
202 long iVariable, startFromPrevious = 0;
203 double result, lastResult = 0;
204 char pfix[IFPF_BUF_SIZE];
205 unsigned long simplexFlags = 0;
207 short columnMajorOrder = -1;
209 signal(SIGINT, optimizationInterruptHandler);
212 argc =
scanargs(&s_arg, argc, argv);
216 fprintf(stderr,
"%s", USAGE);
220 input = output = equation = NULL;
221 variableName = variableUnits = NULL;
222 lowerLimit = upperLimit = stepSize = startingValue = heat = bestParamValue = NULL;
225 verbosity = startFromPrevious = 0;
226 xName = yName = syName = NULL;
227 tolerance = target = 1e-14;
229 for (i_arg = 1; i_arg < argc; i_arg++) {
230 if (s_arg[i_arg].arg_type == OPTION) {
231 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
232 case SET_MAJOR_ORDER:
234 s_arg[i_arg].n_items--;
235 if (s_arg[i_arg].n_items > 0 && (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
"row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
"column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
236 SDDS_Bomb(
"Invalid -majorOrder syntax/values");
237 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
238 columnMajorOrder = 1;
239 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
240 columnMajorOrder = 0;
243 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%lf", &tolerance) != 1 || tolerance <= 0)
244 SDDS_Bomb(
"Incorrect -tolerance syntax");
247 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%lf", &target) != 1 || target <= 0)
251 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%ld", &verbosity) != 1)
252 SDDS_Bomb(
"Incorrect -verbosity syntax");
255 if (s_arg[i_arg].n_items != 3 && s_arg[i_arg].n_items != 4)
257 xName = s_arg[i_arg].list[1];
258 yName = s_arg[i_arg].list[2];
259 s_arg[i_arg].n_items -= 3;
260 if (!
scanItemList(&dummyFlags, s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0,
"ysigma",
SDDS_STRING, &syName, 1, 0, NULL))
264 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
266 yName = s_arg[i_arg].list[1];
267 s_arg[i_arg].n_items -= 2;
268 if (!
scanItemList(&dummyFlags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
"ysigma",
SDDS_STRING, &syName, 1, 0, NULL))
271 case SET_COPYCOLUMNS:
272 if (s_arg[i_arg].n_items < 2)
273 SDDS_Bomb(
"Invalid -copycolumns syntax provided.");
274 colMatch =
tmalloc(
sizeof(*colMatch) * (colMatches = s_arg[i_arg].n_items - 1));
275 for (i = 0; i < colMatches; i++)
276 colMatch[i] = s_arg[i_arg].list[i + 1];
279 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
283 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
285 logFile = s_arg[i_arg].list[1];
286 if (s_arg[i_arg].n_items == 3 && (sscanf(s_arg[i_arg].list[2],
"%" SCNd32, &maxLogRows) != 1 || maxLogRows <= 0))
290 if (!(variableName =
SDDS_Realloc(variableName,
sizeof(*variableName) * (nVariables + 1))) ||
291 !(lowerLimit =
SDDS_Realloc(lowerLimit,
sizeof(*lowerLimit) * (nVariables + 1))) ||
292 !(upperLimit =
SDDS_Realloc(upperLimit,
sizeof(*upperLimit) * (nVariables + 1))) ||
293 !(stepSize =
SDDS_Realloc(stepSize,
sizeof(*stepSize) * (nVariables + 1))) ||
294 !(heat =
SDDS_Realloc(heat,
sizeof(*heat) * (nVariables + 1))) ||
295 !(bestParamValue =
SDDS_Realloc(bestParamValue,
sizeof(*bestParamValue) * (nVariables + 1))) ||
296 !(startingValue =
SDDS_Realloc(startingValue,
sizeof(*startingValue) * (nVariables + 1))) ||
297 !(startingPar =
SDDS_Realloc(startingPar,
sizeof(*startingPar) * (nVariables + 1))) ||
298 !(lowerLimitPar =
SDDS_Realloc(lowerLimitPar,
sizeof(*lowerLimitPar) * (nVariables + 1))) ||
299 !(upperLimitPar =
SDDS_Realloc(upperLimitPar,
sizeof(*upperLimitPar) * (nVariables + 1))) ||
300 !(heatPar =
SDDS_Realloc(heatPar,
sizeof(*heatPar) * (nVariables + 1))) ||
301 !(stepPar =
SDDS_Realloc(stepPar,
sizeof(*stepPar) * (nVariables + 1))) ||
302 !(variableUnits =
SDDS_Realloc(variableUnits,
sizeof(*variableUnits) * (nVariables + 1))))
304 variableUnits[nVariables] = NULL;
305 heat[nVariables] = 0;
306 startingPar[nVariables] = heatPar[nVariables] = lowerLimitPar[nVariables] = upperLimitPar[nVariables] = stepPar[nVariables] = NULL;
307 if ((s_arg[i_arg].n_items -= 1) < 5 ||
308 !
scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
309 "name",
SDDS_STRING, variableName + nVariables, 1, VARNAME_GIVEN,
310 "lowerlimit",
SDDS_STRING, lowerLimitPar + nVariables, 1, LOWER_GIVEN,
311 "upperlimit",
SDDS_STRING, upperLimitPar + nVariables, 1, UPPER_GIVEN,
312 "stepsize",
SDDS_STRING, &(stepPar[nVariables]), 1, STEP_GIVEN,
313 "startingvalue",
SDDS_STRING, startingPar + nVariables, 1, START_GIVEN,
315 "units",
SDDS_STRING, variableUnits + nVariables, 1, VARUNITS_GIVEN, NULL))
316 SDDS_Bomb(
"Invalid -variable syntax or values");
317 if (startingPar[nVariables] && sscanf(startingPar[nVariables],
"%lf", startingValue + nVariables) == 1) {
318 free(startingPar[nVariables]);
319 startingPar[nVariables] = NULL;
321 if (lowerLimitPar[nVariables] && sscanf(lowerLimitPar[nVariables],
"%lf", lowerLimit + nVariables) == 1) {
322 free(lowerLimitPar[nVariables]);
323 lowerLimitPar[nVariables] = NULL;
325 if (upperLimitPar[nVariables] && sscanf(upperLimitPar[nVariables],
"%lf", upperLimit + nVariables) == 1) {
326 free(upperLimitPar[nVariables]);
327 upperLimitPar[nVariables] = NULL;
329 if (heatPar[nVariables] && sscanf(heatPar[nVariables],
"%lf", heat + nVariables) == 1) {
330 free(heatPar[nVariables]);
331 heatPar[nVariables] = NULL;
333 if (stepPar[nVariables] && sscanf(stepPar[nVariables],
"%lf", stepSize + nVariables) == 1) {
334 free(stepPar[nVariables]);
335 stepPar[nVariables] = NULL;
337 if ((dummyFlags & (VARNAME_GIVEN | LOWER_GIVEN | UPPER_GIVEN | STEP_GIVEN | START_GIVEN)) != (VARNAME_GIVEN | LOWER_GIVEN | UPPER_GIVEN | STEP_GIVEN | START_GIVEN))
338 SDDS_Bomb(
"Insufficient information given for -variable");
339 if (!strlen(variableName[nVariables]))
340 SDDS_Bomb(
"Invalid blank variable name");
341 if (!lowerLimitPar[nVariables] && !upperLimitPar[nVariables] && lowerLimit[nVariables] >= upperLimit[nVariables])
342 SDDS_Bomb(
"Invalid limits value for variable");
344 if (!lowerLimitPar[nVariables] && !upperLimitPar[nVariables] && !startingPar[nVariables] &&
345 (startingValue[nVariables] <= lowerLimit[nVariables] || startingValue[nVariables] >= upperLimit[nVariables]))
346 SDDS_Bomb(
"Invalid limits or starting value for variable");
347 if (!stepPar[nVariables] && stepSize[nVariables] <= 0)
348 SDDS_Bomb(
"Invalid step size for variable");
352 s_arg[i_arg].n_items -= 1;
353 if (!
scanItemList(&simplexFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
354 "restarts",
SDDS_LONG, &nRestartMax, 1, 0,
356 "evaluations",
SDDS_LONG, &nEvalMax, 1, 0,
357 "no1dscans", -1, NULL, 0, SIMPLEX_NO_1D_SCANS, NULL) ||
358 nRestartMax < 0 || nPassMax <= 0 || nEvalMax <= 0)
359 SDDS_Bomb(
"Invalid -simplex syntax/values");
362 if ((s_arg[i_arg].n_items < 2) || (s_arg[i_arg].n_items > 3))
364 if (s_arg[i_arg].n_items == 2) {
365 if (!strlen(equation = s_arg[i_arg].list[1])) {
368 }
else if (s_arg[i_arg].n_items == 3) {
369 if (strncmp(s_arg[i_arg].list[2],
"algebraic", strlen(s_arg[i_arg].list[2])) == 0) {
370 ptr = addOuterParentheses(s_arg[i_arg].list[1]);
371 if2pf(pfix, ptr,
sizeof pfix);
374 fprintf(stderr,
"Error: Problem copying equation string\n");
383 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
385 expression =
trealloc(expression,
sizeof(*expression) * (nExpressions + 1));
386 expression[nExpressions] = s_arg[i_arg].list[1];
387 expressionColumn =
trealloc(expressionColumn,
sizeof(*expressionColumn) * (nExpressions + 1));
388 if (s_arg[i_arg].n_items == 3)
389 expressionColumn[nExpressions] = s_arg[i_arg].list[2];
391 expressionColumn[nExpressions] = NULL;
394 case SET_STARTFROMPREVIOUS:
395 startFromPrevious = 1;
398 fprintf(stderr,
"Error: Unknown or ambiguous option: %s\n", s_arg[i_arg].list[0]);
404 input = s_arg[i_arg].list[0];
405 else if (output == NULL)
406 output = s_arg[i_arg].list[0];
408 SDDS_Bomb(
"Too many filenames provided");
415 SDDS_Bomb(
"-ycolumn option must be given");
417 SDDS_Bomb(
"You must specify at least one -variable option");
418 if (equation == NULL)
419 SDDS_Bomb(
"You must specify an equation string");
421 rpn(getenv(
"RPN_DEFNS"));
422 if (rpn_check_error())
427 if ((xName && !
SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, xName, NULL)) ||
429 (syName && !
SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, syName, NULL)))
430 SDDS_Bomb(
"One or more of the specified data columns does not exist or is non-numeric");
432 setupOutputFile(&OutputTable, &fitIndex, &residualIndex, output, &InputTable, xName, yName, syName,
433 variableName, variableUnits, nVariables, colMatch, colMatches,
434 expression, expressionColumn, nExpressions,
435 &logData, logFile, columnMajorOrder);
437 if (!(paramValue =
SDDS_Malloc(
sizeof(*paramValue) * nVariables)) ||
438 !(paramDelta =
SDDS_Malloc(
sizeof(*paramDelta) * nVariables)) ||
439 !(paramDelta0 =
SDDS_Malloc(
sizeof(*paramDelta0) * nVariables)) ||
440 !(variableMem =
SDDS_Malloc(
sizeof(*variableMem) * nVariables)))
442 for (iVariable = 0; iVariable < nVariables; iVariable++)
443 variableMem[iVariable] = rpn_create_mem(variableName[iVariable], 0);
455 for (iVariable = 0; iVariable < nVariables; iVariable++) {
456 if (startingPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, startingPar[iVariable], &startingValue[iVariable]))
458 if (lowerLimitPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, lowerLimitPar[iVariable], &lowerLimit[iVariable]))
460 if (upperLimitPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, upperLimitPar[iVariable], &upperLimit[iVariable]))
469 }
else if (retval == 1 || !startFromPrevious)
470 paramValue[iVariable] = startingValue[iVariable];
471 paramDelta[iVariable] = stepSize[iVariable];
475 fprintf(stderr,
"Starting values and step sizes:\n");
476 for (iVariable = 0; iVariable < nVariables; iVariable++)
477 fprintf(stderr,
" %s = %le %le\n", variableName[iVariable], paramValue[iVariable], paramDelta[iVariable]);
480 if (!(yFit =
SDDS_Realloc(yFit,
sizeof(*yFit) * nData)) ||
481 !(yResidual =
SDDS_Realloc(yResidual,
sizeof(*yResidual) * nData)))
485 expressionValue =
SDDS_Realloc(expressionValue,
sizeof(*expressionValue) * nExpressions);
486 for (j = 0; j < nExpressions; j++)
487 expressionValue[j] = malloc(
sizeof(**expressionValue) * nData);
489 SDDS_StoreParametersInRpnMemories(&InputTable);
490 memcpy(paramDelta0, paramDelta,
sizeof(*paramDelta) * nVariables);
491 for (iRestart = nEval = 0; iRestart <= nRestartMax; iRestart++) {
492 memcpy(paramDelta, paramDelta0,
sizeof(*paramDelta) * nVariables);
495 random_1(-labs(2 * ((
long)time(NULL) / 2) + 1));
496 for (iVariable = 0; iVariable < nVariables; iVariable++) {
498 if (paramValue[iVariable] < lowerLimit[iVariable])
499 paramValue[iVariable] = lowerLimit[iVariable] + paramDelta[iVariable];
500 if (paramValue[iVariable] > upperLimit[iVariable])
501 paramValue[iVariable] = upperLimit[iVariable] - paramDelta[iVariable];
504 nEval +=
simplexMin(&result, paramValue, paramDelta, lowerLimit, upperLimit, NULL, nVariables, target, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
505 if (iRestart != 0 && result > bestResult) {
507 for (iVariable = 0; iVariable < nVariables; iVariable++)
508 paramValue[iVariable] = bestParamValue[iVariable];
511 for (iVariable = 0; iVariable < nVariables; iVariable++)
512 bestParamValue[iVariable] = paramValue[iVariable];
515 fprintf(stderr,
"Result of simplex minimization: %le\n", result);
516 if (result < target || (iRestart != 0 && fabs(lastResult - result) < tolerance))
522 fprintf(stderr,
"Performing restart %ld\n", iRestart + 1);
525 for (iVariable = 0; iVariable < nVariables; iVariable++)
526 paramValue[iVariable] = bestParamValue[iVariable];
527 result = fitFunction(paramValue, &ii);
530 fprintf(stderr,
"%ld evaluations of fit function required, giving result %e\n", nEval, result);
531 for (i = result = 0; i < nData; i++)
532 result += sqr(yResidual[i]);
533 rmsResidual = sqrt(result / nData);
535 for (i = chiSqr = 0; i < nData; i++)
536 chiSqr += sqr(yResidual[i] / syData[i]);
539 sy2 = result / (nData - nVariables);
540 for (i = chiSqr = 0; i < nData; i++)
541 chiSqr += sqr(yResidual[i]) / sy2;
546 fprintf(stderr,
"Significance level: %.5e\n", sigLevel);
547 fprintf(stderr,
"RMS deviation: %.15e\n", rmsResidual);
552 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yFit, nData, fitIndex) ||
553 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yResidual, nData, residualIndex))
555 for (i = 0; i < nExpressions; i++)
556 if (expressionColumn[i] &&
557 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_NAME, expressionValue[i], nData, expressionColumn[i]))
559 for (iVariable = 0; iVariable < nVariables; iVariable++)
560 if (!
SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, variableName[iVariable], paramValue[iVariable], NULL))
586 free(bestParamValue);
598void setupOutputFile(
SDDS_DATASET *OutputTable,
long *fitIndex,
long *residualIndex,
char *output,
599 SDDS_DATASET *InputTable,
char *xName,
char *yName,
char *syName,
char **variableName,
600 char **variableUnits,
long variables,
char **colMatch, int32_t colMatches,
601 char **expression,
char **expressionColumn,
long nExpressions,
602 SDDS_DATASET *logData,
char *logFile,
short columnMajorOrder) {
603 char *name, *yUnits = NULL, **col = NULL;
605 static char *residualNamePart =
"Residual";
613 if (columnMajorOrder != -1)
614 OutputTable->layout.data_mode.column_major = columnMajorOrder;
616 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
617 if (logFile && !!
SDDS_InitializeOutput(logData, SDDS_BINARY, 0, NULL,
"sddsgenericfit log", logFile))
627 for (i = 0; i < cols; i++) {
634 name =
tmalloc(
sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
635 sprintf(name,
"%s%s", yName, residualNamePart);
638 sprintf(name,
"%sFit", yName);
643 for (i = 0; i < variables; i++) {
650 for (i = 0; i < nExpressions; i++) {
651 if (expressionColumn[i]) {
665double fitFunction(
double *a,
long *invalid) {
673 for (i = 0; i < nVariables; i++)
674 rpn_store(a[i], NULL, variableMem[i]);
677 fprintf(stderr,
"Running fit function:\n");
679 for (i = sum = 0; i < nData; i++) {
680 if (!SDDS_StoreRowInRpnMemories(&InputTable, i))
681 SDDS_Bomb(
"Problem storing data in RPN memories");
683 for (j = 0; j < nExpressions; j++) {
684 expressionValue[j][i] = rpn(expression[j]);
686 fprintf(stderr,
"Expression %ld: %le\n", j, expressionValue[j][i]);
688 yFit[i] = rpn(equation);
689 if (rpn_check_error()) {
693 yResidual[i] = tmp = (yFit[i] - yData[i]);
694 if (verbosity > 10) {
696 fprintf(stderr,
"i=%" PRId64
" x=%le y=%le fit=%le\n", i, xData[i], yData[i], yFit[i]);
698 fprintf(stderr,
"i=%" PRId64
" y=%le fit=%le\n", i, yData[i], yFit[i]);
703 for (i = sum = 0; i < nData; i++) {
704 if (!SDDS_StoreRowInRpnMemories(&InputTable, i))
705 SDDS_Bomb(
"Problem storing data in RPN memories");
707 for (j = 0; j < nExpressions; j++)
708 expressionValue[j][i] = rpn(expression[j]);
709 yFit[i] = rpn(equation);
710 if (rpn_check_error()) {
714 yResidual[i] = tmp = (yFit[i] - yData[i]);
715 sum += sqr(tmp / syData[i]);
722 if (step && (step % maxLogRows) == 0) {
726 if (!
SDDS_SetRowValues(&logData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, step - 1,
"Step", step,
"Chi", sum / nData, NULL))
728 for (i = 0; i < nVariables; i++) {
729 if (!
SDDS_SetRowValues(&logData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, step - 1, variableName[i], a[i], NULL))
733 return (sum / nData);
736void report(
double y,
double *x,
long pass,
long n_eval,
long n_dimen) {
739 fprintf(stderr,
"pass %ld, after %ld evaluations: result = %.16e\na = ", pass, n_eval, y);
740 for (i = 0; i < n_dimen; i++)
741 fprintf(stderr,
"%.8e ", x[i]);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition within the SDDS dataset.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_UpdatePage(SDDS_DATASET *SDDS_dataset, uint32_t mode)
Updates the current page of the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
char * SDDS_FindColumn(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Finds the first column in the SDDS dataset that matches the specified criteria.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
double random_1(long iseed)
Generate a uniform random double in [0,1] using a custom seed initialization.
double gauss_rn_lim(double mean, double sigma, double limit_in_sigmas, double(*urandom)(long iseed))
Generate a Gaussian-distributed random number with specified mean, sigma, and optional cutoff.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
double ChiSqrSigLevel(double ChiSquared0, long nu)
Computes the probability that a chi-squared variable exceeds a given value.
long simplexMinAbort(unsigned long abort)
Abort or query the status of the simplex optimization.
long simplexMin(double *yReturn, double *xGuess, double *dxGuess, double *xLowerLimit, double *xUpperLimit, short *disable, long dimensions, double target, double tolerance, double(*func)(double *x, long *invalid), void(*report)(double ymin, double *xmin, long pass, long evals, long dims), long maxEvaluations, long maxPasses, long maxDivisions, double divisorFactor, double passRangeFactor, unsigned long flags)
Top-level convenience function for simplex-based minimization.