SDDSlib
Loading...
Searching...
No Matches
sddsexpfit.c File Reference

Performs an exponential fit of the form y(n) = a0 + a1 * exp(a2 * x(n)) More...

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Macros

#define START_CONSTANT_GIVEN   0x0001
 
#define FIX_CONSTANT_GIVEN   (0x0001 << 3)
 
#define START_FACTOR_GIVEN   0x0002
 
#define FIX_FACTOR_GIVEN   (0x0002 << 3)
 
#define START_RATE_GIVEN   0x0004
 
#define FIX_RATE_GIVEN   (0x0004 << 3)
 
#define CLUE_GROWS   0
 
#define CLUE_DECAYS   1
 
#define N_CLUE_TYPES   2
 

Enumerations

enum  option_type {
  SET_TOLERANCE , SET_VERBOSITY , SET_CLUE , SET_GUESS ,
  SET_COLUMNS , SET_FULLOUTPUT , SET_PIPE , SET_LIMITS ,
  SET_STARTVALUES , SET_FIXVALUE , SET_AUTOOFFSET , SET_MAJOR_ORDER ,
  N_OPTIONS
}
 

Functions

double fitFunction (double *a, long *invalid)
 
void report (double res, double *a, long pass, long n_eval, long n_dimen)
 
void setupOutputFile (SDDS_DATASET *OutputTable, long *xIndex, long *yIndex, long *fitIndex, long *residualIndex, char *output, long fullOutput, SDDS_DATASET *InputTable, char *xName, char *yName, short columnMajorOrder)
 
char * makeInverseUnits (char *units)
 
int main (int argc, char **argv)
 

Variables

char * option [N_OPTIONS]
 
static char * USAGE
 
static double * xData
 
static double * yData
 
static double * syData
 
static int64_t nData
 
static double yMin
 
static double yMax
 
static double xMin
 
static double xMax
 
static double fit [3]
 
char * clue_name [N_CLUE_TYPES]
 
long verbosity
 

Detailed Description

Performs an exponential fit of the form y(n) = a0 + a1 * exp(a2 * x(n))

Overview

sddsexpfit is a command-line utility designed to perform exponential fitting on input data. It reads data from an input file, applies an exponential model to fit the data, and outputs the results to an output file. The program offers a variety of command line options to configure fit parameters, control output verbosity, and manage data processing.

Features

  • Configurable fit parameters with initial guesses and fixed values.
  • Adjustable convergence tolerance for the fitting algorithm.
  • Verbose output for detailed logging.
  • Support for specifying data columns and handling uncertainties.
  • Options to control the data processing order and output format.

Command Line Options

General Usage

sddsexpfit [<inputfile>] [<outputfile>] [options]

Options

-pipe=[input][,output] -fulloutput -columns=<x-name>,<y-name>[,ySigma=<name>] -tolerance=

-verbosity=<integer> -clue={grows|decays} -guess=<constant>,<factor>,<rate> -startValues=[constant=

][,factor=

][,rate=

] -fixValue=[constant=

][,factor=

][,rate=

] -autoOffset -limits=[evaluations=<number>][,passes=<number>] -majorOrder=row|column

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, L. Emery, R. Soliday, H. Shang, N. Kuklev

Definition in file sddsexpfit.c.

Macro Definition Documentation

◆ CLUE_DECAYS

#define CLUE_DECAYS   1

Definition at line 123 of file sddsexpfit.c.

◆ CLUE_GROWS

#define CLUE_GROWS   0

Definition at line 122 of file sddsexpfit.c.

◆ FIX_CONSTANT_GIVEN

#define FIX_CONSTANT_GIVEN   (0x0001 << 3)

Definition at line 116 of file sddsexpfit.c.

◆ FIX_FACTOR_GIVEN

#define FIX_FACTOR_GIVEN   (0x0002 << 3)

Definition at line 118 of file sddsexpfit.c.

◆ FIX_RATE_GIVEN

#define FIX_RATE_GIVEN   (0x0004 << 3)

Definition at line 120 of file sddsexpfit.c.

◆ N_CLUE_TYPES

#define N_CLUE_TYPES   2

Definition at line 124 of file sddsexpfit.c.

◆ START_CONSTANT_GIVEN

#define START_CONSTANT_GIVEN   0x0001

Definition at line 115 of file sddsexpfit.c.

◆ START_FACTOR_GIVEN

#define START_FACTOR_GIVEN   0x0002

