55char *option[N_OPTIONS] = {
61 "sddspoly [<inputfile>] [<outputfile>] "
62 "[-pipe=[input][,output]]\n"
63 " -evaluate=filename=<polyFilename>,output=<column>,coefficients=<column>,\n"
64 " input0=<inputColumn>,power0=<powerColumn>[,input1=<inputColumn>,power1=<polyColumn>][,...]\n"
65 " [-evaluate=...]\n\n"
67 " -pipe Standard SDDS Toolkit pipe option.\n"
68 " -evaluate Specifies evaluation of a polynomial defined in <polyFilename>.\n"
69 " The results are stored in <outputfile> under the column name\n"
70 " specified by output=<column>.\n"
71 " The coefficients are taken from the column named\n"
72 " coefficients=<column>.\n"
73 " The input<n> qualifiers specify the column names in <inputfile>\n"
74 " that serve as inputs to the polynomial.\n"
75 " The power<n> qualifiers specify the column names in\n"
76 " <polyFilename> that provide the exponents for each input.\n\n"
77 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
79#define POLY_FILE_SEEN 0x0001U
80#define POLY_OUTPUT_SEEN 0x0002U
81#define POLY_COEF_SEEN 0x0004U
82#define POLY_IN0_SEEN 0x0008U
83#define POLY_OUT0_SEEN 0x0010U
84#define POLY_IN1_SEEN 0x0020U
85#define POLY_OUT1_SEEN 0x0040U
86#define POLY_IN2_SEEN 0x0080U
87#define POLY_OUT2_SEEN 0x0100U
88#define POLY_IN3_SEEN 0x0200U
89#define POLY_OUT3_SEEN 0x0400U
90#define POLY_IN4_SEEN 0x0800U
91#define POLY_OUT4_SEEN 0x1000U
109double evaluatePoly(
double *coef, int32_t **power,
long nCoef,
double *input,
long nInputs);
112int main(
int argc,
char **argv) {
114 long nPoly, iPoly, iInput;
117 char *input, *output;
118 unsigned long pipeFlags;
119 SCANNED_ARG *scanned;
124 argc =
scanargs(&scanned, argc, argv);
130 input = output = NULL;
135 for (iArg = 1; iArg < argc; iArg++) {
136 if (scanned[iArg].arg_type == OPTION) {
138 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
147 scanned[iArg].n_items -= 1;
149 scanned[iArg].list + 1,
150 &scanned[iArg].n_items,
153 "output",
SDDS_STRING, &(
poly[nPoly].outputColumn), 1, POLY_OUTPUT_SEEN,
154 "coefficients",
SDDS_STRING, &(
poly[nPoly].coefColumn), 1, POLY_COEF_SEEN,
166 !(
poly[nPoly].flags & POLY_FILE_SEEN) ||
167 !(
poly[nPoly].flags & POLY_OUTPUT_SEEN) ||
168 !(
poly[nPoly].flags & POLY_COEF_SEEN) ||
169 !(
poly[nPoly].flags & POLY_IN0_SEEN) ||
170 !(
poly[nPoly].flags & POLY_OUT0_SEEN)) {
178 scanned[iArg].n_items - 1,
185 fprintf(stderr,
"error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
191 input = scanned[iArg].list[0];
192 }
else if (!output) {
193 output = scanned[iArg].list[0];
203 SDDS_Bomb(
"give at least one -evaluate option");
214 for (iPoly = 0; iPoly < nPoly; iPoly++) {
215 initializePolynomial(&
poly[iPoly], &SDDSin, &SDDSout);
228 outputData =
SDDS_Realloc(outputData,
sizeof(*outputData) * rows);
233 for (iPoly = 0; iPoly < nPoly; iPoly++) {
234 for (iInput = 0; iInput <
poly[iPoly].nInputs; iInput++) {
235 poly[iPoly].inputData[iInput] =
237 if (!
poly[iPoly].inputData[iInput]) {
242 for (row = 0; row < rows; row++) {
243 for (iInput = 0; iInput <
poly[iPoly].nInputs; iInput++) {
244 poly[iPoly].input[iInput] =
poly[iPoly].inputData[iInput][row];
246 outputData[row] = evaluatePoly(
poly[iPoly].coef,
250 poly[iPoly].nInputs);
253 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, outputData, rows,
poly[iPoly].outputColumn)) {
276 FreePolynormialMemory(
poly, nPoly);
282double evaluatePoly(
double *coef, int32_t **power,
long nCoef,
double *input,
long nInputs) {
283 double sum = 0.0, term;
286 for (iCoef = 0; iCoef < nCoef; iCoef++) {
288 for (iInput = 0; iInput < nInputs; iInput++) {
289 term *=
ipow(input[iInput], power[iInput][iCoef]);
302 for (i = 1; i < 5; i++) {
303 if ((
poly->flags & (POLY_IN0_SEEN << (2 * i))) &&
304 !(
poly->flags & (POLY_OUT0_SEEN << (2 * i)))) {
305 SDDS_Bomb(
"input qualifier seen without matching output qualifier");
307 if (!(
poly->flags & (POLY_IN0_SEEN << (2 * i))) &&
308 (
poly->flags & (POLY_OUT0_SEEN << (2 * i)))) {
309 SDDS_Bomb(
"output qualifier seen without matching input qualifier");
311 if (!(
poly->flags & (POLY_IN0_SEEN << (2 * i))) &&
312 !(
poly->flags & (POLY_OUT0_SEEN << (2 * i)))) {
318 for (i++; i < 5; i++) {
319 if ((
poly->flags & (POLY_IN0_SEEN << (2 * i))) ||
320 (
poly->flags & (POLY_OUT0_SEEN << (2 * i)))) {
321 SDDS_Bomb(
"input<n> or output<n> qualifiers skipped");
343 for (i = 0; i <
poly->nInputs; i++) {
353 snprintf(buffer,
sizeof(buffer),
"problem with file %s\n",
poly->filename);
358 if ((
poly->nTerms = SDDS_RowCount(&SDDSpoly)) <= 0) {
359 snprintf(buffer,
sizeof(buffer),
"problem with file %s: no rows\n",
poly->filename);
374 for (i = 0; i <
poly->nInputs; i++) {
376 if (!
poly->power[i]) {
391 if (!
poly->inputData) {
399 for (i = 0; i < npoly; i++) {
400 for (j = 0; j <
poly[i].nInputs; j++) {
401 free(
poly[i].power[j]);
402 free(
poly[i].inputData[j]);
403 free(
poly[i].inputColumn[j]);
404 free(
poly[i].powerColumn[j]);
406 free(
poly[i].powerColumn);
407 free(
poly[i].inputColumn);
410 free(
poly[i].inputData);
412 free(
poly[i].filename);
413 free(
poly[i].coefColumn);
414 free(
poly[i].outputColumn);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
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.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
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_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
Utility functions for SDDS dataset manipulation and string array operations.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
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.
double poly(double *a, long n, double x)
Evaluate a polynomial at a given point.
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.