SDDSlib
Loading...
Searching...
No Matches
sddssinefit.c
Go to the documentation of this file.
1/**
2 * @file sddssinefit.c
3 * @brief Performs a sinusoidal fit on input data using the model:
4 * y(n) = a0 + a1*sin(2*PI*a2*x(n) + a3)
5 * or
6 * y(n) = a0 + a1*sin(2*PI*a2*x(n) + a3) + a4*x(n)
7 *
8 * This program reads input data from an SDDS (Self Describing Data Sets) file,
9 * performs a sinusoidal fit based on the provided parameters and options, and
10 * outputs the fitted data along with residuals to an output SDDS file.
11 *
12 * @copyright
13 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
14 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
15 *
16 * @license
17 * This file is distributed under the terms of the Software License Agreement
18 * found in the file LICENSE included with this distribution.
19 *
20 * @author M. Borland, C. Saunders, R. Soliday, L. Emery, H. Shang, N. Kuklev
21 */
22
23#include "mdb.h"
24#include "SDDS.h"
25#include "scan.h"
26
27/* Enumeration for option types */
28enum option_type {
29 SET_TOLERANCE,
30 SET_VERBOSITY,
31 SET_CLUE,
32 SET_GUESS,
33 SET_COLUMNS,
34 SET_FULLOUTPUT,
35 SET_LIMITS,
36 SET_PIPE,
37 SET_MAJOR_ORDER,
38 SET_LOCK_FREQ,
39 SET_ADD_SLOPE,
40 N_OPTIONS
41};
42
43char *option[N_OPTIONS] = {
44 "tolerance",
45 "verbosity",
46 "clue",
47 "guess",
48 "columns",
49 "fulloutput",
50 "limits",
51 "pipe",
52 "majorOrder",
53 "lockFrequency",
54 "addSlope",
55};
56
57static char *USAGE =
58 "Usage: sddssinefit [<inputfile>] [<outputfile>] \n"
59 " [-pipe=<input>[,<output>]]\n"
60 " [-fulloutput]\n"
61 " [-columns=<x-name>,<y-name>]\n"
62 " [-tolerance=<value>]\n"
63 " [-limits=evaluations=<number>,passes=<number>]\n"
64 " [-verbosity=<integer>]\n"
65 " [-guess=constant=<constant>,factor=<factor>,frequency=<freq>,phase=<phase>,slope=<slope>]\n"
66 " [-lockFrequency]\n"
67 " [-addSlope]\n"
68 " [-majorOrder=row|column]\n\n"
69 "Description:\n"
70 " Performs a sinusoidal fit of the form:\n"
71 " y = <constant> + <factor>*sin(2*PI*<freq>*x + <phase>)\n"
72 " or\n"
73 " y = <constant> + <factor>*sin(2*PI*<freq>*x + <phase>) + <slope>*x\n\n"
74 "Options:\n"
75 " <inputfile> : Path to the input SDDS file.\n"
76 " <outputfile> : Path to the output SDDS file.\n"
77 " -pipe=<input>,<output> : Use standard input/output for data streams.\n"
78 " -fulloutput : Include full output with residuals.\n"
79 " -columns=<x-name>,<y-name> : Specify the names of the x and y data columns.\n"
80 " -tolerance=<value> : Set the tolerance for the fitting algorithm (default: 1e-6).\n"
81 " -limits=evaluations=<n>,passes=<m> : Set maximum number of evaluations and passes (default: 5000 evaluations, 25 passes).\n"
82 " -verbosity=<integer> : Set verbosity level (default: 0).\n"
83 " -guess=constant=<c>,factor=<f>,frequency=<freq>,phase=<p>,slope=<s> : Provide initial guesses for fit parameters.\n"
84 " -lockFrequency : Lock the frequency parameter during fitting.\n"
85 " -addSlope : Include a slope term in the fit.\n"
86 " -majorOrder=row|column : Specify the major order for data processing.\n\n"
87 "Author:\n"
88 " Michael Borland\n"
89 " (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
90
91static double *xData, *yData;
92static int64_t nData;
93static double yMin, yMax, xMin, xMax;
94static double fit[5];
95
96double fitFunction(double *a, long *invalid);
97double fitFunctionWithSlope(double *a, long *invalid);
98void report(double res, double *a, long pass, long n_eval, long n_dimen);
99void setupOutputFile(SDDS_DATASET *OutputTable, int32_t *xIndex, int32_t *yIndex, int32_t *fitIndex,
100 int32_t *residualIndex, char *output, long fullOutput, SDDS_DATASET *InputTable,
101 char *xName, char *yName, short columnMajorOrder, short addSlope);
102char *makeInverseUnits(char *units);
103
104long verbosity;
105
106#define GUESS_CONSTANT_GIVEN 0x0001
107#define GUESS_FACTOR_GIVEN 0x0002
108#define GUESS_FREQ_GIVEN 0x0004
109#define GUESS_PHASE_GIVEN 0x0008
110#define GUESS_SLOPE_GIVEN 0x0010
111
112int main(int argc, char **argv) {
113 double tolerance, result;
114 int32_t nEvalMax = 5000, nPassMax = 25;
115 double a[5], da[5];
116 double alo[5], ahi[5];
117 long n_dimen = 4;
118 int64_t zeroes;
119 SDDS_DATASET InputTable, OutputTable;
120 SCANNED_ARG *s_arg;
121 long i_arg, fullOutput;
122 int64_t i;
123 char *input, *output, *xName, *yName;
124 int32_t xIndex, yIndex, fitIndex, residualIndex;
125 long retval;
126 double *fitData, *residualData, rmsResidual;
127 unsigned long guessFlags, dummyFlags, pipeFlags;
128 double constantGuess, factorGuess, freqGuess, phaseGuess, slopeGuess;
129 double firstZero, lastZero;
130 unsigned long simplexFlags = 0, majorOrderFlag;
131 short columnMajorOrder = -1;
132 short lockFreq = 0;
133 short addSlope = 0;
134
136 argc = scanargs(&s_arg, argc, argv);
137 if (argc < 2 || argc > (2 + N_OPTIONS))
138 bomb(NULL, USAGE);
139
140 input = output = NULL;
141 tolerance = 1e-6;
142 verbosity = fullOutput = 0;
143 xName = yName = NULL;
144 guessFlags = 0;
145 pipeFlags = 0;
146
147 for (i_arg = 1; i_arg < argc; i_arg++) {
148 if (s_arg[i_arg].arg_type == OPTION) {
149 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
150 case SET_MAJOR_ORDER:
151 majorOrderFlag = 0;
152 s_arg[i_arg].n_items--;
153 if (s_arg[i_arg].n_items > 0 &&
154 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
155 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
156 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
157 SDDS_Bomb("invalid -majorOrder syntax/values");
158 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
159 columnMajorOrder = 1;
160 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
161 columnMajorOrder = 0;
162 break;
163 case SET_TOLERANCE:
164 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%lf", &tolerance) != 1)
165 SDDS_Bomb("incorrect -tolerance syntax");
166 break;
167 case SET_VERBOSITY:
168 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &verbosity) != 1)
169 SDDS_Bomb("incorrect -verbosity syntax");
170 break;
171 case SET_GUESS:
172 if (s_arg[i_arg].n_items < 2)
173 SDDS_Bomb("incorrect -guess syntax");
174 s_arg[i_arg].n_items -= 1;
175 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
176 "constant", SDDS_DOUBLE, &constantGuess, 1, GUESS_CONSTANT_GIVEN,
177 "factor", SDDS_DOUBLE, &factorGuess, 1, GUESS_FACTOR_GIVEN,
178 "frequency", SDDS_DOUBLE, &freqGuess, 1, GUESS_FREQ_GIVEN,
179 "phase", SDDS_DOUBLE, &phaseGuess, 1, GUESS_PHASE_GIVEN,
180 "slope", SDDS_DOUBLE, &slopeGuess, 1, GUESS_SLOPE_GIVEN, NULL))
181 SDDS_Bomb("invalid -guess syntax");
182 break;
183 case SET_COLUMNS:
184 if (s_arg[i_arg].n_items != 3)
185 SDDS_Bomb("invalid -columns syntax");
186 xName = s_arg[i_arg].list[1];
187 yName = s_arg[i_arg].list[2];
188 break;
189 case SET_FULLOUTPUT:
190 fullOutput = 1;
191 break;
192 case SET_LOCK_FREQ:
193 lockFreq = 1;
194 break;
195 case SET_ADD_SLOPE:
196 addSlope = 1;
197 n_dimen = 5;
198 break;
199 case SET_LIMITS:
200 if (s_arg[i_arg].n_items < 2)
201 SDDS_Bomb("incorrect -limits syntax");
202 s_arg[i_arg].n_items -= 1;
203 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
204 "evaluations", SDDS_LONG, &nEvalMax, 1, 0,
205 "passes", SDDS_LONG, &nPassMax, 1, 0, NULL) ||
206 nEvalMax <= 0 || nPassMax <= 0)
207 SDDS_Bomb("invalid -limits syntax");
208 break;
209 case SET_PIPE:
210 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
211 SDDS_Bomb("invalid -pipe syntax");
212 break;
213 default:
214 fprintf(stderr, "Error: Unknown or ambiguous option: %s\n", s_arg[i_arg].list[0]);
215 exit(EXIT_FAILURE);
216 break;
217 }
218 } else {
219 if (input == NULL)
220 input = s_arg[i_arg].list[0];
221 else if (output == NULL)
222 output = s_arg[i_arg].list[0];
223 else
224 SDDS_Bomb("Too many filenames provided.");
225 }
226 }
227
228 processFilenames("sddssinefit", &input, &output, pipeFlags, 0, NULL);
229
230 if (!xName || !yName)
231 SDDS_Bomb("-columns option must be specified.");
232
233 if (!SDDS_InitializeInput(&InputTable, input) ||
234 SDDS_GetColumnIndex(&InputTable, xName) < 0 ||
235 SDDS_GetColumnIndex(&InputTable, yName) < 0)
236 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
237
238 setupOutputFile(&OutputTable, &xIndex, &yIndex, &fitIndex, &residualIndex, output, fullOutput,
239 &InputTable, xName, yName, columnMajorOrder, addSlope);
240
241 fitData = residualData = NULL;
242
243 alo[0] = -(ahi[0] = DBL_MAX);
244 alo[1] = alo[2] = 0;
245 ahi[1] = ahi[2] = DBL_MAX;
246 alo[3] = -(ahi[3] = PIx2);
247 if (addSlope) {
248 alo[4] = -(ahi[4] = DBL_MAX);
249 }
250 firstZero = lastZero = 0;
251 while ((retval = SDDS_ReadPage(&InputTable)) > 0) {
252 if (!(xData = SDDS_GetColumnInDoubles(&InputTable, xName)) ||
253 !(yData = SDDS_GetColumnInDoubles(&InputTable, yName)))
254 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
255 if ((nData = SDDS_CountRowsOfInterest(&InputTable)) < 4)
256 continue;
257
258 find_min_max(&yMin, &yMax, yData, nData);
259 find_min_max(&xMin, &xMax, xData, nData);
260 zeroes = 0;
261 for (i = 1; i < nData; i++)
262 if (yData[i] * yData[i - 1] <= 0) {
263 i++;
264 if (!zeroes)
265 firstZero = (xData[i] + xData[i - 1]) / 2;
266 else
267 lastZero = (xData[i] + xData[i - 1]) / 2;
268 zeroes++;
269 }
270 a[0] = (yMin + yMax) / 2;
271 a[1] = (yMax - yMin) / 2;
272 if (!zeroes)
273 a[2] = 2 / fabs(xMax - xMin);
274 else
275 a[2] = zeroes / (2 * fabs(lastZero - firstZero));
276 a[3] = 0;
277 if (addSlope) {
278 a[4] = 0;
279 }
280 if (guessFlags & GUESS_CONSTANT_GIVEN)
281 a[0] = constantGuess;
282 if (guessFlags & GUESS_FACTOR_GIVEN)
283 a[1] = factorGuess;
284 if (guessFlags & GUESS_FREQ_GIVEN)
285 a[2] = freqGuess;
286 if (guessFlags & GUESS_PHASE_GIVEN)
287 a[3] = phaseGuess;
288 if (guessFlags & GUESS_SLOPE_GIVEN)
289 a[4] = slopeGuess;
290
291 alo[1] = a[1] / 2;
292 if (!(da[0] = a[0] * 0.1))
293 da[0] = 0.01;
294 if (!(da[1] = a[1] * 0.1))
295 da[1] = 0.01;
296 da[2] = a[2] * 0.25;
297 da[3] = 0.01;
298 if (addSlope) {
299 da[4] = 0.01;
300 }
301
302 if (lockFreq) {
303 alo[2] = ahi[2] = a[2];
304 da[2] = 0;
305 }
306
307 if (addSlope) {
308 simplexMin(&result, a, da, alo, ahi, NULL, n_dimen, -DBL_MAX, tolerance, fitFunctionWithSlope,
309 (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
310 } else {
311 simplexMin(&result, a, da, alo, ahi, NULL, n_dimen, -DBL_MAX, tolerance, fitFunction,
312 (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
313 }
314 fitData = trealloc(fitData, sizeof(*fitData) * nData);
315 residualData = trealloc(residualData, sizeof(*residualData) * nData);
316 if (addSlope) {
317 for (i = result = 0; i < nData; i++) {
318 fitData[i] = a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]) + a[4] * xData[i];
319 residualData[i] = yData[i] - fitData[i];
320 result += sqr(residualData[i]);
321 }
322 } else {
323 for (i = result = 0; i < nData; i++) {
324 fitData[i] = a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]);
325 residualData[i] = yData[i] - fitData[i];
326 result += sqr(residualData[i]);
327 }
328 }
329 rmsResidual = sqrt(result / nData);
330 if (verbosity > 1) {
331 fprintf(stderr, "RMS deviation: %.15e\n", rmsResidual);
332 fprintf(stderr, "(RMS deviation)/(largest value): %.15e\n", rmsResidual / MAX(fabs(yMin), fabs(yMax)));
333 }
334 if (verbosity > 0) {
335 if (addSlope) {
336 fprintf(stderr, "Coefficients of fit to the form y = a0 + a1*sin(2*PI*a2*x + a3) + a4*x, a = \n");
337 for (i = 0; i < 5; i++)
338 fprintf(stderr, "%.8e ", a[i]);
339 } else {
340 fprintf(stderr, "Coefficients of fit to the form y = a0 + a1*sin(2*PI*a2*x + a3), a = \n");
341 for (i = 0; i < 4; i++)
342 fprintf(stderr, "%.8e ", a[i]);
343 }
344 fprintf(stderr, "\n");
345 }
346
347 if (!SDDS_StartPage(&OutputTable, nData) ||
348 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, xData, nData, xIndex) ||
349 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, fitData, nData, fitIndex) ||
350 !SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
351 "sinefitConstant", a[0],
352 "sinefitFactor", a[1],
353 "sinefitFrequency", a[2],
354 "sinefitPhase", a[3],
355 "sinefitRmsResidual", rmsResidual,
356 NULL) ||
357 (addSlope &&
358 (!SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
359 "sinefitSlope", a[4], NULL))) ||
360 (fullOutput && (!SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yData, nData, yIndex) ||
361 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, residualData, nData, residualIndex))) ||
362 !SDDS_WritePage(&OutputTable))
363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
364 }
365
366 if (SDDS_Terminate(&InputTable) != 1) {
367 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
368 return EXIT_FAILURE;
369 }
370 if (SDDS_Terminate(&OutputTable) != 1) {
371 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
372 return EXIT_FAILURE;
373 }
374
375 return EXIT_SUCCESS;
376}
377
378void setupOutputFile(SDDS_DATASET *OutputTable, int32_t *xIndex, int32_t *yIndex, int32_t *fitIndex,
379 int32_t *residualIndex, char *output, long fullOutput, SDDS_DATASET *InputTable,
380 char *xName, char *yName, short columnMajorOrder, short addSlope) {
381 char *name, *yUnits, *description, *xUnits, *inverse_xUnits;
382 int32_t typeValue = SDDS_DOUBLE;
383 static char *residualNamePart = "Residual";
384 static char *residualDescriptionPart = "Residual of sinusoidal fit to ";
385
386 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddssinefit output", output) ||
387 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
388 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
389 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
390 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
391 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
392 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
393 exit(EXIT_FAILURE);
394 }
395 if (columnMajorOrder != -1)
396 OutputTable->layout.data_mode.column_major = columnMajorOrder;
397 else
398 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
399
400 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
401 description = tmalloc(sizeof(*description) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
402
403 if (fullOutput) {
404 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
405 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
406 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0)
407 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
408 sprintf(name, "%s%s", yName, residualNamePart);
409 sprintf(description, "%s%s", yName, residualDescriptionPart);
410 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
411 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
412 }
413
414 sprintf(name, "%sFit", yName);
415 sprintf(description, "Sinusoidal fit to %s", yName);
416 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
417 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
418
419 inverse_xUnits = makeInverseUnits(xUnits);
420
421 if (SDDS_DefineParameter(OutputTable, "sinefitConstant", NULL, yUnits, "Constant term from sinusoidal fit",
422 NULL, SDDS_DOUBLE, 0) < 0 ||
423 SDDS_DefineParameter(OutputTable, "sinefitFactor", NULL, yUnits, "Factor from sinusoidal fit",
424 NULL, SDDS_DOUBLE, 0) < 0 ||
425 SDDS_DefineParameter(OutputTable, "sinefitFrequency", NULL, inverse_xUnits, "Frequency from sinusoidal fit",
426 NULL, SDDS_DOUBLE, 0) < 0 ||
427 SDDS_DefineParameter(OutputTable, "sinefitPhase", NULL, xUnits, "Phase from sinusoidal fit",
428 NULL, SDDS_DOUBLE, 0) < 0 ||
429 SDDS_DefineParameter(OutputTable, "sinefitRmsResidual", NULL, yUnits, "RMS residual from sinusoidal fit",
430 NULL, SDDS_DOUBLE, 0) < 0)
431 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
432
433 if (addSlope) {
434 if (SDDS_DefineParameter(OutputTable, "sinefitSlope", NULL, yUnits, "Slope term added to sinusoidal fit",
435 NULL, SDDS_DOUBLE, 0) < 0)
436 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
437 }
438 if (!SDDS_WriteLayout(OutputTable))
439 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
440
441 free(name);
442 free(description);
443}
444
445char *makeInverseUnits(char *units) {
446 char *inverseUnits;
447
448 if (!units || SDDS_StringIsBlank(units))
449 return NULL;
450 inverseUnits = tmalloc(sizeof(*inverseUnits) * (strlen(units) + 5));
451
452 if (strncmp(units, "1/(", 3) == 0 && units[strlen(units) - 1] == ')') {
453 /* Special case of "1/(<unit>)" */
454 strcpy(inverseUnits, units + 3);
455 inverseUnits[strlen(inverseUnits) - 1] = '\0';
456 } else if (!strchr(units, ' ')) {
457 /* Special case of units string without spaces */
458 sprintf(inverseUnits, "1/%s", units);
459 } else {
460 /* General case */
461 sprintf(inverseUnits, "1/(%s)", units);
462 }
463
464 return inverseUnits;
465}
466
467double fitFunction(double *a, long *invalid) {
468 int64_t i;
469 double chi;
470 static double min_chi;
471
472 min_chi = DBL_MAX;
473
474 *invalid = 0;
475 for (i = chi = 0; i < nData; i++)
476 chi += sqr(yData[i] - (a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3])));
477 if (isnan(chi) || isinf(chi))
478 *invalid = 1;
479 if (verbosity > 3)
480 fprintf(stderr, "Trial: a = %e, %e, %e, %e --> chi = %e, invalid = %ld\n", a[0], a[1], a[2], a[3], chi, *invalid);
481 if (min_chi > chi) {
482 min_chi = chi;
483 fit[0] = a[0];
484 fit[1] = a[1];
485 fit[2] = a[2];
486 fit[3] = a[3];
487 if (verbosity > 2)
488 fprintf(stderr, "New best chi = %e: a = %e, %e, %e, %e\n", chi, fit[0], fit[1], fit[2], fit[3]);
489 }
490 return chi;
491}
492
493double fitFunctionWithSlope(double *a, long *invalid) {
494 int64_t i;
495 double chi;
496 static double min_chi;
497
498 min_chi = DBL_MAX;
499
500 *invalid = 0;
501 for (i = chi = 0; i < nData; i++)
502 chi += sqr(yData[i] - (a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]) + a[4] * xData[i]));
503 if (isnan(chi) || isinf(chi))
504 *invalid = 1;
505 if (verbosity > 3)
506 fprintf(stderr, "Trial: a = %e, %e, %e, %e, %e --> chi = %e, invalid = %ld\n",
507 a[0], a[1], a[2], a[3], a[4], chi, *invalid);
508 if (min_chi > chi) {
509 min_chi = chi;
510 fit[0] = a[0];
511 fit[1] = a[1];
512 fit[2] = a[2];
513 fit[3] = a[3];
514 fit[4] = a[4];
515 if (verbosity > 2)
516 fprintf(stderr, "New best chi = %e: a = %e, %e, %e, %e, %e\n",
517 chi, fit[0], fit[1], fit[2], fit[3], fit[4]);
518 }
519 return chi;
520}
521
522void report(double y, double *x, long pass, long nEval, long n_dimen) {
523 long i;
524
525 fprintf(stderr, "Pass %ld, after %ld evaluations: result = %.16e\n", pass, nEval, y);
526 fprintf(stderr, "a = ");
527 for (i = 0; i < n_dimen; i++)
528 fprintf(stderr, "%.8e ", x[i]);
529 fputc('\n', stderr);
530}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
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.
Definition SDDS_info.c:364
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *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_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_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.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.c:33
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
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.
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.
Definition simplex.c:472