Definition at line 117 of file sddsexpfit.c.

◆ START_RATE_GIVEN

#define START_RATE_GIVEN   0x0004

Definition at line 119 of file sddsexpfit.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 57 of file sddsexpfit.c.

57 {
58 SET_TOLERANCE,
59 SET_VERBOSITY,
60 SET_CLUE,
61 SET_GUESS,
62 SET_COLUMNS,
63 SET_FULLOUTPUT,
64 SET_PIPE,
65 SET_LIMITS,
66 SET_STARTVALUES,
67 SET_FIXVALUE,
68 SET_AUTOOFFSET,
69 SET_MAJOR_ORDER,
70 N_OPTIONS
71};

Function Documentation

◆ fitFunction()

double fitFunction ( double * a,
long * invalid )

Definition at line 498 of file sddsexpfit.c.

498 {
499 int64_t i;
500 double chi = 0.0, diff;
501 static double min_chi;
502
503 min_chi = DBL_MAX;
504
505 *invalid = 0;
506 for (i = 0; i < nData; i++) {
507 diff = yData[i] - (a[0] + a[1] * exp(a[2] * xData[i]));
508 if (syData)
509 diff /= syData[i];
510 chi += sqr(diff);
511 }
512 if (isnan(chi) || isinf(chi))
513 *invalid = 1;
514 if (verbosity > 3)
515 fprintf(stderr, "trial: a = %e, %e, %e --> chi = %e, invalid = %ld\n", a[0], a[1], a[2], chi, *invalid);
516 if (min_chi > chi) {
517 min_chi = chi;
518 fit[0] = a[0];
519 fit[1] = a[1];
520 fit[2] = a[2];
521 if (verbosity > 2)
522 fprintf(stderr, "new best chi = %e: a = %e, %e, %e\n", chi, fit[0], fit[1], fit[2]);
523 }
524 return chi;
525}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 132 of file sddsexpfit.c.

