85 SET_STARTFROMPREVIOUS,
94char *option[N_OPTIONS] = {
112 "Usage: sddsgenericfit [OPTIONS] [<inputfile>] [<outputfile>]\n"
114 " -pipe=[input][,output]\n"
115 " -equation=<rpnString>[,algebraic]\n"
116 " -expression=<string>[,<columnName>] [-expression=...]\n"
118 " -tolerance=<value>\n"
119 " -simplex=[restarts=<nRestarts>][,cycles=<nCycles>][,evaluations=<nEvals>][,no1DScans]\n"
120 " -variable=name=<name>,lowerLimit=<value|parameter-name>,upperLimit=<value|parameter-name>,\n"
121 " stepsize=<value|parameter-name>,startingValue=<value|parametername>[,units=<string>][,heat=<value|parameter-name>]\n"
122 " -verbosity=<integer>\n"
123 " -startFromPrevious\n"
124 " -majorOrder=row|column\n"
125 " -copy=<list of column names>\n"
126 " -ycolumn=ycolumn_name[,ySigma=<sy-name>]\n"
127 " -logFile=<filename>[,<flushInterval(500)>]\n"
129 " Uses the Simplex method to find a fit to <y-name> as a function of <x-name> by varying the given\n"
130 " variables, which are assumed to appear in the <rpnString>.\n"
131 "\nDetailed Options:\n"
133 " Specify the name of the dependent data column and optionally <sy-name> to weight the fit.\n"
134 " This option replaces the old -columns option.\n"
136 " Provide a list of column names to copy from the input file to the output file.\n"
138 " If provided, the intermediate fitting results will be written to the specified log file.\n"
140 " Specify an RPN expression for the equation used in fitting. This equation can use the names\n"
141 " of any of the columns or parameters in the file, just as in sddsprocess. It is expected\n"
142 " to return a value that will be compared to the data in column <y-name>.\n"
144 " Specify an RPN expression to evaluate before the main equation is evaluated. Can be used\n"
145 " to prepare quantities on the stack or in variables when the equation is complicated.\n"
146 " If the <columnName> is given, values of the expression are stored in the output file\n"
147 " under the given name.\n"
149 " Specify the value of the (weighted) RMS residual that is acceptably small to consider the\n"
152 " Specify the minimum change in the (weighted) RMS residual that is considered significant\n"
153 " enough to justify continuing optimization.\n"
155 " Configure simplex optimization parameters such as restarts, cycles, evaluations, and disabling 1D scans.\n"
156 " Defaults are 10 restarts, 10 cycles, and 5000 evaluations.\n"
158 " Define a fitting variable with its name, lower limit, upper limit, step size, starting value,\n"
159 " units, and an optional heat parameter. The variable name must not match any existing column\n"
160 " or parameter in the input file.\n"
162 " Set the verbosity level of output during optimization. Higher values result in more detailed output.\n"
163 " -startFromPrevious\n"
164 " Use the final values from the previous fit as starting values for the next fit.\n"
166 " Specify the output file's data order as row-major or column-major.\n"
167 "\nProgram Information:\n"
168 " Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
170void report(
double res,
double *a,
long pass,
long n_eval,
long n_dimen);
171void setupOutputFile(
SDDS_DATASET *OutputTable,
long *fitIndex,
long *residualIndex,
char *output,
172 SDDS_DATASET *InputTable,
char *xName,
char *yName,
char *syName,
char **variableName,
173 char **variableUnits,
long variables,
char **colMatch, int32_t colMatches,
174 char **expression,
char **expressionColumn,
long nExpressions,
175 SDDS_DATASET *logData,
char *logFile,
short columnMajorOrder);
177double fitFunction(
double *a,
long *invalid);
180static double *xData = NULL, *yData = NULL, *syData = NULL, *yFit = NULL, *yResidual = NULL;
181static int64_t nData = 0;
182static char *equation;
183static long *variableMem, nVariables, verbosity;
184static char **expression = NULL;
185static char **expressionColumn = NULL;
186static long nExpressions = 0;
187static double **expressionValue = NULL;
188static char **variableName = NULL;
189static int64_t step = 0;
190static char *logFile = NULL;
192static int32_t maxLogRows = 500;
194#define VARNAME_GIVEN 0x0001U
195#define LOWER_GIVEN 0x0002U
196#define UPPER_GIVEN 0x0004U
197#define STEP_GIVEN 0x0008U
198#define START_GIVEN 0x0010U
199#define VARUNITS_GIVEN 0x0020U
201static short abortRequested = 0;
203void optimizationInterruptHandler(
int signal) {
206 fprintf(stderr,
"Aborting minimization\n");
209int main(
int argc,
char **argv) {
214 char *input, *output, *xName, *yName, *syName, **colMatch;
215 long fitIndex, residualIndex, retval;
217 double rmsResidual, chiSqr, sigLevel;
218 unsigned long pipeFlags, dummyFlags, majorOrderFlag;
219 int32_t nEvalMax = 5000, nPassMax = 10, nRestartMax = 10;
220 long nEval, iRestart;
221 double tolerance, target;
222 char **variableUnits;
223 double *lowerLimit, *upperLimit, *stepSize, *startingValue, *paramValue, *paramDelta = NULL, *paramDelta0 = NULL;
224 char **startingPar = NULL, **lowerLimitPar = NULL, **upperLimitPar = NULL, **heatPar = NULL, **stepPar = NULL;
225 double *heat, *bestParamValue, bestResult = 0;
226 long iVariable, startFromPrevious = 0;
227 double result, lastResult = 0;
228 char pfix[IFPF_BUF_SIZE];
229 unsigned long simplexFlags = 0;
231 short columnMajorOrder = -1;
233 signal(SIGINT, optimizationInterruptHandler);
236 argc =
scanargs(&s_arg, argc, argv);
240 fprintf(stderr,
"%s", USAGE);
244 input = output = equation = NULL;
245 variableName = variableUnits = NULL;
246 lowerLimit = upperLimit = stepSize = startingValue = heat = bestParamValue = NULL;
249 verbosity = startFromPrevious = 0;
250 xName = yName = syName = NULL;
251 tolerance = target = 1e-14;
253 for (i_arg = 1; i_arg < argc; i_arg++) {
254 if (s_arg[i_arg].arg_type == OPTION) {
255 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
256 case SET_MAJOR_ORDER:
258 s_arg[i_arg].n_items--;
259 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)))
260 SDDS_Bomb(
"Invalid -majorOrder syntax/values");
261 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
262 columnMajorOrder = 1;
263 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
264 columnMajorOrder = 0;
267 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%lf", &tolerance) != 1 || tolerance <= 0)
268 SDDS_Bomb(
"Incorrect -tolerance syntax");
271 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%lf", &target) != 1 || target <= 0)
275 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1],
"%ld", &verbosity) != 1)
276 SDDS_Bomb(
"Incorrect -verbosity syntax");
279 if (s_arg[i_arg].n_items != 3 && s_arg[i_arg].n_items != 4)
281 xName = s_arg[i_arg].list[1];
282 yName = s_arg[i_arg].list[2];
283 s_arg[i_arg].n_items -= 3;
284 if (!
scanItemList(&dummyFlags, s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0,
"ysigma",
SDDS_STRING, &syName, 1, 0, NULL))
288 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
290 yName = s_arg[i_arg].list[1];
291 s_arg[i_arg].n_items -= 2;
292 if (!
scanItemList(&dummyFlags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
"ysigma",
SDDS_STRING, &syName, 1, 0, NULL))
295 case SET_COPYCOLUMNS:
296 if (s_arg[i_arg].n_items < 2)
297 SDDS_Bomb(
"Invalid -copycolumns syntax provided.");
298 colMatch =
tmalloc(
sizeof(*colMatch) * (colMatches = s_arg[i_arg].n_items - 1));
299 for (i = 0; i < colMatches; i++)
300 colMatch[i] = s_arg[i_arg].list[i + 1];
303 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
307 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
309 logFile = s_arg[i_arg].list[1];
310 if (s_arg[i_arg].n_items == 3 && (sscanf(s_arg[i_arg].list[2],
"%" SCNd32, &maxLogRows) != 1 || maxLogRows <= 0))
314 if (!(variableName =
SDDS_Realloc(variableName,
sizeof(*variableName) * (nVariables + 1))) ||
315 !(lowerLimit =
SDDS_Realloc(lowerLimit,
sizeof(*lowerLimit) * (nVariables + 1))) ||
316 !(upperLimit =
SDDS_Realloc(upperLimit,
sizeof(*upperLimit) * (nVariables + 1))) ||
317 !(stepSize =
SDDS_Realloc(stepSize,
sizeof(*stepSize) * (nVariables + 1))) ||
318 !(heat =
SDDS_Realloc(heat,
sizeof(*heat) * (nVariables + 1))) ||
319 !(bestParamValue =
SDDS_Realloc(bestParamValue,
sizeof(*bestParamValue) * (nVariables + 1))) ||
320 !(startingValue =
SDDS_Realloc(startingValue,
sizeof(*startingValue) * (nVariables + 1))) ||
321 !(startingPar =
SDDS_Realloc(startingPar,
sizeof(*startingPar) * (nVariables + 1))) ||
322 !(lowerLimitPar =
SDDS_Realloc(lowerLimitPar,
sizeof(*lowerLimitPar) * (nVariables + 1))) ||
323 !(upperLimitPar =
SDDS_Realloc(upperLimitPar,
sizeof(*upperLimitPar) * (nVariables + 1))) ||
324 !(heatPar =
SDDS_Realloc(heatPar,
sizeof(*heatPar) * (nVariables + 1))) ||
325 !(stepPar =
SDDS_Realloc(stepPar,
sizeof(*stepPar) * (nVariables + 1))) ||
326 !(variableUnits =
SDDS_Realloc(variableUnits,
sizeof(*variableUnits) * (nVariables + 1))))
328 variableUnits[nVariables] = NULL;
329 heat[nVariables] = 0;
330 startingPar[nVariables] = heatPar[nVariables] = lowerLimitPar[nVariables] = upperLimitPar[nVariables] = stepPar[nVariables] = NULL;
331 if ((s_arg[i_arg].n_items -= 1) < 5 ||
332 !
scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
333 "name",
SDDS_STRING, variableName + nVariables, 1, VARNAME_GIVEN,
334 "lowerlimit",
SDDS_STRING, lowerLimitPar + nVariables, 1, LOWER_GIVEN,
335 "upperlimit",
SDDS_STRING, upperLimitPar + nVariables, 1, UPPER_GIVEN,
336 "stepsize",
SDDS_STRING, &(stepPar[nVariables]), 1, STEP_GIVEN,
337 "startingvalue",
SDDS_STRING, startingPar + nVariables, 1, START_GIVEN,
339 "units",
SDDS_STRING, variableUnits + nVariables, 1, VARUNITS_GIVEN, NULL))
340 SDDS_Bomb(
"Invalid -variable syntax or values");
341 if (startingPar[nVariables] && sscanf(startingPar[nVariables],
"%lf", startingValue + nVariables) == 1) {
342 free(startingPar[nVariables]);
343 startingPar[nVariables] = NULL;
345 if (lowerLimitPar[nVariables] && sscanf(lowerLimitPar[nVariables],
"%lf", lowerLimit + nVariables) == 1) {
346 free(lowerLimitPar[nVariables]);
347 lowerLimitPar[nVariables] = NULL;
349 if (upperLimitPar[nVariables] && sscanf(upperLimitPar[nVariables],
"%lf", upperLimit + nVariables) == 1) {
350 free(upperLimitPar[nVariables]);
351 upperLimitPar[nVariables] = NULL;
353 if (heatPar[nVariables] && sscanf(heatPar[nVariables],
"%lf", heat + nVariables) == 1) {
354 free(heatPar[nVariables]);
355 heatPar[nVariables] = NULL;
357 if (stepPar[nVariables] && sscanf(stepPar[nVariables],
"%lf", stepSize + nVariables) == 1) {
358 free(stepPar[nVariables]);
359 stepPar[nVariables] = NULL;
361 if ((dummyFlags & (VARNAME_GIVEN | LOWER_GIVEN | UPPER_GIVEN | STEP_GIVEN | START_GIVEN)) != (VARNAME_GIVEN | LOWER_GIVEN | UPPER_GIVEN | STEP_GIVEN | START_GIVEN))
362 SDDS_Bomb(
"Insufficient information given for -variable");
363 if (!strlen(variableName[nVariables]))
364 SDDS_Bomb(
"Invalid blank variable name");
365 if (!lowerLimitPar[nVariables] && !upperLimitPar[nVariables] && lowerLimit[nVariables] >= upperLimit[nVariables])
366 SDDS_Bomb(
"Invalid limits value for variable");
368 if (!lowerLimitPar[nVariables] && !upperLimitPar[nVariables] && !startingPar[nVariables] &&
369 (startingValue[nVariables] <= lowerLimit[nVariables] || startingValue[nVariables] >= upperLimit[nVariables]))
370 SDDS_Bomb(
"Invalid limits or starting value for variable");
371 if (!stepPar[nVariables] && stepSize[nVariables] <= 0)
372 SDDS_Bomb(
"Invalid step size for variable");
376 s_arg[i_arg].n_items -= 1;
377 if (!
scanItemList(&simplexFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
378 "restarts",
SDDS_LONG, &nRestartMax, 1, 0,
380 "evaluations",
SDDS_LONG, &nEvalMax, 1, 0,
381 "no1dscans", -1, NULL, 0, SIMPLEX_NO_1D_SCANS, NULL) ||
382 nRestartMax < 0 || nPassMax <= 0 || nEvalMax <= 0)
383 SDDS_Bomb(
"Invalid -simplex syntax/values");
386 if ((s_arg[i_arg].n_items < 2) || (s_arg[i_arg].n_items > 3))
388 if (s_arg[i_arg].n_items == 2) {
389 if (!strlen(equation = s_arg[i_arg].list[1])) {
392 }
else if (s_arg[i_arg].n_items == 3) {
393 if (strncmp(s_arg[i_arg].list[2],
"algebraic", strlen(s_arg[i_arg].list[2])) == 0) {
394 ptr = addOuterParentheses(s_arg[i_arg].list[1]);
395 if2pf(pfix, ptr,
sizeof pfix);
398 fprintf(stderr,
"Error: Problem copying equation string\n");
407 if (s_arg[i_arg].n_items != 2 && s_arg[i_arg].n_items != 3)
409 expression =
trealloc(expression,
sizeof(*expression) * (nExpressions + 1));
410 expression[nExpressions] = s_arg[i_arg].list[1];
411 expressionColumn =
trealloc(expressionColumn,
sizeof(*expressionColumn) * (nExpressions + 1));
412 if (s_arg[i_arg].n_items == 3)
413 expressionColumn[nExpressions] = s_arg[i_arg].list[2];
415 expressionColumn[nExpressions] = NULL;
418 case SET_STARTFROMPREVIOUS:
419 startFromPrevious = 1;
422 fprintf(stderr,
"Error: Unknown or ambiguous option: %s\n", s_arg[i_arg].list[0]);
428 input = s_arg[i_arg].list[0];
429 else if (output == NULL)
430 output = s_arg[i_arg].list[0];
432 SDDS_Bomb(
"Too many filenames provided");
439 SDDS_Bomb(
"-ycolumn option must be given");
441 SDDS_Bomb(
"You must specify at least one -variable option");
442 if (equation == NULL)
443 SDDS_Bomb(
"You must specify an equation string");
445 rpn(getenv(
"RPN_DEFNS"));
446 if (rpn_check_error())
451 if ((xName && !
SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, xName, NULL)) ||
453 (syName && !
SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, syName, NULL)))
454 SDDS_Bomb(
"One or more of the specified data columns does not exist or is non-numeric");
456 setupOutputFile(&OutputTable, &fitIndex, &residualIndex, output, &InputTable, xName, yName, syName,
457 variableName, variableUnits, nVariables, colMatch, colMatches,
458 expression, expressionColumn, nExpressions,
459 &logData, logFile, columnMajorOrder);
461 if (!(paramValue =
SDDS_Malloc(
sizeof(*paramValue) * nVariables)) ||
462 !(paramDelta =
SDDS_Malloc(
sizeof(*paramDelta) * nVariables)) ||
463 !(paramDelta0 =
SDDS_Malloc(
sizeof(*paramDelta0) * nVariables)) ||
464 !(variableMem =
SDDS_Malloc(
sizeof(*variableMem) * nVariables)))
466 for (iVariable = 0; iVariable < nVariables; iVariable++)
467 variableMem[iVariable] = rpn_create_mem(variableName[iVariable], 0);
479 for (iVariable = 0; iVariable < nVariables; iVariable++) {
480 if (startingPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, startingPar[iVariable], &startingValue[iVariable]))
482 if (lowerLimitPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, lowerLimitPar[iVariable], &lowerLimit[iVariable]))
484 if (upperLimitPar[iVariable] && !
SDDS_GetParameterAsDouble(&InputTable, upperLimitPar[iVariable], &upperLimit[iVariable]))
493 }
else if (retval == 1 || !startFromPrevious)
494 paramValue[iVariable] = startingValue[iVariable];
495 paramDelta[iVariable] = stepSize[iVariable];
499 fprintf(stderr,
"Starting values and step sizes:\n");
500 for (iVariable = 0; iVariable < nVariables; iVariable++)
501 fprintf(stderr,
" %s = %le %le\n", variableName[iVariable], paramValue[iVariable], paramDelta[iVariable]);
504 if (!(yFit =
SDDS_Realloc(yFit,
sizeof(*yFit) * nData)) ||
505 !(yResidual =
SDDS_Realloc(yResidual,
sizeof(*yResidual) * nData)))
509 expressionValue =
SDDS_Realloc(expressionValue,
sizeof(*expressionValue) * nExpressions);
510 for (j = 0; j < nExpressions; j++)
511 expressionValue[j] = malloc(
sizeof(**expressionValue) * nData);
513 SDDS_StoreParametersInRpnMemories(&InputTable);
514 memcpy(paramDelta0, paramDelta,
sizeof(*paramDelta) * nVariables);
515 for (iRestart = nEval = 0; iRestart <= nRestartMax; iRestart++) {
516 memcpy(paramDelta, paramDelta0,
sizeof(*paramDelta) * nVariables);
519 random_1(-labs(2 * ((
long)time(NULL) / 2) + 1));
520 for (iVariable = 0; iVariable < nVariables; iVariable++) {
522 if (paramValue[iVariable] < lowerLimit[iVariable])
523 paramValue[iVariable] = lowerLimit[iVariable] + paramDelta[iVariable];
524 if (paramValue[iVariable] > upperLimit[iVariable])
525 paramValue[iVariable] = upperLimit[iVariable] - paramDelta[iVariable];
528 nEval +=
simplexMin(&result, paramValue, paramDelta, lowerLimit, upperLimit, NULL, nVariables, target, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
529 if (iRestart != 0 && result > bestResult) {
531 for (iVariable = 0; iVariable < nVariables; iVariable++)
532 paramValue[iVariable] = bestParamValue[iVariable];
535 for (iVariable = 0; iVariable < nVariables; iVariable++)
536 bestParamValue[iVariable] = paramValue[iVariable];
539 fprintf(stderr,
"Result of simplex minimization: %le\n", result);
540 if (result < target || (iRestart != 0 && fabs(lastResult - result) < tolerance))
546 fprintf(stderr,
"Performing restart %ld\n", iRestart + 1);
549 for (iVariable = 0; iVariable < nVariables; iVariable++)
550 paramValue[iVariable] = bestParamValue[iVariable];
551 result = fitFunction(paramValue, &ii);
554 fprintf(stderr,
"%ld evaluations of fit function required, giving result %e\n", nEval, result);
555 for (i = result = 0; i < nData; i++)
556 result += sqr(yResidual[i]);
557 rmsResidual = sqrt(result / nData);
559 for (i = chiSqr = 0; i < nData; i++)
560 chiSqr += sqr(yResidual[i] / syData[i]);
563 sy2 = result / (nData - nVariables);
564 for (i = chiSqr = 0; i < nData; i++)
565 chiSqr += sqr(yResidual[i]) / sy2;
570 fprintf(stderr,
"Significance level: %.5e\n", sigLevel);
571 fprintf(stderr,
"RMS deviation: %.15e\n", rmsResidual);
576 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yFit, nData, fitIndex) ||
577 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yResidual, nData, residualIndex))
579 for (i = 0; i < nExpressions; i++)
580 if (expressionColumn[i] &&
581 !
SDDS_SetColumn(&OutputTable, SDDS_SET_BY_NAME, expressionValue[i], nData, expressionColumn[i]))
583 for (iVariable = 0; iVariable < nVariables; iVariable++)
584 if (!
SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, variableName[iVariable], paramValue[iVariable], NULL))
610 free(bestParamValue);
622void setupOutputFile(
SDDS_DATASET *OutputTable,
long *fitIndex,
long *residualIndex,
char *output,
623 SDDS_DATASET *InputTable,
char *xName,
char *yName,
char *syName,
char **variableName,
624 char **variableUnits,
long variables,
char **colMatch, int32_t colMatches,
625 char **expression,
char **expressionColumn,
long nExpressions,
626 SDDS_DATASET *logData,
char *logFile,
short columnMajorOrder) {
627 char *name, *yUnits = NULL, **col = NULL;
629 static char *residualNamePart =
"Residual";
637 if (columnMajorOrder != -1)
638 OutputTable->layout.data_mode.column_major = columnMajorOrder;
640 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
641 if (logFile && !!
SDDS_InitializeOutput(logData, SDDS_BINARY, 0, NULL,
"sddsgenericfit log", logFile))
651 for (i = 0; i < cols; i++) {
658 name =
tmalloc(
sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
659 sprintf(name,
"%s%s", yName, residualNamePart);
662 sprintf(name,
"%sFit", yName);
667 for (i = 0; i < variables; i++) {
674 for (i = 0; i < nExpressions; i++) {
675 if (expressionColumn[i]) {
689double fitFunction(
double *a,
long *invalid) {
697 for (i = 0; i < nVariables; i++)
698 rpn_store(a[i], NULL, variableMem[i]);
701 fprintf(stderr,
"Running fit function:\n");
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]);
710 fprintf(stderr,
"Expression %ld: %le\n", j, expressionValue[j][i]);
712 yFit[i] = rpn(equation);
713 if (rpn_check_error()) {
717 yResidual[i] = tmp = (yFit[i] - yData[i]);
718 if (verbosity > 10) {
720 fprintf(stderr,
"i=%" PRId64
" x=%le y=%le fit=%le\n", i, xData[i], yData[i], yFit[i]);
722 fprintf(stderr,
"i=%" PRId64
" y=%le fit=%le\n", i, yData[i], yFit[i]);
727 for (i = sum = 0; i < nData; i++) {
728 if (!SDDS_StoreRowInRpnMemories(&InputTable, i))
729 SDDS_Bomb(
"Problem storing data in RPN memories");
731 for (j = 0; j < nExpressions; j++)
732 expressionValue[j][i] = rpn(expression[j]);
733 yFit[i] = rpn(equation);
734 if (rpn_check_error()) {
738 yResidual[i] = tmp = (yFit[i] - yData[i]);
739 sum += sqr(tmp / syData[i]);
746 if (step && (step % maxLogRows) == 0) {
750 if (!
SDDS_SetRowValues(&logData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, step - 1,
"Step", step,
"Chi", sum / nData, NULL))
752 for (i = 0; i < nVariables; i++) {
753 if (!
SDDS_SetRowValues(&logData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, step - 1, variableName[i], a[i], NULL))
757 return (sum / nData);
760void report(
double y,
double *x,
long pass,
long n_eval,
long n_dimen) {
763 fprintf(stderr,
"pass %ld, after %ld evaluations: result = %.16e\na = ", pass, n_eval, y);
764 for (i = 0; i < n_dimen; i++)
765 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.
Header file for routines used by SDDS command-line applications.
#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.