52#include <gsl/gsl_bspline.h>
53#include <gsl/gsl_multifit.h>
54#include <gsl/gsl_rng.h>
55#include <gsl/gsl_randist.h>
56#include <gsl/gsl_statistics.h>
57#include <gsl/gsl_version.h>
59void makeSubstitutions(
char *buffer1,
char *buffer2,
char *
template,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol);
60char *changeInformation(
SDDS_DATASET *SDDSout,
char *name,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol,
char **
template,
char *newUnits);
61char **makeCoefficientUnits(
SDDS_DATASET *SDDSout,
char *xName,
char *yName,
long int order,
long coeffs);
63 SDDS_DATASET *SDDSin,
char *input,
char *xName,
char **yNames,
char *xSigmaName,
64 char **ySigmaNames,
long sigmasValid,
long int order,
long coeffs,
long breaks,
65 long numCols,
long copyParameters);
66void checkInputFile(
SDDS_DATASET *SDDSin,
char *xName,
char **yNames,
char *xSigmaName,
char **ySigmaNames,
long numYNames);
67long coefficient_index(
long int order,
long coeffs,
long order_of_interest);
69char **ResolveColumnNames(
SDDS_DATASET *SDDSin,
char **wildcardList,
long length, int32_t *numYNames);
70char **GenerateYSigmaNames(
char *controlString,
char **yNames,
long numYNames);
71void RemoveElementFromStringArray(
char **array,
long index,
long length);
72char **RemoveNonNumericColumnsFromNameArray(
SDDS_DATASET *SDDSin,
char **columns, int32_t *numColumns);
74int print_matrix(FILE *f,
const gsl_matrix *m);
103char *option[N_OPTIONS] = {
129 "Usage: sddssplinefit [options] [<inputfile>] [<outputfile>]\n"
131 " -pipe=[input][,output] Use standard input and/or output for data.\n"
132 " -independent=<xName> Specify the name of the independent data column to use.\n"
133 " -dependent=<yName1-wildcard>[,<yName2-wildcard>...] Specify names of dependent data columns to use, supporting wildcards and separated by commas.\n"
134 " -sigmaIndependent=<xSigma> Specify the name of the independent sigma values column.\n"
135 " -sigmaDependent=<ySigmaFormatString> Specify a printf-style control string to generate dependent sigma column names from independent variable names (e.g., %sSigma).\n"
136 " -order=<number> Define the order of the spline. Default is 4.\n"
137 " -coefficients=<number> Set the number of coefficients. Specify either coefficients or breakpoints, not both.\n"
138 " -breakpoints=<number> Set the number of breakpoints. Condition enforced: breakpoints = coefficients + 2 - order.\n"
139 " -xOffset=<value> Define the desired value of x to fit about.\n"
140 " -xFactor=<value> Define the factor to multiply x values by before fitting.\n"
141 " -sigmas=<value>,{absolute | fractional} Specify absolute or fractional sigma for all points.\n"
142 " -modifySigmas Modify the y sigmas using the x sigmas and an initial fit.\n"
143 " -generateSigmas[={keepLargest, keepSmallest}] Generate y sigmas from the RMS deviation of an initial fit. Optionally keep the sigmas from the data if larger/smaller than the RMS deviation.\n"
144 " -sparse=<interval> Specify an integer interval at which to sample data.\n"
145 " -range=<lower>,<upper>[,fitOnly] Define the range of the independent variable over which to perform the fit and evaluation. If 'fitOnly' is given, the fit is compared to data over the original range.\n"
146 " -normalize[=<termNumber>] Normalize so that the specified term is unity.\n"
147 " -verbose Enable verbose output for additional information.\n"
148 " -evaluate=<filename>[,begin=<value>][,end=<value>][,number=<integer>][,derivatives=<order>][,basis] \n"
149 " Evaluate the spline fit and optionally compute derivatives and provide basis functions.\n"
150 " -infoFile=<filename> Specify a file to output fit information.\n"
151 " -copyParameters Copy parameters from the input file to the output file.\n\n"
152 "Program by Louis Emery, started with Michael Borland polynomial fit program (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
154static char *additional_help =
"\n\
155sddssplinefit performs spline fits of the form y = SUM(i){ A[i] * B(x-x_offset, i)}, where B(x,i) is the ith basis\n\
156spline function evaluated at x. Internally, sddssplinefit computes the A[i] coefficients, writes the fitted y values to the output file,\n\
157and estimates the errors in these values.\n";
159static char *additional_help2 =
"\n\
160 -independent Specify the name of the independent data column to use.\n\
161 -dependent Specify the names of dependent data columns to use, supporting wildcards and separated by commas.\n\
162 -sigmaIndependent Specify the name of the independent sigma values column.\n\
163 -sigmaDependent Specify a printf-style control string to generate dependent sigma column names from independent variable names (e.g., %sSigma).\n\
164 -order Define the order of the spline. Default is 4.\n\
165 -coefficients Set the number of coefficients. Specify either coefficients or breakpoints, not both.\n\
166 -breakpoints Set the number of breakpoints. Condition enforced: breakpoints = coefficients + 2 - order.\n\
167 -xOffset Define the desired value of x to fit about.\n\
168 -xFactor Define the factor to multiply x values by before fitting.\n\
169 -sigmas Specify absolute or fractional sigma for all points.\n\
170 -modifySigmas Modify the y sigmas using the x sigmas and an initial fit.\n\
171 -generateSigmas Generate y sigmas from the RMS deviation of an initial fit.\n\
172 Optionally keep the sigmas from the data if larger/smaller than the RMS deviation.\n\
173 -sparse Specify an integer interval at which to sample data.\n\
174 -range Define the range of the independent variable over which to perform the fit and evaluation.\n\
175 If 'fitOnly' is given, the fit is compared to data over the original range.\n\
176 -normalize Normalize so that the specified term is unity.\n\
177 -verbose Enable verbose output for additional information.\n\
178 -evaluate Evaluate the spline fit and optionally compute derivatives and provide basis functions.\n\
179 -infoFile Specify a file to output fit information.\n\
180 -copyParameters Copy parameters from the input file to the output file.\n\n";
182#define ABSOLUTE_SIGMAS 0
183#define FRACTIONAL_SIGMAS 1
184#define N_SIGMAS_OPTIONS 2
185char *sigmas_options[N_SIGMAS_OPTIONS] = {
"absolute",
"fractional"};
187#define FLGS_GENERATESIGMAS 1
188#define FLGS_KEEPLARGEST 2
189#define FLGS_KEEPSMALLEST 4
191#define REVPOW_ACTIVE 0x0001
192#define REVPOW_VERBOSE 0x0002
194static long iOffset = -1, iOffsetO = -1, iFactor = -1, iFactorO = -1;
195static long *iChiSq = NULL, *iChiSqO = NULL, *iRmsResidual = NULL, *iRmsResidualO = NULL, *iSigLevel = NULL, *iSigLevelO = NULL;
196static long *iFitIsValid = NULL, *iFitIsValidO = NULL;
199static long ix = -1, ixSigma = -1;
200static long *iy = NULL, *iySigma = NULL;
201static long *iFit = NULL, *iResidual = NULL;
203static long *iCoefficient = NULL, *iCoefficientSigma = NULL, *iCoefficientUnits = NULL;
205static char *xSymbol, **ySymbols;
207#define EVAL_BEGIN_GIVEN 0x0001U
208#define EVAL_END_GIVEN 0x0002U
209#define EVAL_NUMBER_GIVEN 0x0004U
210#define EVAL_DERIVATIVES 0x0008U
211#define EVAL_PROVIDEBASIS 0x0010U
213#define MAX_Y_SIGMA_NAME_SIZE 1024
219 int64_t number, nderiv;
223 char ***yDerivName, ***yDerivUnits;
225 gsl_bspline_workspace *bw;
228void makeEvaluationTable(
EVAL_PARAMETERS *evalParameters,
double *x, int64_t points, gsl_vector *B,
229 gsl_matrix *cov, gsl_vector *c,
char *xName,
char **yName,
long yNames,
long iYName,
long int order);
231int main(
int argc,
char **argv) {
232 double **y = NULL, **yFit = NULL, **sy = NULL, **diff = NULL;
233 double *x = NULL, *sx = NULL;
234 double xOffset, xScaleFactor;
235 double *xOrig = NULL, **yOrig = NULL, **yFitOrig = NULL, *sxOrig = NULL, **syOrig = NULL, **sy0 = NULL;
236 long coeffs, breaks, normTerm, ySigmasValid;
237 long orderGiven, coeffsGiven, breaksGiven;
238 int64_t i, j, points, pointsOrig;
240 long sigmasMode, sparseInterval;
241 double *chi = NULL, xLow, xHigh, *rmsResidual = NULL;
242 char *xName = NULL, *yName = NULL, **yNames = NULL, *xSigmaName = NULL;
243 char **ySigmaNames = NULL, *ySigmaControlString = NULL;
244 char *input = NULL, *output = NULL;
246 long *isFit = NULL, iArg, modifySigmas;
247 long generateSigmas, verbose, ignoreSigmas;
248 long outputInitialized, copyParameters = 0;
251 double xMin, xMax, revpowThreshold;
252 double rms_average(
double *d_x, int64_t d_n);
253 char *infoFile = NULL;
254 unsigned long pipeFlags, reviseOrders;
256 long rangeFitOnly = 0;
259 long cloDependentIndex = -1, numDependentItems;
263 gsl_bspline_workspace *bw;
265 gsl_vector *c, *yGsl, *wGsl;
267 gsl_multifit_linear_workspace *mw;
268 long degreesOfFreedom;
269 double totalSumSquare, Rsq;
272 argc =
scanargs(&s_arg, argc, argv);
273 if (argc < 2 || argc > (3 + N_OPTIONS)) {
274 fprintf(stderr,
"usage: %s\n", USAGE);
275 fprintf(stderr,
"%s%s", additional_help, additional_help2);
279 input = output = NULL;
280 xName = yName = xSigmaName = ySigmaControlString = NULL;
281 yNames = ySigmaNames = NULL;
282 numDependentItems = 0;
283 modifySigmas = reviseOrders = 0;
291 verbose = ignoreSigmas = 0;
296 evalParameters.file = NULL;
302 for (iArg = 1; iArg < argc; iArg++) {
303 if (s_arg[iArg].arg_type == OPTION) {
304 switch (
match_string(s_arg[iArg].list[0], option, N_OPTIONS, 0)) {
305 case CLO_MODIFYSIGMAS:
309 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &order) != 1)
313 case CLO_COEFFICIENTS:
314 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &coeffs) != 1)
315 SDDS_Bomb(
"invalid -coefficients syntax");
318 case CLO_BREAKPOINTS:
319 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &breaks) != 1)
320 SDDS_Bomb(
"invalid -breakpoints syntax");
325 if ((s_arg[iArg].n_items != 3 && s_arg[iArg].n_items != 4) ||
326 1 != sscanf(s_arg[iArg].list[1],
"%lf", &xMin) ||
327 1 != sscanf(s_arg[iArg].list[2],
"%lf", &xMax) ||
330 if (s_arg[iArg].n_items == 4) {
331 if (strncmp(
str_tolower(s_arg[iArg].list[3]),
"fitonly", strlen(s_arg[iArg].list[3])) == 0) {
337 case CLO_GENERATESIGMAS:
338 generateSigmas = FLGS_GENERATESIGMAS;
339 if (s_arg[iArg].n_items > 1) {
340 if (s_arg[iArg].n_items != 2)
341 SDDS_Bomb(
"incorrect -generateSigmas syntax");
342 if (strncmp(s_arg[iArg].list[1],
"keepsmallest", strlen(s_arg[iArg].list[1])) == 0)
343 generateSigmas |= FLGS_KEEPSMALLEST;
344 if (strncmp(s_arg[iArg].list[1],
"keeplargest", strlen(s_arg[iArg].list[1])) == 0)
345 generateSigmas |= FLGS_KEEPLARGEST;
346 if ((generateSigmas & FLGS_KEEPSMALLEST) && (generateSigmas & FLGS_KEEPLARGEST))
347 SDDS_Bomb(
"ambiguous -generateSigmas syntax");
351 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%lf", &xOffset) != 1)
355 if (s_arg[iArg].n_items != 3)
357 if (sscanf(s_arg[iArg].list[1],
"%lf", &sigmas) != 1)
358 SDDS_Bomb(
"couldn't scan value for -sigmas");
359 if ((sigmasMode =
match_string(s_arg[iArg].list[2], sigmas_options, N_SIGMAS_OPTIONS, 0)) < 0)
363 if (s_arg[iArg].n_items != 2)
365 if (sscanf(s_arg[iArg].list[1],
"%ld", &sparseInterval) != 1)
366 SDDS_Bomb(
"couldn't scan value for -sparse");
367 if (sparseInterval < 1)
375 if (s_arg[iArg].n_items > 2 ||
376 (s_arg[iArg].n_items == 2 && sscanf(s_arg[iArg].list[1],
"%ld", &normTerm) != 1) ||
380 case CLO_REVISEORDERS:
381 revpowThreshold = 0.1;
382 s_arg[iArg].n_items -= 1;
383 if (!
scanItemList(&reviseOrders, s_arg[iArg].list + 1, &s_arg[iArg].n_items, 0,
385 "verbose", -1, NULL, 1, REVPOW_VERBOSE, NULL))
386 SDDS_Bomb(
"invalid -reviseOrders syntax");
387 s_arg[iArg].n_items += 1;
388 reviseOrders |= REVPOW_ACTIVE;
389 revpowThreshold = fabs(revpowThreshold);
392 if (s_arg[iArg].n_items != 2 ||
393 sscanf(s_arg[iArg].list[1],
"%lf", &xScaleFactor) != 1 || xScaleFactor == 0)
396 case CLO_INDEPENDENT:
397 if (s_arg[iArg].n_items != 2)
398 SDDS_Bomb(
"invalid -independent syntax");
399 xName = s_arg[iArg].list[1];
402 numDependentItems = s_arg[iArg].n_items - 1;
403 cloDependentIndex = iArg;
404 if (numDependentItems < 1)
407 case CLO_SIGMAINDEPENDENT:
408 if (s_arg[iArg].n_items != 2)
409 SDDS_Bomb(
"invalid -sigmaIndependent syntax");
410 xSigmaName = s_arg[iArg].list[1];
412 case CLO_SIGMADEPENDENT:
413 if (s_arg[iArg].n_items != 2)
414 SDDS_Bomb(
"invalid -sigmaDependent syntax");
415 ySigmaControlString = s_arg[iArg].list[1];
418 if (!
processPipeOption(s_arg[iArg].list + 1, s_arg[iArg].n_items - 1, &pipeFlags))
422 if (s_arg[iArg].n_items != 2)
424 infoFile = s_arg[iArg].list[1];
427 if (s_arg[iArg].n_items < 2)
429 evalParameters.file = s_arg[iArg].list[1];
430 s_arg[iArg].n_items -= 2;
431 s_arg[iArg].list += 2;
432 evalParameters.begin = 0;
433 evalParameters.end = 0;
434 evalParameters.nderiv = 0;
435 evalParameters.number = 0;
436 if (!
scanItemList(&evalParameters.flags, s_arg[iArg].list, &s_arg[iArg].n_items, 0,
437 "begin",
SDDS_DOUBLE, &evalParameters.begin, 1, EVAL_BEGIN_GIVEN,
438 "end",
SDDS_DOUBLE, &evalParameters.end, 1, EVAL_END_GIVEN,
439 "derivatives",
SDDS_LONG64, &evalParameters.nderiv, 1, EVAL_DERIVATIVES,
440 "basis", -1, NULL, 0, EVAL_PROVIDEBASIS,
441 "number",
SDDS_LONG64, &evalParameters.number, 1, EVAL_NUMBER_GIVEN, NULL))
443 s_arg[iArg].n_items += 2;
444 s_arg[iArg].list -= 2;
446 case CLO_COPYPARAMETERS:
450 bomb(
"unknown switch", USAGE);
455 input = s_arg[iArg].list[0];
456 else if (output == NULL)
457 output = s_arg[iArg].list[0];
466 breaks = coeffs + 2 - order;
468 coeffs = breaks - 2 + order;
469 if (breaksGiven && coeffsGiven)
470 SDDS_Bomb(
"You must specify only one of breakpoints or coefficients");
474 if (!xName || !numDependentItems)
475 SDDS_Bomb(
"you must specify a column name for x and y");
476 if (modifySigmas && !xSigmaName)
477 SDDS_Bomb(
"you must specify x sigmas with -modifySigmas");
478 if (generateSigmas) {
480 SDDS_Bomb(
"you can't specify both -generateSigmas and -modifySigmas");
482 if (ySigmaControlString) {
483 if (sigmasMode != -1)
484 SDDS_Bomb(
"you can't specify both -sigmas and a y sigma name");
487 if (sigmasMode != -1 || generateSigmas || ySigmaControlString || modifySigmas)
492 outputInitialized = 0;
493 yNames = ResolveColumnNames(&SDDSin, s_arg[cloDependentIndex].list + 1, numDependentItems, &numYNames);
494 if (ySigmaControlString != NULL)
495 ySigmaNames = GenerateYSigmaNames(ySigmaControlString, yNames, numYNames);
497 checkInputFile(&SDDSin, xName, yNames, xSigmaName, ySigmaNames, numYNames);
498 sy0 =
tmalloc(
sizeof(
double *) * numYNames);
499 y =
tmalloc(
sizeof(
double *) * numYNames);
500 yFit =
tmalloc(
sizeof(
double *) * numYNames);
501 sy =
tmalloc(
sizeof(
double *) * numYNames);
502 isFit =
tmalloc(
sizeof(
long) * numYNames);
503 chi =
tmalloc(
sizeof(
double) * numYNames);
504 iCoefficient =
tmalloc(
sizeof(
long) * numYNames);
505 iCoefficientSigma =
tmalloc(
sizeof(
long) * numYNames);
506 iCoefficientUnits =
tmalloc(
sizeof(
long) * numYNames);
514 fprintf(stdout,
"number of points %" PRId64
"\n", points);
516 fprintf(stderr,
"error: unable to read column %s\n", xName);
519 for (i = 0; i < numYNames; i++) {
521 fprintf(stderr,
"error: unable to read column %s\n", yNames[i]);
527 fprintf(stderr,
"error: unable to read column %s\n", xSigmaName);
530 for (colIndex = 0; colIndex < numYNames; colIndex++) {
531 sy0[colIndex] =
tmalloc(
sizeof(
double) * points);
532 yFit[colIndex] =
tmalloc(
sizeof(
double) * points);
536 for (i = 0; i < numYNames; i++) {
538 fprintf(stderr,
"error: unable to read column %s\n", ySigmaNames[i]);
544 if (xMin != xMax || sparseInterval != 1) {
545 xOrig =
tmalloc(
sizeof(*xOrig) * points);
546 yOrig =
tmalloc(
sizeof(*yOrig) * numYNames);
547 yFitOrig =
tmalloc(
sizeof(*yFitOrig) * numYNames);
548 for (colIndex = 0; colIndex < numYNames; colIndex++) {
550 fprintf(stdout,
"Setting up a separate array for range or sparsing for column %s because of range option ...\n", yNames[colIndex]);
551 yOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
552 yFitOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
555 sxOrig =
tmalloc(
sizeof(*sxOrig) * points);
557 syOrig =
tmalloc(
sizeof(*syOrig) * numYNames);
558 for (colIndex = 0; colIndex < numYNames; colIndex++)
559 syOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
562 for (i = j = 0; i < points; i++) {
566 for (colIndex = 0; colIndex < numYNames; colIndex++) {
567 yOrig[colIndex][i] = y[colIndex][i];
569 syOrig[colIndex][i] = sy0[colIndex][i];
573 for (i = j = 0; i < points; i++) {
574 if (xOrig[i] <= xMax && xOrig[i] >= xMin) {
576 for (colIndex = 0; colIndex < numYNames; colIndex++) {
577 y[colIndex][j] = yOrig[colIndex][i];
579 sy0[colIndex][j] = syOrig[colIndex][i];
588 if (sparseInterval != 1) {
589 for (i = j = 0; i < points; i++) {
590 if (i % sparseInterval == 0) {
592 for (colIndex = 0; colIndex < numYNames; colIndex++) {
593 y[colIndex][j] = y[colIndex][i];
595 sy0[colIndex][j] = sy0[colIndex][i];
615 fprintf(stdout,
"Range: xLow %lf; xHigh %lf; points %" PRId64
"\n", xLow, xHigh, points);
616 if (sigmasMode == ABSOLUTE_SIGMAS) {
617 for (colIndex = 0; colIndex < numYNames; colIndex++) {
618 for (i = 0; i < points; i++)
619 sy0[colIndex][i] = sigmas;
620 if (sy0[colIndex] != syOrig[colIndex])
621 for (i = 0; i < pointsOrig; i++)
622 syOrig[colIndex][i] = sigmas;
624 }
else if (sigmasMode == FRACTIONAL_SIGMAS) {
625 for (colIndex = 0; colIndex < numYNames; colIndex++) {
626 for (i = 0; i < points; i++)
627 sy0[colIndex][i] = sigmas * fabs(y[colIndex][i]);
628 if (sy0[colIndex] != syOrig[colIndex])
629 for (i = 0; i < pointsOrig; i++)
630 syOrig[colIndex][i] = fabs(yOrig[colIndex][i]) * sigmas;
634 if (!ySigmasValid || generateSigmas)
635 for (colIndex = 0; colIndex < numYNames; colIndex++) {
636 for (i = 0; i < points; i++)
637 sy0[colIndex][i] = 1;
640 for (i = 0; i < points; i++)
641 for (colIndex = 0; colIndex < numYNames; colIndex++) {
642 if (sy0[colIndex][i] == 0)
643 SDDS_Bomb(
"y sigma = 0 for one or more points.");
646 diff =
tmalloc(
sizeof(*diff) * numYNames);
647 sy =
tmalloc(
sizeof(*sy) * numYNames);
648 for (colIndex = 0; colIndex < numYNames; colIndex++) {
649 diff[colIndex] =
tmalloc(
sizeof(
double) * points);
650 sy[colIndex] =
tmalloc(
sizeof(
double) * points);
653 for (i = 0; i < points; i++) {
654 for (colIndex = 0; colIndex < numYNames; colIndex++)
655 sy[colIndex][i] = sy0[colIndex][i];
663 bw = gsl_bspline_alloc(order, breaks);
664 B = gsl_vector_alloc(coeffs);
667 X = gsl_matrix_alloc(points, coeffs);
668 c = gsl_vector_alloc(coeffs);
669 yGsl = gsl_vector_alloc(points);
670 wGsl = gsl_vector_alloc(points);
671 cov = gsl_matrix_alloc(coeffs, coeffs);
672 mw = gsl_multifit_linear_alloc(points, coeffs);
673 degreesOfFreedom = points - coeffs;
675 fprintf(stdout,
"Order %ld\ncoefficients %ld\nbreak points %ld\n", order, coeffs, breaks);
676 if (generateSigmas || modifySigmas)
677 fprintf(stderr,
"generate sigmas or modify sigmas are not a feature in spline fitting.\n");
679 if (reviseOrders & REVPOW_ACTIVE)
680 fprintf(stderr,
"revise orders is not a feature in spline fitting.\n");
682 if (!outputInitialized) {
683 initializeOutputFile(&SDDSout, &SDDSoutInfo, output, infoFile, &SDDSin, input, xName, yNames,
684 xSigmaName, ySigmaNames, ySigmasValid, order, coeffs, breaks, numYNames, copyParameters);
686 outputInitialized = 1;
688 if (evalParameters.file) {
690 if (evalParameters.nderiv >= order) {
691 evalParameters.nderiv = order - 1;
693 fprintf(stderr,
"Spline derivative order reduced to %" PRId64
" (i.e. order - 1)\n", evalParameters.nderiv);
695 evalParameters.bw = bw;
696 setupEvaluationFile(&evalParameters, xName, yNames, numYNames, &SDDSin);
700 rmsResidual =
tmalloc(
sizeof(
double) * numYNames);
702 if (outputInitialized) {
703 if (!
SDDS_StartPage(&SDDSout, rangeFitOnly ? pointsOrig : points) ||
706 if (copyParameters) {
713 if (!
SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_INDEX, rangeFitOnly ? xOrig : x, rangeFitOnly ? pointsOrig : points, ix))
715 for (colIndex = 0; colIndex < numYNames; colIndex++) {
718 for (i = 0; i < points; i++) {
719 gsl_vector_set(yGsl, i, y[colIndex][i]);
721 gsl_vector_set(wGsl, i, 1.0 /
ipower(sy[colIndex][i], 2));
725 gsl_bspline_knots_uniform(xLow, xHigh, bw);
731 for (i = 0; i < points; ++i) {
734 gsl_bspline_eval(x[i], B, bw);
736 for (j = 0; j < coeffs; ++j) {
737 Bj = gsl_vector_get(B, j);
739 gsl_matrix_set(X, i, j, Bj);
744 fprintf(stderr,
"X matrix %s:\n", yNames[colIndex]);
745 print_matrix(stderr, X);
748 gsl_multifit_wlinear(X, wGsl, yGsl, c, cov, &chi[colIndex], mw);
750 fprintf(stdout,
"conventionally-defined chi = sum( sqr(diff) * weight): %e\n", chi[colIndex]);
753 fprintf(stderr,
"Covariance matrix for %s:\n", yNames[colIndex]);
754 print_matrix(stderr, cov);
757 totalSumSquare = gsl_stats_wtss(wGsl->data, 1, yGsl->data, 1, yGsl->size);
758 Rsq = 1.0 - chi[colIndex] / totalSumSquare;
760 fprintf(stdout,
"(reduced) chisq/dof = %e, Rsq = %f\n", chi[colIndex] / degreesOfFreedom, Rsq);
763 for (i = 0; i < points; i++) {
764 gsl_bspline_eval(x[i], B, bw);
766 gsl_multifit_linear_est(B, c, cov, &yFit[colIndex][i], &y_err);
769 for (i = 0; i < pointsOrig; i++) {
770 diff[colIndex][i] = yOrig[colIndex][i] - yFitOrig[colIndex][i];
772 rmsResidual[colIndex] = rms_average(diff[colIndex], points);
779 for (i = 0; i < points; i++) {
780 diff[colIndex][i] = y[colIndex][i] - yFit[colIndex][i];
782 rmsResidual[colIndex] = rms_average(diff[colIndex], points);
792 if (evalParameters.file) {
793 evalParameters.bw = bw;
794 makeEvaluationTable(&evalParameters, x, points, B, cov, c, xName, yNames, numYNames, colIndex, order);
799 !
SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_INDEX, rangeFitOnly ? sxOrig : sx, rangeFitOnly ? pointsOrig : points, ixSigma))
804 Indices = malloc(
sizeof(*Indices) * coeffs);
805 for (i = 0; i < coeffs; i++)
807 if (!
SDDS_SetColumn(&SDDSoutInfo, SDDS_SET_BY_NAME, Indices, coeffs,
"Index"))
811 for (colIndex = 0; colIndex < numYNames; colIndex++) {
812 if (ySigmasValid && iySigma[colIndex] != -1 &&
814 rangeFitOnly ? pointsOrig : points, iySigma[colIndex]))
822 iRmsResidual[colIndex], rmsResidual[colIndex],
823 iChiSq[colIndex], (chi[colIndex] / degreesOfFreedom),
824 iSigLevel[colIndex],
ChiSqrSigLevel(chi[colIndex], points - coeffs),
825 iOffset, xOffset, iFactor, xScaleFactor, iFitIsValid[colIndex], isFit[colIndex] ?
'y' :
'n', -1))
831 iRmsResidualO[colIndex], rmsResidual[colIndex],
832 iChiSqO[colIndex], (chi[colIndex] / degreesOfFreedom),
833 iSigLevelO[colIndex],
ChiSqrSigLevel(chi[colIndex], points - coeffs),
834 iOffsetO, xOffset, iFactorO, xScaleFactor, iFitIsValidO[colIndex], isFit[colIndex] ?
'y' :
'n', -1))
848 for (colIndex = 0; colIndex < numYNames; colIndex++) {
849 free(diff[colIndex]);
851 if (yOrig[colIndex] != y[colIndex])
852 free(yOrig[colIndex]);
853 if (syOrig && sy0 && syOrig[colIndex] != sy0[colIndex])
854 free(syOrig[colIndex]);
856 if (sy0 && sy0[colIndex])
858 if (yFit && yFit[colIndex])
859 free(yFit[colIndex]);
861 gsl_bspline_free(bw);
864 gsl_vector_free(yGsl);
865 gsl_vector_free(wGsl);
867 gsl_matrix_free(cov);
868 gsl_multifit_linear_free(mw);
873 if (outputInitialized) {
882 if (evalParameters.file) {
896void RemoveElementFromStringArray(
char **array,
long index,
long length) {
899 for (lh = index; lh < length - 1; lh++)
900 array[lh] = array[lh + 1];
903char **RemoveNonNumericColumnsFromNameArray(
SDDS_DATASET *SDDSin,
char **columns, int32_t *numColumns) {
904 long i, numNumericColumns = *numColumns;
906 for (i = 0; i < *numColumns; i++) {
908 printf(
"Removing %s because not a numeric type.", columns[i]);
909 RemoveElementFromStringArray(columns, i, *numColumns);
914 *numColumns = numNumericColumns;
918char **ResolveColumnNames(
SDDS_DATASET *SDDSin,
char **wildcardList,
long length, int32_t *numYNames) {
924 for (i = 0; i < length; i++) {
929 bomb(
"Error matching columns in ResolveColumnNames: No matches.", NULL);
931 result = RemoveNonNumericColumnsFromNameArray(SDDSin, result, numYNames);
935char **GenerateYSigmaNames(
char *controlString,
char **yNames,
long numYNames) {
937 char **result, sigmaName[MAX_Y_SIGMA_NAME_SIZE];
939 result =
tmalloc(
sizeof(
char *) * numYNames);
940 for (i = 0; i < numYNames; i++) {
941 sprintf(sigmaName, controlString, yNames[i]);
942 nameLength = strlen(sigmaName);
943 result[i] =
tmalloc(
sizeof(
char) * (nameLength + 1));
944 strcpy(result[i], sigmaName);
949double rms_average(
double *x, int64_t n) {
953 for (i = sum2 = 0; i < n; i++)
956 return (sqrt(sum2 / n));
959void checkInputFile(
SDDS_DATASET *SDDSin,
char *xName,
char **yNames,
char *xSigmaName,
char **ySigmaNames,
long numYNames) {
964 SDDS_Bomb(
"x column doesn't exist or is nonnumeric");
970 if (xSigmaName && !(ptr =
SDDS_FindColumn(SDDSin, FIND_NUMERIC_TYPE, xSigmaName, NULL)))
971 SDDS_Bomb(
"x sigma column doesn't exist or is nonnumeric");
976 for (i = 0; i < numYNames; i++) {
978 if (!(ptr =
SDDS_FindColumn(SDDSin, FIND_NUMERIC_TYPE, ySigmaNames[i], NULL)))
979 SDDS_Bomb(
"y sigma column doesn't exist or is nonnumeric");
987 SDDS_DATASET *SDDSin,
char *input,
char *xName,
char **yNames,
char *xSigmaName,
988 char **ySigmaNames,
long sigmasValid,
long int order,
long coeffs,
long breakpoints,
989 long numCols,
long copyParameters) {
990 char buffer[SDDS_MAXLINE], buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], buffer3[SDDS_MAXLINE];
991 char *xUnits, *yUnits;
998 ySymbols =
tmalloc(
sizeof(
char *) * numCols);
999 iChiSq =
tmalloc(
sizeof(
long) * numCols);
1000 iChiSqO =
tmalloc(
sizeof(
long) * numCols);
1001 iRmsResidual =
tmalloc(
sizeof(
long) * numCols);
1002 iRmsResidualO =
tmalloc(
sizeof(
long) * numCols);
1003 iSigLevel =
tmalloc(
sizeof(
long) * numCols);
1004 iSigLevelO =
tmalloc(
sizeof(
long) * numCols);
1005 iFitIsValid =
tmalloc(
sizeof(
long) * numCols);
1006 iFitIsValidO =
tmalloc(
sizeof(
long) * numCols);
1007 iy =
tmalloc(
sizeof(
long) * numCols);
1008 iySigma =
tmalloc(
sizeof(
long) * numCols);
1009 iFit =
tmalloc(
sizeof(
long) * numCols);
1010 iResidual =
tmalloc(
sizeof(
long) * numCols);
1012 for (colIndex = 0; colIndex < numCols; colIndex++) {
1013 ySymbols[colIndex] = NULL;
1015 iChiSq[colIndex] = -1;
1016 iChiSqO[colIndex] = -1;
1017 iRmsResidual[colIndex] = -1;
1018 iRmsResidualO[colIndex] = -1;
1019 iSigLevel[colIndex] = -1;
1020 iSigLevelO[colIndex] = -1;
1021 iFitIsValid[colIndex] = -1;
1022 iFitIsValidO[colIndex] = -1;
1024 iySigma[colIndex] = -1;
1025 iFit[colIndex] = -1;
1026 iResidual[colIndex] = -1;
1029 if (!
SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL,
"sddssplinefit output: fitted data", output) ||
1033 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1035 for (colIndex = 0; colIndex < numCols; colIndex++) {
1039 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1043 for (colIndex = 0; colIndex < numCols; colIndex++)
1045 ySymbols[colIndex] = yNames[colIndex];
1047 for (colIndex = 0; colIndex < numCols; colIndex++) {
1055 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1057 for (colIndex = 0; colIndex < numCols; colIndex++) {
1058 sprintf(buffer,
"%sFit", yNames[colIndex]);
1059 sprintf(buffer1,
"Fit[%s]", ySymbols[colIndex]);
1062 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1064 SDDS_Bomb(
"unable to get index of just-defined fit output column");
1066 sprintf(buffer,
"%sResidual", yNames[colIndex]);
1067 sprintf(buffer1,
"Residual[%s]", ySymbols[colIndex]);
1070 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1072 SDDS_Bomb(
"unable to get index of just-defined residual output column");
1074 if (sigmasValid && !ySigmaNames) {
1075 sprintf(buffer,
"%sSigma", yNames[colIndex]);
1077 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1080 sprintf(buffer1,
"Sigma[%s]", ySymbols[colIndex]);
1082 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1087 if (outputInfo && !
SDDS_InitializeOutput(SDDSoutInfo, SDDS_BINARY, 0, NULL,
"sddsspline output: fit information", outputInfo))
1088 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1093 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1096 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1099 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1102 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1103 sprintf(buffer,
"%sOffset", xName);
1104 sprintf(buffer1,
"Offset of %s for fit", xName);
1106 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1107 sprintf(buffer,
"%sScale", xName);
1108 sprintf(buffer1,
"Scale factor of %s for fit", xName);
1110 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1113 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1114 for (colIndex = 0; colIndex < numCols; colIndex++) {
1116 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1118 sprintf(buffer1,
"%sCoefficient", yNames[colIndex]);
1119 sprintf(buffer2,
"%sCoefficientSigma", yNames[colIndex]);
1122 (sigmasValid &&
SDDS_DefineColumn(SDDSoutInfo, buffer2,
"$gs$r$ba$n",
"[CoefficientUnits]",
"sigma of coefficient of term in fit", NULL,
SDDS_DOUBLE, 0) < 0))
1123 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1128 sprintf(buffer1,
"%sReducedChiSquared", yNames[colIndex]);
1129 sprintf(buffer2,
"%sRmsResidual", yNames[colIndex]);
1130 sprintf(buffer3,
"%sSignificanceLevel", yNames[colIndex]);
1133 "Reduced chi-squared of fit",
1136 (iRmsResidual[colIndex] =
1138 (iSigLevel[colIndex] =
SDDS_DefineParameter(SDDSoutInfo, buffer3, NULL, NULL,
"Probability that data is from fit function", NULL,
SDDS_DOUBLE, NULL)) < 0)
1139 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1143 sprintf(buffer,
"%sFitIsValid", yNames[colIndex]);
1145 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1149 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1152 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1155 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1158 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1159 sprintf(buffer,
"%sOffset", xName);
1160 sprintf(buffer1,
"Offset of %s for fit", xName);
1162 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1163 sprintf(buffer,
"%sScale", xName);
1164 sprintf(buffer1,
"Scale factor of %s for fit", xName);
1166 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1168 for (colIndex = 0; colIndex < numCols; colIndex++) {
1170 sprintf(buffer1,
"%sReducedChiSquared", yNames[colIndex]);
1171 sprintf(buffer2,
"%sRmsResidual", yNames[colIndex]);
1172 sprintf(buffer3,
"%sSignificanceLevel", yNames[colIndex]);
1175 "Reduced chi-squared of fit",
1178 (iRmsResidualO[colIndex] =
1180 (iSigLevelO[colIndex] =
SDDS_DefineParameter(SDDSout, buffer3, NULL, NULL,
"Probability that data is from fit function", NULL,
SDDS_DOUBLE, NULL)) < 0)
1181 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1185 sprintf(buffer,
"%sFitIsValid", yNames[colIndex]);
1187 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1190 if (copyParameters) {
1192 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1194 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1198 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1205 long iYName, i, iCoeff, coeffs;
1206 char *xSymbol, *ySymbol;
1207 char *mainTemplateFirstDeriv[3] = {
"%yNameDeriv",
"Derivative w.r.t. %xSymbol of %ySymbol",
"d[%ySymbol]/d[%xSymbol]"};
1208 char *mainTemplate[3];
1210 char ***yDerivName, ***yDerivUnits;
1211 long nderiv, derivOrder;
1213 gsl_bspline_workspace *bw;
1215#if GSL_MAJOR_VERSION == 1
1216 gsl_bspline_deriv_workspace *bdw;
1218 SDDSout = &evalParameters->dataset;
1219 bw = evalParameters->bw;
1220 coeffs = gsl_bspline_ncoeffs(bw);
1222 if (!
SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL,
"sddsspline output: evaluation of spline fits", evalParameters->file) ||
1224 SDDS_Bomb(
"Problem setting up evaluation file");
1227 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1232 if (evalParameters->flags & EVAL_PROVIDEBASIS) {
1233 iSpline =
tmalloc(
sizeof(*iSpline) * coeffs);
1234 evalParameters->iSpline = iSpline;
1235 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1236 sprintf(buffer,
"B%04ld", iCoeff);
1238 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1242 if (evalParameters->flags & EVAL_DERIVATIVES) {
1243 nderiv = evalParameters->nderiv;
1244 yDerivName =
tmalloc(
sizeof(*yDerivName) * (nderiv + 1));
1245 evalParameters->yDerivName = yDerivName;
1246 yDerivUnits =
tmalloc(
sizeof(*yDerivUnits) * (nderiv + 1));
1247 evalParameters->yDerivUnits = yDerivUnits;
1248 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1249 yDerivName[derivOrder] =
tmalloc(
sizeof(**yDerivName) * yNames);
1250 yDerivUnits[derivOrder] =
tmalloc(
sizeof(**yDerivUnits) * yNames);
1252 for (iYName = 0; iYName < yNames; iYName++) {
1254 SDDS_Bomb(
"Problem setting up evaluation file");
1255 yDerivName[0][iYName] = yName[iYName];
1257 for (derivOrder = 1; derivOrder <= nderiv; derivOrder++) {
1258 for (i = 0; i < 3; i++) {
1259 if (derivOrder != 1) {
1263 sprintf(buffer,
"%%yNameDeriv%ld", derivOrder);
1267 sprintf(buffer,
"Derivative %ld w.r.t. %%xSymbol of %%ySymbol", derivOrder);
1271 sprintf(buffer,
"d$a%ld$n[%%ySymbol]/d[%%xSymbol]$a%ld$n", derivOrder, derivOrder);
1274 cp_str(&mainTemplate[i], buffer);
1276 mainTemplate[i] = mainTemplateFirstDeriv[i];
1280 fprintf(stderr,
"error: problem getting symbol for column %s\n", yName[iYName]);
1281 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1287 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1288 yDerivUnits[derivOrder][iYName] = (
char *)divideColumnUnits(SDDSout, yDerivName[derivOrder - 1][iYName], xName);
1289 yDerivName[derivOrder][iYName] = (
char *)changeInformation(SDDSout,
"placeholderName", yDerivName[0][iYName],
1290 ySymbol, xName, xSymbol, mainTemplate, yDerivUnits[derivOrder][iYName]);
1294 SDDS_Bomb(
"Problem setting up evaluation file with derivatives");
1296 for (iYName = 0; iYName < yNames; iYName++) {
1298 SDDS_Bomb(
"Problem setting up evaluation file");
1301 SDDS_Bomb(
"Problem setting up evaluation file");
1306void makeEvaluationTable(
EVAL_PARAMETERS * evalParameters,
double *x, int64_t points,
1307 gsl_vector *B, gsl_matrix *cov, gsl_vector *c,
1308 char *xName,
char **yName,
long yNames,
long iYName,
long int order) {
1309 static double *xEval = NULL, *yEval = NULL;
1310 static int64_t maxEvals = 0;
1316 gsl_matrix *dB = NULL;
1317 long nderiv, coeffs, iCoeff, derivOrder;
1318 double **yDeriv = NULL;
1321 gsl_bspline_workspace *bw;
1323#if GSL_MAJOR_VERSION == 1
1324 gsl_bspline_deriv_workspace *bdw;
1326 SDDSout = &evalParameters->dataset;
1327 yDerivName = evalParameters->yDerivName;
1328 iSpline = evalParameters->iSpline;
1329 bw = evalParameters->bw;
1330 coeffs = gsl_bspline_ncoeffs(bw);
1332 if (!(evalParameters->flags & EVAL_BEGIN_GIVEN) || !(evalParameters->flags & EVAL_END_GIVEN)) {
1335 if (!(evalParameters->flags & EVAL_BEGIN_GIVEN))
1336 evalParameters->begin = min;
1337 if (!(evalParameters->flags & EVAL_END_GIVEN))
1338 evalParameters->end = max;
1340 if (!(evalParameters->flags & EVAL_NUMBER_GIVEN))
1341 evalParameters->number = points;
1342 if (evalParameters->number > 1)
1343 delta = (evalParameters->end - evalParameters->begin) / (evalParameters->number - 1);
1347 if (!xEval || maxEvals < evalParameters->number) {
1348 if (!(xEval = (
double *)
SDDS_Realloc(xEval,
sizeof(*xEval) * evalParameters->number)) ||
1349 !(yEval = (
double *)
SDDS_Realloc(yEval,
sizeof(*yEval) * evalParameters->number)))
1351 maxEvals = evalParameters->number;
1354 Bspline =
tmalloc(
sizeof(*Bspline) * coeffs);
1356 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1357 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1358 Bspline[iCoeff] =
tmalloc(
sizeof(**Bspline) * evalParameters->number);
1362 if (!(evalParameters->flags & EVAL_DERIVATIVES)) {
1363 for (i = 0; i < evalParameters->number; i++) {
1364 xi = evalParameters->begin + i * delta;
1366 gsl_bspline_eval(xi, B, bw);
1367 gsl_multifit_linear_est(B, c, cov, &yEval[i], &yerr);
1368 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1369 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1370 Bspline[iCoeff][i] = gsl_vector_get(B, iCoeff);
1380 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1381 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1382 for (iCoeff = 0; iCoeff < coeffs; iCoeff++)
1384 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1387 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1389 nderiv = evalParameters->nderiv;
1390 yDeriv =
tmalloc(
sizeof(
double *) * (nderiv + 1));
1391 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1392 yDeriv[derivOrder] =
tmalloc(
sizeof(
double) * evalParameters->number);
1394 dB = gsl_matrix_alloc(coeffs, nderiv + 1);
1395 for (i = 0; i < evalParameters->number; i++) {
1396 xi = evalParameters->begin + i * delta;
1398 gsl_bspline_eval(xi, B, bw);
1399 gsl_multifit_linear_est(B, c, cov, &yEval[i], &yerr);
1400#if GSL_MAJOR_VERSION == 1
1401 bdw = gsl_bspline_deriv_alloc(order);
1402 gsl_bspline_deriv_eval(xi, nderiv, dB, bw, bdw);
1403 gsl_bspline_deriv_free(bdw);
1405 gsl_bspline_deriv_eval(xi, nderiv, dB, bw);
1407 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1408 yDeriv[derivOrder][i] = 0;
1409 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1410 yDeriv[derivOrder][i] += gsl_vector_get(c, iCoeff) * gsl_matrix_get(dB, iCoeff, derivOrder);
1413 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1414 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1415 Bspline[iCoeff][i] = gsl_vector_get(B, iCoeff);
1419 gsl_matrix_free(dB);
1426 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1428 for (derivOrder = 1; derivOrder <= nderiv; derivOrder++) {
1429 if (!
SDDS_SetColumnFromDoubles(SDDSout, SDDS_SET_BY_NAME, yDeriv[derivOrder], evalParameters->number, yDerivName[derivOrder][iYName]))
1430 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1432 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1433 for (iCoeff = 0; iCoeff < coeffs; iCoeff++)
1435 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1438 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1440 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1441 free(yDeriv[derivOrder]);
1446 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1447 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1448 free(Bspline[iCoeff]);
1455char *changeInformation(
SDDS_DATASET * SDDSout,
char *name,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol,
char **
template,
char *newUnits) {
1456 char buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], *ptr;
1459 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1461 makeSubstitutions(buffer1, buffer2,
template[2], nameRoot, symbolRoot, xName, xSymbol);
1463 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1465 makeSubstitutions(buffer1, buffer2,
template[1], nameRoot, symbolRoot, xName, xSymbol);
1467 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1469 makeSubstitutions(buffer1, buffer2,
template[0], nameRoot, symbolRoot, xName, xSymbol);
1471 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1476void makeSubstitutions(
char *buffer1,
char *buffer2,
char *
template,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol) {
1477 strcpy(buffer2,
template);
1482 strcpy(buffer1, buffer2);
1485int print_matrix(FILE * f,
const gsl_matrix *m) {
1488 for (i = 0; i < m->size1; i++) {
1489 for (j = 0; j < m->size2; j++) {
1490 if ((status = fprintf(f,
"%10.6lf ", gsl_matrix_get(m, i, j))) < 0)
1495 if ((status = fprintf(f,
"\n")) < 0)
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
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_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
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_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
int32_t SDDS_DefineParameter1(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, void *fixed_value)
Defines a data parameter with a fixed numerical value.
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_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_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
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_CHARACTER
Identifier for the character data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
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 replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.
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 ipower(double x, long n)
Evaluate a power function x^n.
double ChiSqrSigLevel(double ChiSquared0, long nu)
Computes the probability that a chi-squared variable exceeds a given value.
char * str_tolower(char *s)
Convert a string to lower case.