132 {
133 double tolerance, result, chiSqr, sigLevel;
134 int32_t nEvalMax = 5000, nPassMax = 100;
135 double guess[3];
136 double a[3], da[3];
137 double alo[3], ahi[3];
138 long n_dimen = 3, guessGiven, startGiven;
139 SDDS_DATASET InputTable, OutputTable;
140 SCANNED_ARG *s_arg;
141 long i_arg, clue, fullOutput;
142 int64_t i;
143 char *input, *output, *xName, *yName, *syName;
144 long xIndex, yIndex, fitIndex, residualIndex, retval;
145 double *fitData, *residualData, rmsResidual;
146 unsigned long guessFlags, pipeFlags, dummyFlags, majorOrderFlag;
147 double constantStart, factorStart, rateStart;
148 short disable[3] = {0, 0, 0};
149 short autoOffset = 0;
150 short columnMajorOrder = -1;
151
153 argc = scanargs(&s_arg, argc, argv);
154 if (argc < 2 || argc > (2 + N_OPTIONS))
155 bomb(NULL, USAGE);
156
157 input = output = NULL;
158 tolerance = 1e-6;
159 verbosity = fullOutput = guessGiven = startGiven = 0;
160 clue = -1;
161 xName = yName = syName = NULL;
162 pipeFlags = guessFlags = 0;
163 constantStart = factorStart = rateStart = 0;
164
165 for (i_arg = 1; i_arg < argc; i_arg++) {
166 if (s_arg[i_arg].arg_type == OPTION) {
167 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
168 case SET_MAJOR_ORDER:
169 majorOrderFlag = 0;
170 s_arg[i_arg].n_items--;
171 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)))
172 SDDS_Bomb("invalid -majorOrder syntax/values");
173 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
174 columnMajorOrder = 1;
175 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
176 columnMajorOrder = 0;
177 break;
178 case SET_AUTOOFFSET:
179 autoOffset = 1;
180 break;
181 case SET_TOLERANCE:
182 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%lf", &tolerance) != 1)
183 SDDS_Bomb("incorrect -tolerance syntax");
184 break;
185 case SET_VERBOSITY:
186 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &verbosity) != 1)
187 SDDS_Bomb("incorrect -verbosity syntax");
188 break;
189 case SET_CLUE:
190 if (s_arg[i_arg].n_items != 2 || (clue = match_string(s_arg[i_arg].list[1], clue_name, N_CLUE_TYPES, 0)) < 0)
191 SDDS_Bomb("incorrect -clue syntax");
192 break;
193 case SET_GUESS:
194 if (startGiven)
195 SDDS_Bomb("can't have -startValues and -guess at once");
196 if (s_arg[i_arg].n_items != 4 || sscanf(s_arg[i_arg].list[1], "%lf", guess + 0) != 1 || sscanf(s_arg[i_arg].list[2], "%lf", guess + 1) != 1 || sscanf(s_arg[i_arg].list[3], "%lf", guess + 2) != 1)
197 SDDS_Bomb("invalid -guess syntax");
198 guessGiven = 1;
199 break;
200 case SET_STARTVALUES:
201 if (s_arg[i_arg].n_items < 2)
202 SDDS_Bomb("incorrect -startValues syntax");
203 if (guessGiven)
204 SDDS_Bomb("can't have -startValues and -guess at once");
205 s_arg[i_arg].n_items -= 1;
206 dummyFlags = guessFlags;
207 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "constant", SDDS_DOUBLE, &constantStart, 1, START_CONSTANT_GIVEN, "factor", SDDS_DOUBLE, &factorStart, 1, START_FACTOR_GIVEN, "rate", SDDS_DOUBLE, &rateStart, 1, START_RATE_GIVEN, NULL))
208 SDDS_Bomb("invalid -fixValue syntax");
209 if ((dummyFlags >> 3) & (guessFlags))
210 SDDS_Bomb("can't have -fixValue and -startValue for the same item");
211 guessFlags |= dummyFlags;
212 startGiven = 1;
213 break;
214 case SET_FIXVALUE:
215 if (s_arg[i_arg].n_items < 2)
216 SDDS_Bomb("incorrect -fixValue syntax");
217 s_arg[i_arg].n_items -= 1;
218 dummyFlags = guessFlags;
219 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "constant", SDDS_DOUBLE, &constantStart, 1, FIX_CONSTANT_GIVEN, "factor", SDDS_DOUBLE, &factorStart, 1, FIX_FACTOR_GIVEN, "rate", SDDS_DOUBLE, &rateStart, 1, FIX_RATE_GIVEN, NULL))
220 SDDS_Bomb("invalid -fixValue syntax");
221 if ((dummyFlags) & (guessFlags >> 3))
222 SDDS_Bomb("can't have -fixValue and -startValue for the same item");
223 guessFlags |= dummyFlags;
224 break;
225 case SET_COLUMNS:
226 if (s_arg[i_arg].n_items != 3 && s_arg[i_arg].n_items != 4)
227 SDDS_Bomb("invalid -columns syntax");
228 xName = s_arg[i_arg].list[1];
229 yName = s_arg[i_arg].list[2];
230 s_arg[i_arg].n_items -= 3;
231 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0, "ysigma", SDDS_STRING, &syName, 1, 0, NULL))
232 SDDS_Bomb("invalid -columns syntax");
233 break;
234 case SET_FULLOUTPUT:
235 fullOutput = 1;
236 break;
237 case SET_PIPE:
238 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
239 SDDS_Bomb("invalid -pipe syntax");
240 break;
241 case SET_LIMITS:
242 if (s_arg[i_arg].n_items < 2)
243 SDDS_Bomb("incorrect -limits syntax");
244 s_arg[i_arg].n_items -= 1;
245 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "evaluations", SDDS_LONG, &nEvalMax, 1, 0, "passes", SDDS_LONG, &nPassMax, 1, 0, NULL) || nEvalMax <= 0 || nPassMax <= 0)
246 SDDS_Bomb("invalid -limits syntax");
247 break;
248 default:
249 fprintf(stderr, "error: unknown/ambiguous option: %s\n", s_arg[i_arg].list[0]);
250 exit(EXIT_FAILURE);
251 break;
252 }
253 } else {
254 if (input == NULL)
255 input = s_arg[i_arg].list[0];
256 else if (output == NULL)
257 output = s_arg[i_arg].list[0];
258 else
259 SDDS_Bomb("too many filenames");
260 }
261 }
262
263 processFilenames("sddsexpfit", &input, &output, pipeFlags, 0, NULL);
264
265 for (i = 0; i < 3; i++) {
266 if ((guessFlags >> 3) & (1 << i)) {
267 disable[i] = 1;
268 }
269 }
270
271 if (!xName || !yName)
272 SDDS_Bomb("-columns option must be given");
273
274 if (!SDDS_InitializeInput(&InputTable, input) || SDDS_GetColumnIndex(&InputTable, xName) < 0 ||
275 SDDS_GetColumnIndex(&InputTable, yName) < 0 || (syName && SDDS_GetColumnIndex(&InputTable, syName) < 0))
276 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
277
278 setupOutputFile(&OutputTable, &xIndex, &yIndex, &fitIndex, &residualIndex, output, fullOutput, &InputTable, xName, yName, columnMajorOrder);
279
280 while ((retval = SDDS_ReadPage(&InputTable)) > 0) {
281 fitData = residualData = NULL;
282 xData = yData = syData = NULL;
283 if (!(xData = SDDS_GetColumnInDoubles(&InputTable, xName)) ||
284 !(yData = SDDS_GetColumnInDoubles(&InputTable, yName)) ||
285 (syName && !(syData = SDDS_GetColumnInDoubles(&InputTable, syName))))
286 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
287 if ((nData = SDDS_CountRowsOfInterest(&InputTable)) < 4)
288 continue;
289
290 if (xData[0] > xData[nData - 1])
291 fputs("warning: data reverse-ordered", stderr);
292
293 find_min_max(&yMin, &yMax, yData, nData);
294 find_min_max(&xMin, &xMax, xData, nData);
295 for (i = 0; i < nData; i++)
296 xData[i] -= xMin;
297
298 fill_double_array(alo, 3, -DBL_MAX / 2);
299 fill_double_array(ahi, 3, DBL_MAX / 2);
300
301 if (!guessGiven) {
302 if (clue == CLUE_GROWS) {
303 a[0] = 0.9 * yData[0];
304 a[1] = yData[nData - 1] - yData[0];
305 a[2] = 1 / (xData[nData - 1] - xData[0]);
306 alo[2] = 0;
307 if (a[1] > 0)
308 alo[1] = 0;
309 else
310 ahi[1] = 0;
311 } else if (clue == CLUE_DECAYS) {
312 a[0] = 0.9 * yData[nData - 1];
313 a[1] = yData[0] - yData[nData - 1];
314 a[2] = 0;
315 ahi[2] = 0;
316 if (a[1] > 0)
317 alo[1] = 0;
318 else
319 ahi[1] = 0;
320 } else {
321 a[0] = yMin * 0.9;
322 a[1] = yMax - yMin;
323 a[2] = 0;
324 }
325 } else {
326 a[0] = guess[0];
327 a[1] = guess[1];
328 a[2] = guess[2];
329 }
330
331 if (guessFlags & (START_CONSTANT_GIVEN + FIX_CONSTANT_GIVEN))
332 a[0] = constantStart;
333 if (guessFlags & (START_FACTOR_GIVEN + FIX_FACTOR_GIVEN))
334 a[1] = factorStart;
335 if (guessFlags & (START_RATE_GIVEN + FIX_RATE_GIVEN))
336 a[2] = rateStart;
337
338 da[0] = da[1] = fabs(a[1] - a[0]) / 20.0;
339 da[2] = 0.1 / (xData[nData - 1] - xData[0]);
340 if (verbosity > 3)
341 fprintf(stderr, "starting guess: %e, %e, %e\n", a[0], a[1], a[2]);
342
343 simplexMin(&result, a, da, alo, ahi, disable, n_dimen, -DBL_MAX, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, 0);
344
345 da[0] = a[0] / 10;
346 da[1] = a[1] / 10;
347 da[2] = a[2] / 10;
348 simplexMin(&result, a, da, alo, ahi, disable, n_dimen, -DBL_MAX, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, 0);
349
350 if (!autoOffset) {
351 /* user wants the coefficients with the offset removed */
352 a[1] *= exp(-a[2] * xMin);
353 for (i = 0; i < nData; i++)
354 xData[i] += xMin;
355 }
356
357 fitData = trealloc(fitData, sizeof(*fitData) * nData);
358 residualData = trealloc(residualData, sizeof(*residualData) * nData);
359 for (i = result = 0; i < nData; i++) {
360 fitData[i] = a[0] + a[1] * exp(a[2] * xData[i]);
361 residualData[i] = yData[i] - fitData[i];
362 result += sqr(residualData[i]);
363 }
364 rmsResidual = sqrt(result / nData);
365 if (syData) {
366 for (i = chiSqr = 0; i < nData; i++)
367 chiSqr += sqr(residualData[i] / syData[i]);
368 } else {
369 double sy2;
370 sy2 = result / (nData - 3);
371 for (i = chiSqr = 0; i < nData; i++)
372 chiSqr += sqr(residualData[i]) / sy2;
373 }
374 sigLevel = ChiSqrSigLevel(chiSqr, nData - 3);
375 if (verbosity > 1) {
376 fprintf(stderr, "RMS deviation: %.15e\n", rmsResidual);
377 fprintf(stderr, "(RMS deviation)/(largest value): %.15e\n", rmsResidual / MAX(fabs(yMin), fabs(yMax)));
378 if (syData)
379 fprintf(stderr, "Significance level: %.5e\n", sigLevel);
380 }
381 if (verbosity > 0) {
382 fprintf(stderr, "coefficients of fit to the form y = a0 + a1*exp(a2*x), a = \n");
383 for (i = 0; i < 3; i++)
384 fprintf(stderr, "%.8e ", a[i]);
385 fprintf(stderr, "\n");
386 }
387
388 if (!SDDS_StartPage(&OutputTable, nData) ||
389 !SDDS_CopyParameters(&OutputTable, &InputTable) ||
390 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, xData, nData, xIndex) ||
391 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, fitData, nData, fitIndex) ||
392 !SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
393 "expfitConstant", a[0],
394 "expfitFactor", a[1],
395 "expfitRate", a[2],
396 "expfitRmsResidual", rmsResidual,
397 "expfitSigLevel", sigLevel, NULL) ||
398 (fullOutput && (!SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yData, nData, yIndex) ||
399 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, residualData, nData, residualIndex))) ||
400 !SDDS_WritePage(&OutputTable))
401 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
402 if (xData)
403 free(xData);
404 if (yData)
405 free(yData);
406 if (syData)
407 free(syData);
408 if (fitData)
409 free(fitData);
410 if (residualData)
411 free(residualData);
412 }
413 if (!SDDS_Terminate(&InputTable) || !SDDS_Terminate(&OutputTable)) {
414 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
415 exit(EXIT_FAILURE);
416 }
417 return EXIT_SUCCESS;
418}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
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_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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#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 bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
void fill_double_array(double *array, long n, double value)
Fills a double array with the specified value.
Definition fill_array.c:27
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.
double ChiSqrSigLevel(double ChiSquared0, long nu)
Computes the probability that a chi-squared variable exceeds a given value.
Definition sigLevel.c:64
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

