88#include <gsl/gsl_bspline.h>
89#include <gsl/gsl_multifit.h>
90#include <gsl/gsl_rng.h>
91#include <gsl/gsl_randist.h>
92#include <gsl/gsl_statistics.h>
93#include <gsl/gsl_version.h>
95void makeSubstitutions(
char *buffer1,
char *buffer2,
char *
template,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol);
96char *changeInformation(
SDDS_DATASET *SDDSout,
char *name,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol,
char **
template,
char *newUnits);
97char **makeCoefficientUnits(
SDDS_DATASET *SDDSout,
char *xName,
char *yName,
long int order,
long coeffs);
99 SDDS_DATASET *SDDSin,
char *input,
char *xName,
char **yNames,
char *xSigmaName,
100 char **ySigmaNames,
long sigmasValid,
long int order,
long coeffs,
long breaks,
101 long numCols,
long copyParameters);
102void checkInputFile(
SDDS_DATASET *SDDSin,
char *xName,
char **yNames,
char *xSigmaName,
char **ySigmaNames,
long numYNames);
103long coefficient_index(
long int order,
long coeffs,
long order_of_interest);
105char **ResolveColumnNames(
SDDS_DATASET *SDDSin,
char **wildcardList,
long length, int32_t *numYNames);
106char **GenerateYSigmaNames(
char *controlString,
char **yNames,
long numYNames);
107void RemoveElementFromStringArray(
char **array,
long index,
long length);
108char **RemoveNonNumericColumnsFromNameArray(
SDDS_DATASET *SDDSin,
char **columns, int32_t *numColumns);
110int print_matrix(FILE *f,
const gsl_matrix *m);
132 CLO_SIGMAINDEPENDENT,
139char *option[N_OPTIONS] = {
165 "sddssplinefit [<inputfile>] [<outputfile>]\n"
166 " [-pipe=[input][,output]]\n"
167 " -independent=<xName>\n"
168 " -dependent=<yName1-wildcard>[,<yName2-wildcard>...]\n"
169 " [-sigmaIndependent=<xSigma>]\n"
170 " [-sigmaDependent=<ySigmaFormatString>]\n"
171 " [-order=<number>]\n"
172 " [-coefficients=<number>]\n"
173 " [-breakpoints=<number>]\n"
174 " [-xOffset=<value>]\n"
175 " [-xFactor=<value>]\n"
176 " [-sigmas=<value>,{absolute|fractional}]\n"
178 " [-generateSigmas[={keepLargest,keepSmallest}]]\n"
179 " [-sparse=<interval>]\n"
180 " [-range=<lower>,<upper>[,fitOnly]]\n"
181 " [-normalize[=<termNumber>]]\n"
183 " [-evaluate=<filename>[,begin=<value>][,end=<value>][,number=<integer>][,derivatives=<order>][,basis]]\n"
184 " [-infoFile=<filename>]\n"
185 " [-copyParameters]\n"
186 "Program by Louis Emery, started with Michael Borland polynomial fit program (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
188static char *additional_help =
"\n\
189sddssplinefit 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\
190spline function evaluated at x. Internally, sddssplinefit computes the A[i] coefficients, writes the fitted y values to the output file,\n\
191and estimates the errors in these values.\n";
193static char *additional_help2 =
"\n\
194 -independent Specify the name of the independent data column to use.\n\
195 -dependent Specify the names of dependent data columns to use, supporting wildcards and separated by commas.\n\
196 -sigmaIndependent Specify the name of the independent sigma values column.\n\
197 -sigmaDependent Specify a printf-style control string to generate dependent sigma column names from independent variable names (e.g., %sSigma).\n\
198 -order Define the order of the spline. Default is 4.\n\
199 -coefficients Set the number of coefficients. Specify either coefficients or breakpoints, not both.\n\
200 -breakpoints Set the number of breakpoints. Condition enforced: breakpoints = coefficients + 2 - order.\n\
201 -xOffset Define the desired value of x to fit about.\n\
202 -xFactor Define the factor to multiply x values by before fitting.\n\
203 -sigmas Specify absolute or fractional sigma for all points.\n\
204 -modifySigmas Modify the y sigmas using the x sigmas and an initial fit.\n\
205 -generateSigmas Generate y sigmas from the RMS deviation of an initial fit.\n\
206 Optionally keep the sigmas from the data if larger/smaller than the RMS deviation.\n\
207 -sparse Specify an integer interval at which to sample data.\n\
208 -range Define the range of the independent variable over which to perform the fit and evaluation.\n\
209 If 'fitOnly' is given, the fit is compared to data over the original range.\n\
210 -normalize Normalize so that the specified term is unity.\n\
211 -verbose Enable verbose output for additional information.\n\
212 -evaluate Evaluate the spline fit and optionally compute derivatives and provide basis functions.\n\
213 -infoFile Specify a file to output fit information.\n\
214 -copyParameters Copy parameters from the input file to the output file.\n\n";
216#define ABSOLUTE_SIGMAS 0
217#define FRACTIONAL_SIGMAS 1
218#define N_SIGMAS_OPTIONS 2
219char *sigmas_options[N_SIGMAS_OPTIONS] = {
"absolute",
"fractional"};
221#define FLGS_GENERATESIGMAS 1
222#define FLGS_KEEPLARGEST 2
223#define FLGS_KEEPSMALLEST 4
225#define REVPOW_ACTIVE 0x0001
226#define REVPOW_VERBOSE 0x0002
228static long iOffset = -1, iOffsetO = -1, iFactor = -1, iFactorO = -1;
229static long *iChiSq = NULL, *iChiSqO = NULL, *iRmsResidual = NULL, *iRmsResidualO = NULL, *iSigLevel = NULL, *iSigLevelO = NULL;
230static long *iFitIsValid = NULL, *iFitIsValidO = NULL;
233static long ix = -1, ixSigma = -1;
234static long *iy = NULL, *iySigma = NULL;
235static long *iFit = NULL, *iResidual = NULL;
237static long *iCoefficient = NULL, *iCoefficientSigma = NULL, *iCoefficientUnits = NULL;
239static char *xSymbol, **ySymbols;
241#define EVAL_BEGIN_GIVEN 0x0001U
242#define EVAL_END_GIVEN 0x0002U
243#define EVAL_NUMBER_GIVEN 0x0004U
244#define EVAL_DERIVATIVES 0x0008U
245#define EVAL_PROVIDEBASIS 0x0010U
247#define MAX_Y_SIGMA_NAME_SIZE 1024
253 int64_t number, nderiv;
257 char ***yDerivName, ***yDerivUnits;
259 gsl_bspline_workspace *bw;
262void makeEvaluationTable(
EVAL_PARAMETERS *evalParameters,
double *x, int64_t points, gsl_vector *B,
263 gsl_matrix *cov, gsl_vector *c,
char *xName,
char **yName,
long yNames,
long iYName,
long int order);
265int main(
int argc,
char **argv) {
266 double **y = NULL, **yFit = NULL, **sy = NULL, **diff = NULL;
267 double *x = NULL, *sx = NULL;
268 double xOffset, xScaleFactor;
269 double *xOrig = NULL, **yOrig = NULL, **yFitOrig = NULL, *sxOrig = NULL, **syOrig = NULL, **sy0 = NULL;
270 long coeffs, breaks, normTerm, ySigmasValid;
271 long orderGiven, coeffsGiven, breaksGiven;
272 int64_t i, j, points, pointsOrig;
274 long sigmasMode, sparseInterval;
275 double *chi = NULL, xLow, xHigh, *rmsResidual = NULL;
276 char *xName = NULL, *yName = NULL, **yNames = NULL, *xSigmaName = NULL;
277 char **ySigmaNames = NULL, *ySigmaControlString = NULL;
278 char *input = NULL, *output = NULL;
280 long *isFit = NULL, iArg, modifySigmas;
281 long generateSigmas, verbose, ignoreSigmas;
282 long outputInitialized, copyParameters = 0;
285 double xMin, xMax, revpowThreshold;
286 double rms_average(
double *d_x, int64_t d_n);
287 char *infoFile = NULL;
288 unsigned long pipeFlags, reviseOrders;
290 long rangeFitOnly = 0;
293 long cloDependentIndex = -1, numDependentItems;
297 gsl_bspline_workspace *bw;
299 gsl_vector *c, *yGsl, *wGsl;
301 gsl_multifit_linear_workspace *mw;
302 long degreesOfFreedom;
303 double totalSumSquare, Rsq;
306 argc =
scanargs(&s_arg, argc, argv);
307 if (argc < 2 || argc > (3 + N_OPTIONS)) {
308 fprintf(stderr,
"usage: %s\n", USAGE);
309 fprintf(stderr,
"%s%s", additional_help, additional_help2);
313 input = output = NULL;
314 xName = yName = xSigmaName = ySigmaControlString = NULL;
315 yNames = ySigmaNames = NULL;
316 numDependentItems = 0;
317 modifySigmas = reviseOrders = 0;
325 verbose = ignoreSigmas = 0;
330 evalParameters.file = NULL;
336 for (iArg = 1; iArg < argc; iArg++) {
337 if (s_arg[iArg].arg_type == OPTION) {
338 switch (
match_string(s_arg[iArg].list[0], option, N_OPTIONS, 0)) {
339 case CLO_MODIFYSIGMAS:
343 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &order) != 1)
347 case CLO_COEFFICIENTS:
348 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &coeffs) != 1)
349 SDDS_Bomb(
"invalid -coefficients syntax");
352 case CLO_BREAKPOINTS:
353 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%ld", &breaks) != 1)
354 SDDS_Bomb(
"invalid -breakpoints syntax");
359 if ((s_arg[iArg].n_items != 3 && s_arg[iArg].n_items != 4) ||
360 1 != sscanf(s_arg[iArg].list[1],
"%lf", &xMin) ||
361 1 != sscanf(s_arg[iArg].list[2],
"%lf", &xMax) ||
364 if (s_arg[iArg].n_items == 4) {
365 if (strncmp(
str_tolower(s_arg[iArg].list[3]),
"fitonly", strlen(s_arg[iArg].list[3])) == 0) {
371 case CLO_GENERATESIGMAS:
372 generateSigmas = FLGS_GENERATESIGMAS;
373 if (s_arg[iArg].n_items > 1) {
374 if (s_arg[iArg].n_items != 2)
375 SDDS_Bomb(
"incorrect -generateSigmas syntax");
376 if (strncmp(s_arg[iArg].list[1],
"keepsmallest", strlen(s_arg[iArg].list[1])) == 0)
377 generateSigmas |= FLGS_KEEPSMALLEST;
378 if (strncmp(s_arg[iArg].list[1],
"keeplargest", strlen(s_arg[iArg].list[1])) == 0)
379 generateSigmas |= FLGS_KEEPLARGEST;
380 if ((generateSigmas & FLGS_KEEPSMALLEST) && (generateSigmas & FLGS_KEEPLARGEST))
381 SDDS_Bomb(
"ambiguous -generateSigmas syntax");
385 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1],
"%lf", &xOffset) != 1)
389 if (s_arg[iArg].n_items != 3)
391 if (sscanf(s_arg[iArg].list[1],
"%lf", &sigmas) != 1)
392 SDDS_Bomb(
"couldn't scan value for -sigmas");
393 if ((sigmasMode =
match_string(s_arg[iArg].list[2], sigmas_options, N_SIGMAS_OPTIONS, 0)) < 0)
397 if (s_arg[iArg].n_items != 2)
399 if (sscanf(s_arg[iArg].list[1],
"%ld", &sparseInterval) != 1)
400 SDDS_Bomb(
"couldn't scan value for -sparse");
401 if (sparseInterval < 1)
409 if (s_arg[iArg].n_items > 2 ||
410 (s_arg[iArg].n_items == 2 && sscanf(s_arg[iArg].list[1],
"%ld", &normTerm) != 1) ||
414 case CLO_REVISEORDERS:
415 revpowThreshold = 0.1;
416 s_arg[iArg].n_items -= 1;
417 if (!
scanItemList(&reviseOrders, s_arg[iArg].list + 1, &s_arg[iArg].n_items, 0,
419 "verbose", -1, NULL, 1, REVPOW_VERBOSE, NULL))
420 SDDS_Bomb(
"invalid -reviseOrders syntax");
421 s_arg[iArg].n_items += 1;
422 reviseOrders |= REVPOW_ACTIVE;
423 revpowThreshold = fabs(revpowThreshold);
426 if (s_arg[iArg].n_items != 2 ||
427 sscanf(s_arg[iArg].list[1],
"%lf", &xScaleFactor) != 1 || xScaleFactor == 0)
430 case CLO_INDEPENDENT:
431 if (s_arg[iArg].n_items != 2)
432 SDDS_Bomb(
"invalid -independent syntax");
433 xName = s_arg[iArg].list[1];
436 numDependentItems = s_arg[iArg].n_items - 1;
437 cloDependentIndex = iArg;
438 if (numDependentItems < 1)
441 case CLO_SIGMAINDEPENDENT:
442 if (s_arg[iArg].n_items != 2)
443 SDDS_Bomb(
"invalid -sigmaIndependent syntax");
444 xSigmaName = s_arg[iArg].list[1];
446 case CLO_SIGMADEPENDENT:
447 if (s_arg[iArg].n_items != 2)
448 SDDS_Bomb(
"invalid -sigmaDependent syntax");
449 ySigmaControlString = s_arg[iArg].list[1];
452 if (!
processPipeOption(s_arg[iArg].list + 1, s_arg[iArg].n_items - 1, &pipeFlags))
456 if (s_arg[iArg].n_items != 2)
458 infoFile = s_arg[iArg].list[1];
461 if (s_arg[iArg].n_items < 2)
463 evalParameters.file = s_arg[iArg].list[1];
464 s_arg[iArg].n_items -= 2;
465 s_arg[iArg].list += 2;
466 evalParameters.begin = 0;
467 evalParameters.end = 0;
468 evalParameters.nderiv = 0;
469 evalParameters.number = 0;
470 if (!
scanItemList(&evalParameters.flags, s_arg[iArg].list, &s_arg[iArg].n_items, 0,
471 "begin",
SDDS_DOUBLE, &evalParameters.begin, 1, EVAL_BEGIN_GIVEN,
472 "end",
SDDS_DOUBLE, &evalParameters.end, 1, EVAL_END_GIVEN,
473 "derivatives",
SDDS_LONG64, &evalParameters.nderiv, 1, EVAL_DERIVATIVES,
474 "basis", -1, NULL, 0, EVAL_PROVIDEBASIS,
475 "number",
SDDS_LONG64, &evalParameters.number, 1, EVAL_NUMBER_GIVEN, NULL))
477 s_arg[iArg].n_items += 2;
478 s_arg[iArg].list -= 2;
480 case CLO_COPYPARAMETERS:
484 bomb(
"unknown switch", USAGE);
489 input = s_arg[iArg].list[0];
490 else if (output == NULL)
491 output = s_arg[iArg].list[0];
500 breaks = coeffs + 2 - order;
502 coeffs = breaks - 2 + order;
503 if (breaksGiven && coeffsGiven)
504 SDDS_Bomb(
"You must specify only one of breakpoints or coefficients");
508 if (!xName || !numDependentItems)
509 SDDS_Bomb(
"you must specify a column name for x and y");
510 if (modifySigmas && !xSigmaName)
511 SDDS_Bomb(
"you must specify x sigmas with -modifySigmas");
512 if (generateSigmas) {
514 SDDS_Bomb(
"you can't specify both -generateSigmas and -modifySigmas");
516 if (ySigmaControlString) {
517 if (sigmasMode != -1)
518 SDDS_Bomb(
"you can't specify both -sigmas and a y sigma name");
521 if (sigmasMode != -1 || generateSigmas || ySigmaControlString || modifySigmas)
526 outputInitialized = 0;
527 yNames = ResolveColumnNames(&SDDSin, s_arg[cloDependentIndex].list + 1, numDependentItems, &numYNames);
528 if (ySigmaControlString != NULL)
529 ySigmaNames = GenerateYSigmaNames(ySigmaControlString, yNames, numYNames);
531 checkInputFile(&SDDSin, xName, yNames, xSigmaName, ySigmaNames, numYNames);
532 sy0 =
tmalloc(
sizeof(
double *) * numYNames);
533 y =
tmalloc(
sizeof(
double *) * numYNames);
534 yFit =
tmalloc(
sizeof(
double *) * numYNames);
535 sy =
tmalloc(
sizeof(
double *) * numYNames);
536 isFit =
tmalloc(
sizeof(
long) * numYNames);
537 chi =
tmalloc(
sizeof(
double) * numYNames);
538 iCoefficient =
tmalloc(
sizeof(
long) * numYNames);
539 iCoefficientSigma =
tmalloc(
sizeof(
long) * numYNames);
540 iCoefficientUnits =
tmalloc(
sizeof(
long) * numYNames);
548 fprintf(stdout,
"number of points %" PRId64
"\n", points);
550 fprintf(stderr,
"error: unable to read column %s\n", xName);
553 for (i = 0; i < numYNames; i++) {
555 fprintf(stderr,
"error: unable to read column %s\n", yNames[i]);
561 fprintf(stderr,
"error: unable to read column %s\n", xSigmaName);
564 for (colIndex = 0; colIndex < numYNames; colIndex++) {
565 sy0[colIndex] =
tmalloc(
sizeof(
double) * points);
566 yFit[colIndex] =
tmalloc(
sizeof(
double) * points);
570 for (i = 0; i < numYNames; i++) {
572 fprintf(stderr,
"error: unable to read column %s\n", ySigmaNames[i]);
578 if (xMin != xMax || sparseInterval != 1) {
579 xOrig =
tmalloc(
sizeof(*xOrig) * points);
580 yOrig =
tmalloc(
sizeof(*yOrig) * numYNames);
581 yFitOrig =
tmalloc(
sizeof(*yFitOrig) * numYNames);
582 for (colIndex = 0; colIndex < numYNames; colIndex++) {
584 fprintf(stdout,
"Setting up a separate array for range or sparsing for column %s because of range option ...\n", yNames[colIndex]);
585 yOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
586 yFitOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
589 sxOrig =
tmalloc(
sizeof(*sxOrig) * points);
591 syOrig =
tmalloc(
sizeof(*syOrig) * numYNames);
592 for (colIndex = 0; colIndex < numYNames; colIndex++)
593 syOrig[colIndex] =
tmalloc(
sizeof(
double) * points);
596 for (i = j = 0; i < points; i++) {
600 for (colIndex = 0; colIndex < numYNames; colIndex++) {
601 yOrig[colIndex][i] = y[colIndex][i];
603 syOrig[colIndex][i] = sy0[colIndex][i];
607 for (i = j = 0; i < points; i++) {
608 if (xOrig[i] <= xMax && xOrig[i] >= xMin) {
610 for (colIndex = 0; colIndex < numYNames; colIndex++) {
611 y[colIndex][j] = yOrig[colIndex][i];
613 sy0[colIndex][j] = syOrig[colIndex][i];
622 if (sparseInterval != 1) {
623 for (i = j = 0; i < points; i++) {
624 if (i % sparseInterval == 0) {
626 for (colIndex = 0; colIndex < numYNames; colIndex++) {
627 y[colIndex][j] = y[colIndex][i];
629 sy0[colIndex][j] = sy0[colIndex][i];
649 fprintf(stdout,
"Range: xLow %lf; xHigh %lf; points %" PRId64
"\n", xLow, xHigh, points);
650 if (sigmasMode == ABSOLUTE_SIGMAS) {
651 for (colIndex = 0; colIndex < numYNames; colIndex++) {
652 for (i = 0; i < points; i++)
653 sy0[colIndex][i] = sigmas;
654 if (sy0[colIndex] != syOrig[colIndex])
655 for (i = 0; i < pointsOrig; i++)
656 syOrig[colIndex][i] = sigmas;
658 }
else if (sigmasMode == FRACTIONAL_SIGMAS) {
659 for (colIndex = 0; colIndex < numYNames; colIndex++) {
660 for (i = 0; i < points; i++)
661 sy0[colIndex][i] = sigmas * fabs(y[colIndex][i]);
662 if (sy0[colIndex] != syOrig[colIndex])
663 for (i = 0; i < pointsOrig; i++)
664 syOrig[colIndex][i] = fabs(yOrig[colIndex][i]) * sigmas;
668 if (!ySigmasValid || generateSigmas)
669 for (colIndex = 0; colIndex < numYNames; colIndex++) {
670 for (i = 0; i < points; i++)
671 sy0[colIndex][i] = 1;
674 for (i = 0; i < points; i++)
675 for (colIndex = 0; colIndex < numYNames; colIndex++) {
676 if (sy0[colIndex][i] == 0)
677 SDDS_Bomb(
"y sigma = 0 for one or more points.");
680 diff =
tmalloc(
sizeof(*diff) * numYNames);
681 sy =
tmalloc(
sizeof(*sy) * numYNames);
682 for (colIndex = 0; colIndex < numYNames; colIndex++) {
683 diff[colIndex] =
tmalloc(
sizeof(
double) * points);
684 sy[colIndex] =
tmalloc(
sizeof(
double) * points);
687 for (i = 0; i < points; i++) {
688 for (colIndex = 0; colIndex < numYNames; colIndex++)
689 sy[colIndex][i] = sy0[colIndex][i];
697 bw = gsl_bspline_alloc(order, breaks);
698 B = gsl_vector_alloc(coeffs);
701 X = gsl_matrix_alloc(points, coeffs);
702 c = gsl_vector_alloc(coeffs);
703 yGsl = gsl_vector_alloc(points);
704 wGsl = gsl_vector_alloc(points);
705 cov = gsl_matrix_alloc(coeffs, coeffs);
706 mw = gsl_multifit_linear_alloc(points, coeffs);
707 degreesOfFreedom = points - coeffs;
709 fprintf(stdout,
"Order %ld\ncoefficients %ld\nbreak points %ld\n", order, coeffs, breaks);
710 if (generateSigmas || modifySigmas)
711 fprintf(stderr,
"generate sigmas or modify sigmas are not a feature in spline fitting.\n");
713 if (reviseOrders & REVPOW_ACTIVE)
714 fprintf(stderr,
"revise orders is not a feature in spline fitting.\n");
716 if (!outputInitialized) {
717 initializeOutputFile(&SDDSout, &SDDSoutInfo, output, infoFile, &SDDSin, input, xName, yNames,
718 xSigmaName, ySigmaNames, ySigmasValid, order, coeffs, breaks, numYNames, copyParameters);
720 outputInitialized = 1;
722 if (evalParameters.file) {
724 if (evalParameters.nderiv >= order) {
725 evalParameters.nderiv = order - 1;
727 fprintf(stderr,
"Spline derivative order reduced to %" PRId64
" (i.e. order - 1)\n", evalParameters.nderiv);
729 evalParameters.bw = bw;
730 setupEvaluationFile(&evalParameters, xName, yNames, numYNames, &SDDSin);
734 rmsResidual =
tmalloc(
sizeof(
double) * numYNames);
736 if (outputInitialized) {
737 if (!
SDDS_StartPage(&SDDSout, rangeFitOnly ? pointsOrig : points) ||
740 if (copyParameters) {
747 if (!
SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_INDEX, rangeFitOnly ? xOrig : x, rangeFitOnly ? pointsOrig : points, ix))
749 for (colIndex = 0; colIndex < numYNames; colIndex++) {
752 for (i = 0; i < points; i++) {
753 gsl_vector_set(yGsl, i, y[colIndex][i]);
755 gsl_vector_set(wGsl, i, 1.0 /
ipower(sy[colIndex][i], 2));
759 gsl_bspline_knots_uniform(xLow, xHigh, bw);
765 for (i = 0; i < points; ++i) {
768 gsl_bspline_eval(x[i], B, bw);
770 for (j = 0; j < coeffs; ++j) {
771 Bj = gsl_vector_get(B, j);
773 gsl_matrix_set(X, i, j, Bj);
778 fprintf(stderr,
"X matrix %s:\n", yNames[colIndex]);
779 print_matrix(stderr, X);
782 gsl_multifit_wlinear(X, wGsl, yGsl, c, cov, &chi[colIndex], mw);
784 fprintf(stdout,
"conventionally-defined chi = sum( sqr(diff) * weight): %e\n", chi[colIndex]);
787 fprintf(stderr,
"Covariance matrix for %s:\n", yNames[colIndex]);
788 print_matrix(stderr, cov);
791 totalSumSquare = gsl_stats_wtss(wGsl->data, 1, yGsl->data, 1, yGsl->size);
792 Rsq = 1.0 - chi[colIndex] / totalSumSquare;
794 fprintf(stdout,
"(reduced) chisq/dof = %e, Rsq = %f\n", chi[colIndex] / degreesOfFreedom, Rsq);
797 for (i = 0; i < points; i++) {
798 gsl_bspline_eval(x[i], B, bw);
800 gsl_multifit_linear_est(B, c, cov, &yFit[colIndex][i], &y_err);
803 for (i = 0; i < pointsOrig; i++) {
804 diff[colIndex][i] = yOrig[colIndex][i] - yFitOrig[colIndex][i];
806 rmsResidual[colIndex] = rms_average(diff[colIndex], points);
813 for (i = 0; i < points; i++) {
814 diff[colIndex][i] = y[colIndex][i] - yFit[colIndex][i];
816 rmsResidual[colIndex] = rms_average(diff[colIndex], points);
826 if (evalParameters.file) {
827 evalParameters.bw = bw;
828 makeEvaluationTable(&evalParameters, x, points, B, cov, c, xName, yNames, numYNames, colIndex, order);
833 !
SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_INDEX, rangeFitOnly ? sxOrig : sx, rangeFitOnly ? pointsOrig : points, ixSigma))
838 Indices = malloc(
sizeof(*Indices) * coeffs);
839 for (i = 0; i < coeffs; i++)
841 if (!
SDDS_SetColumn(&SDDSoutInfo, SDDS_SET_BY_NAME, Indices, coeffs,
"Index"))
845 for (colIndex = 0; colIndex < numYNames; colIndex++) {
846 if (ySigmasValid && iySigma[colIndex] != -1 &&
848 rangeFitOnly ? pointsOrig : points, iySigma[colIndex]))
856 iRmsResidual[colIndex], rmsResidual[colIndex],
857 iChiSq[colIndex], (chi[colIndex] / degreesOfFreedom),
858 iSigLevel[colIndex],
ChiSqrSigLevel(chi[colIndex], points - coeffs),
859 iOffset, xOffset, iFactor, xScaleFactor, iFitIsValid[colIndex], isFit[colIndex] ?
'y' :
'n', -1))
865 iRmsResidualO[colIndex], rmsResidual[colIndex],
866 iChiSqO[colIndex], (chi[colIndex] / degreesOfFreedom),
867 iSigLevelO[colIndex],
ChiSqrSigLevel(chi[colIndex], points - coeffs),
868 iOffsetO, xOffset, iFactorO, xScaleFactor, iFitIsValidO[colIndex], isFit[colIndex] ?
'y' :
'n', -1))
882 for (colIndex = 0; colIndex < numYNames; colIndex++) {
883 free(diff[colIndex]);
885 if (yOrig[colIndex] != y[colIndex])
886 free(yOrig[colIndex]);
887 if (syOrig && sy0 && syOrig[colIndex] != sy0[colIndex])
888 free(syOrig[colIndex]);
890 if (sy0 && sy0[colIndex])
892 if (yFit && yFit[colIndex])
893 free(yFit[colIndex]);
895 gsl_bspline_free(bw);
898 gsl_vector_free(yGsl);
899 gsl_vector_free(wGsl);
901 gsl_matrix_free(cov);
902 gsl_multifit_linear_free(mw);
907 if (outputInitialized) {
916 if (evalParameters.file) {
930void RemoveElementFromStringArray(
char **array,
long index,
long length) {
933 for (lh = index; lh < length - 1; lh++)
934 array[lh] = array[lh + 1];
937char **RemoveNonNumericColumnsFromNameArray(
SDDS_DATASET *SDDSin,
char **columns, int32_t *numColumns) {
938 long i, numNumericColumns = *numColumns;
940 for (i = 0; i < *numColumns; i++) {
942 printf(
"Removing %s because not a numeric type.", columns[i]);
943 RemoveElementFromStringArray(columns, i, *numColumns);
948 *numColumns = numNumericColumns;
952char **ResolveColumnNames(
SDDS_DATASET *SDDSin,
char **wildcardList,
long length, int32_t *numYNames) {
958 for (i = 0; i < length; i++) {
963 bomb(
"Error matching columns in ResolveColumnNames: No matches.", NULL);
965 result = RemoveNonNumericColumnsFromNameArray(SDDSin, result, numYNames);
969char **GenerateYSigmaNames(
char *controlString,
char **yNames,
long numYNames) {
971 char **result, sigmaName[MAX_Y_SIGMA_NAME_SIZE];
973 result =
tmalloc(
sizeof(
char *) * numYNames);
974 for (i = 0; i < numYNames; i++) {
975 sprintf(sigmaName, controlString, yNames[i]);
976 nameLength = strlen(sigmaName);
977 result[i] =
tmalloc(
sizeof(
char) * (nameLength + 1));
978 strcpy(result[i], sigmaName);
983double rms_average(
double *x, int64_t n) {
987 for (i = sum2 = 0; i < n; i++)
990 return (sqrt(sum2 / n));
993void checkInputFile(
SDDS_DATASET *SDDSin,
char *xName,
char **yNames,
char *xSigmaName,
char **ySigmaNames,
long numYNames) {
998 SDDS_Bomb(
"x column doesn't exist or is nonnumeric");
1004 if (xSigmaName && !(ptr =
SDDS_FindColumn(SDDSin, FIND_NUMERIC_TYPE, xSigmaName, NULL)))
1005 SDDS_Bomb(
"x sigma column doesn't exist or is nonnumeric");
1010 for (i = 0; i < numYNames; i++) {
1012 if (!(ptr =
SDDS_FindColumn(SDDSin, FIND_NUMERIC_TYPE, ySigmaNames[i], NULL)))
1013 SDDS_Bomb(
"y sigma column doesn't exist or is nonnumeric");
1021 SDDS_DATASET *SDDSin,
char *input,
char *xName,
char **yNames,
char *xSigmaName,
1022 char **ySigmaNames,
long sigmasValid,
long int order,
long coeffs,
long breakpoints,
1023 long numCols,
long copyParameters) {
1024 char buffer[SDDS_MAXLINE], buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], buffer3[SDDS_MAXLINE];
1025 char *xUnits, *yUnits;
1032 ySymbols =
tmalloc(
sizeof(
char *) * numCols);
1033 iChiSq =
tmalloc(
sizeof(
long) * numCols);
1034 iChiSqO =
tmalloc(
sizeof(
long) * numCols);
1035 iRmsResidual =
tmalloc(
sizeof(
long) * numCols);
1036 iRmsResidualO =
tmalloc(
sizeof(
long) * numCols);
1037 iSigLevel =
tmalloc(
sizeof(
long) * numCols);
1038 iSigLevelO =
tmalloc(
sizeof(
long) * numCols);
1039 iFitIsValid =
tmalloc(
sizeof(
long) * numCols);
1040 iFitIsValidO =
tmalloc(
sizeof(
long) * numCols);
1041 iy =
tmalloc(
sizeof(
long) * numCols);
1042 iySigma =
tmalloc(
sizeof(
long) * numCols);
1043 iFit =
tmalloc(
sizeof(
long) * numCols);
1044 iResidual =
tmalloc(
sizeof(
long) * numCols);
1046 for (colIndex = 0; colIndex < numCols; colIndex++) {
1047 ySymbols[colIndex] = NULL;
1049 iChiSq[colIndex] = -1;
1050 iChiSqO[colIndex] = -1;
1051 iRmsResidual[colIndex] = -1;
1052 iRmsResidualO[colIndex] = -1;
1053 iSigLevel[colIndex] = -1;
1054 iSigLevelO[colIndex] = -1;
1055 iFitIsValid[colIndex] = -1;
1056 iFitIsValidO[colIndex] = -1;
1058 iySigma[colIndex] = -1;
1059 iFit[colIndex] = -1;
1060 iResidual[colIndex] = -1;
1063 if (!
SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL,
"sddssplinefit output: fitted data", output) ||
1067 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1069 for (colIndex = 0; colIndex < numCols; colIndex++) {
1073 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1077 for (colIndex = 0; colIndex < numCols; colIndex++)
1079 ySymbols[colIndex] = yNames[colIndex];
1081 for (colIndex = 0; colIndex < numCols; colIndex++) {
1089 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1091 for (colIndex = 0; colIndex < numCols; colIndex++) {
1092 sprintf(buffer,
"%sFit", yNames[colIndex]);
1093 sprintf(buffer1,
"Fit[%s]", ySymbols[colIndex]);
1096 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1098 SDDS_Bomb(
"unable to get index of just-defined fit output column");
1100 sprintf(buffer,
"%sResidual", yNames[colIndex]);
1101 sprintf(buffer1,
"Residual[%s]", ySymbols[colIndex]);
1104 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1106 SDDS_Bomb(
"unable to get index of just-defined residual output column");
1108 if (sigmasValid && !ySigmaNames) {
1109 sprintf(buffer,
"%sSigma", yNames[colIndex]);
1111 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1114 sprintf(buffer1,
"Sigma[%s]", ySymbols[colIndex]);
1116 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1121 if (outputInfo && !
SDDS_InitializeOutput(SDDSoutInfo, SDDS_BINARY, 0, NULL,
"sddsspline output: fit information", outputInfo))
1122 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1127 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1130 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1133 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1136 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1137 sprintf(buffer,
"%sOffset", xName);
1138 sprintf(buffer1,
"Offset of %s for fit", xName);
1140 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1141 sprintf(buffer,
"%sScale", xName);
1142 sprintf(buffer1,
"Scale factor of %s for fit", xName);
1144 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1147 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1148 for (colIndex = 0; colIndex < numCols; colIndex++) {
1150 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1152 sprintf(buffer1,
"%sCoefficient", yNames[colIndex]);
1153 sprintf(buffer2,
"%sCoefficientSigma", yNames[colIndex]);
1156 (sigmasValid &&
SDDS_DefineColumn(SDDSoutInfo, buffer2,
"$gs$r$ba$n",
"[CoefficientUnits]",
"sigma of coefficient of term in fit", NULL,
SDDS_DOUBLE, 0) < 0))
1157 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1162 sprintf(buffer1,
"%sReducedChiSquared", yNames[colIndex]);
1163 sprintf(buffer2,
"%sRmsResidual", yNames[colIndex]);
1164 sprintf(buffer3,
"%sSignificanceLevel", yNames[colIndex]);
1167 "Reduced chi-squared of fit",
1170 (iRmsResidual[colIndex] =
1172 (iSigLevel[colIndex] =
SDDS_DefineParameter(SDDSoutInfo, buffer3, NULL, NULL,
"Probability that data is from fit function", NULL,
SDDS_DOUBLE, NULL)) < 0)
1173 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1177 sprintf(buffer,
"%sFitIsValid", yNames[colIndex]);
1179 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1183 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1186 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1189 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1192 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1193 sprintf(buffer,
"%sOffset", xName);
1194 sprintf(buffer1,
"Offset of %s for fit", xName);
1196 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1197 sprintf(buffer,
"%sScale", xName);
1198 sprintf(buffer1,
"Scale factor of %s for fit", xName);
1200 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1202 for (colIndex = 0; colIndex < numCols; colIndex++) {
1204 sprintf(buffer1,
"%sReducedChiSquared", yNames[colIndex]);
1205 sprintf(buffer2,
"%sRmsResidual", yNames[colIndex]);
1206 sprintf(buffer3,
"%sSignificanceLevel", yNames[colIndex]);
1209 "Reduced chi-squared of fit",
1212 (iRmsResidualO[colIndex] =
1214 (iSigLevelO[colIndex] =
SDDS_DefineParameter(SDDSout, buffer3, NULL, NULL,
"Probability that data is from fit function", NULL,
SDDS_DOUBLE, NULL)) < 0)
1215 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1219 sprintf(buffer,
"%sFitIsValid", yNames[colIndex]);
1221 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1224 if (copyParameters) {
1226 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1228 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1232 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1239 long iYName, i, iCoeff, coeffs;
1240 char *xSymbol, *ySymbol;
1241 char *mainTemplateFirstDeriv[3] = {
"%yNameDeriv",
"Derivative w.r.t. %xSymbol of %ySymbol",
"d[%ySymbol]/d[%xSymbol]"};
1242 char *mainTemplate[3];
1244 char ***yDerivName, ***yDerivUnits;
1245 long nderiv, derivOrder;
1247 gsl_bspline_workspace *bw;
1249#if GSL_MAJOR_VERSION == 1
1250 gsl_bspline_deriv_workspace *bdw;
1252 SDDSout = &evalParameters->dataset;
1253 bw = evalParameters->bw;
1254 coeffs = gsl_bspline_ncoeffs(bw);
1256 if (!
SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL,
"sddsspline output: evaluation of spline fits", evalParameters->file) ||
1258 SDDS_Bomb(
"Problem setting up evaluation file");
1261 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1266 if (evalParameters->flags & EVAL_PROVIDEBASIS) {
1267 iSpline =
tmalloc(
sizeof(*iSpline) * coeffs);
1268 evalParameters->iSpline = iSpline;
1269 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1270 sprintf(buffer,
"B%04ld", iCoeff);
1272 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1276 if (evalParameters->flags & EVAL_DERIVATIVES) {
1277 nderiv = evalParameters->nderiv;
1278 yDerivName =
tmalloc(
sizeof(*yDerivName) * (nderiv + 1));
1279 evalParameters->yDerivName = yDerivName;
1280 yDerivUnits =
tmalloc(
sizeof(*yDerivUnits) * (nderiv + 1));
1281 evalParameters->yDerivUnits = yDerivUnits;
1282 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1283 yDerivName[derivOrder] =
tmalloc(
sizeof(**yDerivName) * yNames);
1284 yDerivUnits[derivOrder] =
tmalloc(
sizeof(**yDerivUnits) * yNames);
1286 for (iYName = 0; iYName < yNames; iYName++) {
1288 SDDS_Bomb(
"Problem setting up evaluation file");
1289 yDerivName[0][iYName] = yName[iYName];
1291 for (derivOrder = 1; derivOrder <= nderiv; derivOrder++) {
1292 for (i = 0; i < 3; i++) {
1293 if (derivOrder != 1) {
1297 sprintf(buffer,
"%%yNameDeriv%ld", derivOrder);
1301 sprintf(buffer,
"Derivative %ld w.r.t. %%xSymbol of %%ySymbol", derivOrder);
1305 sprintf(buffer,
"d$a%ld$n[%%ySymbol]/d[%%xSymbol]$a%ld$n", derivOrder, derivOrder);
1308 cp_str(&mainTemplate[i], buffer);
1310 mainTemplate[i] = mainTemplateFirstDeriv[i];
1314 fprintf(stderr,
"error: problem getting symbol for column %s\n", yName[iYName]);
1315 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1321 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1322 yDerivUnits[derivOrder][iYName] = (
char *)divideColumnUnits(SDDSout, yDerivName[derivOrder - 1][iYName], xName);
1323 yDerivName[derivOrder][iYName] = (
char *)changeInformation(SDDSout,
"placeholderName", yDerivName[0][iYName],
1324 ySymbol, xName, xSymbol, mainTemplate, yDerivUnits[derivOrder][iYName]);
1328 SDDS_Bomb(
"Problem setting up evaluation file with derivatives");
1330 for (iYName = 0; iYName < yNames; iYName++) {
1332 SDDS_Bomb(
"Problem setting up evaluation file");
1335 SDDS_Bomb(
"Problem setting up evaluation file");
1340void makeEvaluationTable(
EVAL_PARAMETERS * evalParameters,
double *x, int64_t points,
1341 gsl_vector *B, gsl_matrix *cov, gsl_vector *c,
1342 char *xName,
char **yName,
long yNames,
long iYName,
long int order) {
1343 static double *xEval = NULL, *yEval = NULL;
1344 static int64_t maxEvals = 0;
1350 gsl_matrix *dB = NULL;
1351 long nderiv, coeffs, iCoeff, derivOrder;
1352 double **yDeriv = NULL;
1355 gsl_bspline_workspace *bw;
1357#if GSL_MAJOR_VERSION == 1
1358 gsl_bspline_deriv_workspace *bdw;
1360 SDDSout = &evalParameters->dataset;
1361 yDerivName = evalParameters->yDerivName;
1362 iSpline = evalParameters->iSpline;
1363 bw = evalParameters->bw;
1364 coeffs = gsl_bspline_ncoeffs(bw);
1366 if (!(evalParameters->flags & EVAL_BEGIN_GIVEN) || !(evalParameters->flags & EVAL_END_GIVEN)) {
1369 if (!(evalParameters->flags & EVAL_BEGIN_GIVEN))
1370 evalParameters->begin = min;
1371 if (!(evalParameters->flags & EVAL_END_GIVEN))
1372 evalParameters->end = max;
1374 if (!(evalParameters->flags & EVAL_NUMBER_GIVEN))
1375 evalParameters->number = points;
1376 if (evalParameters->number > 1)
1377 delta = (evalParameters->end - evalParameters->begin) / (evalParameters->number - 1);
1381 if (!xEval || maxEvals < evalParameters->number) {
1382 if (!(xEval = (
double *)
SDDS_Realloc(xEval,
sizeof(*xEval) * evalParameters->number)) ||
1383 !(yEval = (
double *)
SDDS_Realloc(yEval,
sizeof(*yEval) * evalParameters->number)))
1385 maxEvals = evalParameters->number;
1388 Bspline =
tmalloc(
sizeof(*Bspline) * coeffs);
1390 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1391 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1392 Bspline[iCoeff] =
tmalloc(
sizeof(**Bspline) * evalParameters->number);
1396 if (!(evalParameters->flags & EVAL_DERIVATIVES)) {
1397 for (i = 0; i < evalParameters->number; i++) {
1398 xi = evalParameters->begin + i * delta;
1400 gsl_bspline_eval(xi, B, bw);
1401 gsl_multifit_linear_est(B, c, cov, &yEval[i], &yerr);
1402 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1403 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1404 Bspline[iCoeff][i] = gsl_vector_get(B, iCoeff);
1414 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1415 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1416 for (iCoeff = 0; iCoeff < coeffs; iCoeff++)
1418 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1421 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1423 nderiv = evalParameters->nderiv;
1424 yDeriv =
tmalloc(
sizeof(
double *) * (nderiv + 1));
1425 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1426 yDeriv[derivOrder] =
tmalloc(
sizeof(
double) * evalParameters->number);
1428 dB = gsl_matrix_alloc(coeffs, nderiv + 1);
1429 for (i = 0; i < evalParameters->number; i++) {
1430 xi = evalParameters->begin + i * delta;
1432 gsl_bspline_eval(xi, B, bw);
1433 gsl_multifit_linear_est(B, c, cov, &yEval[i], &yerr);
1434#if GSL_MAJOR_VERSION == 1
1435 bdw = gsl_bspline_deriv_alloc(order);
1436 gsl_bspline_deriv_eval(xi, nderiv, dB, bw, bdw);
1437 gsl_bspline_deriv_free(bdw);
1439 gsl_bspline_deriv_eval(xi, nderiv, dB, bw);
1441 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1442 yDeriv[derivOrder][i] = 0;
1443 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1444 yDeriv[derivOrder][i] += gsl_vector_get(c, iCoeff) * gsl_matrix_get(dB, iCoeff, derivOrder);
1447 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1448 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1449 Bspline[iCoeff][i] = gsl_vector_get(B, iCoeff);
1453 gsl_matrix_free(dB);
1460 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1462 for (derivOrder = 1; derivOrder <= nderiv; derivOrder++) {
1463 if (!
SDDS_SetColumnFromDoubles(SDDSout, SDDS_SET_BY_NAME, yDeriv[derivOrder], evalParameters->number, yDerivName[derivOrder][iYName]))
1464 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1466 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1467 for (iCoeff = 0; iCoeff < coeffs; iCoeff++)
1469 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1472 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1474 for (derivOrder = 0; derivOrder <= nderiv; derivOrder++) {
1475 free(yDeriv[derivOrder]);
1480 if ((iYName == 0) && (evalParameters->flags & EVAL_PROVIDEBASIS)) {
1481 for (iCoeff = 0; iCoeff < coeffs; iCoeff++) {
1482 free(Bspline[iCoeff]);
1489char *changeInformation(
SDDS_DATASET * SDDSout,
char *name,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol,
char **
template,
char *newUnits) {
1490 char buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], *ptr;
1493 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1495 makeSubstitutions(buffer1, buffer2,
template[2], nameRoot, symbolRoot, xName, xSymbol);
1497 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1499 makeSubstitutions(buffer1, buffer2,
template[1], nameRoot, symbolRoot, xName, xSymbol);
1501 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1503 makeSubstitutions(buffer1, buffer2,
template[0], nameRoot, symbolRoot, xName, xSymbol);
1505 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1510void makeSubstitutions(
char *buffer1,
char *buffer2,
char *
template,
char *nameRoot,
char *symbolRoot,
char *xName,
char *xSymbol) {
1511 strcpy(buffer2,
template);
1516 strcpy(buffer1, buffer2);
1519int print_matrix(FILE * f,
const gsl_matrix *m) {
1522 for (i = 0; i < m->size1; i++) {
1523 for (j = 0; j < m->size2; j++) {
1524 if ((status = fprintf(f,
"%10.6lf ", gsl_matrix_get(m, i, j))) < 0)
1529 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.
Utility functions for SDDS dataset manipulation and string array operations.
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.