◆ makeInverseUnits()

char * makeInverseUnits ( char * units)

Definition at line 476 of file sddsexpfit.c.

476 {
477 char *inverseUnits;
478
479 if (!units || SDDS_StringIsBlank(units))
480 return NULL;
481 inverseUnits = tmalloc(sizeof(*inverseUnits) * (strlen(units) + 5));
482
483 if (strncmp(units, "1/(", 3) == 0 && units[strlen(units) - 1] == ')') {
484 /* special case of "1/(<unit>)" */
485 strcpy(inverseUnits, units + 3);
486 inverseUnits[strlen(inverseUnits) - 1] = '\0';
487 } else if (!strchr(units, ' ')) {
488 /* special case of units string without spaces */
489 sprintf(inverseUnits, "1/%s", units);
490 } else {
491 /* general case */
492 sprintf(inverseUnits, "1/(%s)", units);
493 }
494
495 return inverseUnits;
496}
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ report()

void report ( double res,
double * a,
long pass,
long n_eval,
long n_dimen )

Definition at line 527 of file sddsexpfit.c.

527 {
528 long i;
529
530 fprintf(stderr, "Pass %ld, after %ld evaluations: result = %.16e\na = ", pass, nEval, y);
531 for (i = 0; i < n_dimen; i++)
532 fprintf(stderr, "%.8e ", x[i]);
533 fputc('\n', stderr);
534}

◆ setupOutputFile()

void setupOutputFile ( SDDS_DATASET * OutputTable,
long * xIndex,
long * yIndex,
long * fitIndex,
long * residualIndex,
char * output,
long fullOutput,
SDDS_DATASET * InputTable,
char * xName,
char * yName,
short columnMajorOrder )

Definition at line 420 of file sddsexpfit.c.

420 {
421 char *name, *yUnits, *description, *xUnits, *inverse_xUnits;
422 int32_t typeValue = SDDS_DOUBLE;
423 static char *residualNamePart = "Residual";
424 static char *residualDescriptionPart = "Residual of exponential fit to ";
425
426 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddsexpfit output", output) ||
427 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
428 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
429 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
430 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
431 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
432 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
433 exit(EXIT_FAILURE);
434 }
435
436 if (columnMajorOrder != -1)
437 OutputTable->layout.data_mode.column_major = columnMajorOrder;
438 else
439 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
440
441 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
442 description = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
443
444 if (fullOutput) {
445 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
446 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
447 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0)
448 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
449 sprintf(name, "%s%s", yName, residualNamePart);
450 sprintf(description, "%s%s", yName, residualDescriptionPart);
451 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
452 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
453 }
454
455 sprintf(name, "%sFit", yName);
456 sprintf(description, "Exponential fit to %s", yName);
457 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
458 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
459
460 inverse_xUnits = makeInverseUnits(xUnits);
461
462 if (SDDS_DefineParameter(OutputTable, "expfitConstant", NULL, yUnits, "Constant term from exponential fit",
463 NULL, SDDS_DOUBLE, 0) < 0 ||
464 SDDS_DefineParameter(OutputTable, "expfitFactor", NULL, yUnits, "Factor from exponential fit",
465 NULL, SDDS_DOUBLE, 0) < 0 ||
466 SDDS_DefineParameter(OutputTable, "expfitRate", NULL, inverse_xUnits, "Rate from exponential fit",
467 NULL, SDDS_DOUBLE, 0) < 0 ||
468 SDDS_DefineParameter(OutputTable, "expfitRmsResidual", NULL, yUnits, "RMS residual from exponential fit",
469 NULL, SDDS_DOUBLE, 0) < 0 ||
470 SDDS_DefineParameter(OutputTable, "expfitSigLevel", NULL, NULL, "Significance level from chi-squared test", NULL, SDDS_DOUBLE, 0) < 0 ||
471 !SDDS_TransferAllParameterDefinitions(OutputTable, InputTable, SDDS_TRANSFER_KEEPOLD) ||
472 !SDDS_WriteLayout(OutputTable))
473 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
474}
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_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_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.

Variable Documentation

◆ clue_name

char* clue_name[N_CLUE_TYPES]
Initial value:
= {
"grows",
"decays"
}

Definition at line 125 of file sddsexpfit.c.

125 {
126 "grows",
127 "decays"
128};

◆ fit

double fit[3]
static

Definition at line 108 of file sddsexpfit.c.

◆ nData

int64_t nData
static

Definition at line 106 of file sddsexpfit.c.

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"tolerance",
"verbosity",
"clue",
"guess",
"columns",
"fulloutput",
"pipe",
"limits",
"startvalues",
"fixvalue",
"autooffset",
"majorOrder",
}

Definition at line 73 of file sddsexpfit.c.

73 {
74 "tolerance",
75 "verbosity",
76 "clue",
77 "guess",
78 "columns",
79 "fulloutput",
80 "pipe",
81 "limits",
82 "startvalues",
83 "fixvalue",
84 "autooffset",
85 "majorOrder",
86};

◆ syData

double * syData
static

Definition at line 105 of file sddsexpfit.c.

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddsexpfit [<inputfile>] [<outputfile>]\n"
" -pipe=[input][,output]\n"
" -fulloutput\n"
" -columns=<x-name>,<y-name>[,ySigma=<name>]\n"
" -tolerance=<value>\n"
" -verbosity=<integer>\n"
" -clue={grows|decays}\n"
" -guess=<constant>,<factor>,<rate>\n"
" -startValues=[constant=<value>][,factor=<value>][,rate=<value>]\n"
" -fixValue=[constant=<value>][,factor=<value>][,rate=<value>]\n"
" -autoOffset\n"
" -limits=[evaluations=<number>][,passes=<number>]\n"
" -majorOrder=row|column\n\n"
"Performs an exponential fit of the form y = <constant> + <factor> * exp(<rate> * x).\n\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 88 of file sddsexpfit.c.

◆ verbosity

long verbosity

Definition at line 130 of file sddsexpfit.c.

◆ xData

double* xData
static

Definition at line 105 of file sddsexpfit.c.

◆ xMax

double xMax
static

Definition at line 107 of file sddsexpfit.c.

◆ xMin

double xMin
static

Definition at line 107 of file sddsexpfit.c.

◆ yData

double * yData
static

Definition at line 105 of file sddsexpfit.c.

◆ yMax

double yMax
static

Definition at line 107 of file sddsexpfit.c.

◆ yMin

double yMin
static

Definition at line 107 of file sddsexpfit.c.