SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddspoly.c File Reference

Detailed Description

Evaluates polynomials for N-dimensional input from SDDS files.

This program reads input data from SDDS files and evaluates polynomials defined in an auxiliary SDDS file. It supports multiple input columns and generates an output SDDS file containing evaluated results.

Usage

sddspoly [<inputfile>] [<outputfile>] \
[-pipe=[input][,output]] \
-evaluate=filename=<polyFilename>,output=<column>,coefficients=<column>, \
input0=<inputColumn>,power0=<powerColumn>[,input1=<inputColumn>,power1=<powerColumn>]...

Options

Required Description
-evaluate Defines polynomial evaluation using options such as input and output file columns, coefficient, and power definitions.
Optional Description
-pipe Allows input and output streams to be read/written directly to/from a pipeline.

Specific Requirements

  • For -evaluate:
    • Each input<n> and power<n> must be paired correctly to define variables and their exponents.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
M. Borland, H. Shang, R. Soliday

Definition in file sddspoly.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"
#include "SDDSutils.h"
#include <ctype.h>

Go to the source code of this file.

Functions

void initializePolynomial (POLYNOMIAL *poly, SDDS_DATASET *SDDSin, SDDS_DATASET *SDDSout)
 
double evaluatePoly (double *coef, int32_t **power, long nCoef, double *input, long nInputs)
 
void FreePolynormialMemory (POLYNOMIAL *poly, long npoly)
 
int main (int argc, char **argv)
 

Function Documentation

◆ evaluatePoly()

double evaluatePoly ( double * coef,
int32_t ** power,
long nCoef,
double * input,
long nInputs )

Definition at line 282 of file sddspoly.c.

282 {
283 double sum = 0.0, term;
284 long iCoef, iInput;
285
286 for (iCoef = 0; iCoef < nCoef; iCoef++) {
287 term = coef[iCoef];
288 for (iInput = 0; iInput < nInputs; iInput++) {
289 term *= ipow(input[iInput], power[iInput][iCoef]);
290 }
291 sum += term;
292 }
293
294 return sum;
295}
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33

◆ FreePolynormialMemory()

void FreePolynormialMemory ( POLYNOMIAL * poly,
long npoly )

Definition at line 396 of file sddspoly.c.

396 {
397 long i, j;
398
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]);
405 }
406 free(poly[i].powerColumn);
407 free(poly[i].inputColumn);
408 free(poly[i].power);
409 free(poly[i].input);
410 free(poly[i].inputData);
411 free(poly[i].coef);
412 free(poly[i].filename);
413 free(poly[i].coefColumn);
414 free(poly[i].outputColumn);
415 }
416}
double poly(double *a, long n, double x)
Evaluate a polynomial at a given point.
Definition poly.c:30

◆ initializePolynomial()

void initializePolynomial ( POLYNOMIAL * poly,
SDDS_DATASET * SDDSin,
SDDS_DATASET * SDDSout )

Definition at line 297 of file sddspoly.c.

297 {
298 long i;
299 SDDS_DATASET SDDSpoly;
300 char buffer[1024];
301
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");
306 }
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");
310 }
311 if (!(poly->flags & (POLY_IN0_SEEN << (2 * i))) &&
312 !(poly->flags & (POLY_OUT0_SEEN << (2 * i)))) {
313 break;
314 }
315 }
316 poly->nInputs = i;
317
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");
322 }
323 }
324
325 if (!SDDS_InitializeInput(&SDDSpoly, poly->filename)) {
326 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
327 }
328
329 if (SDDS_GetColumnIndex(&SDDSpoly, poly->outputColumn) == -1) {
330 if (!SDDS_DefineSimpleColumn(SDDSout, poly->outputColumn, NULL, SDDS_DOUBLE)) {
331 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
332 }
333 } else {
334 if (SDDS_CheckColumn(&SDDSpoly, poly->outputColumn, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY) {
335 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
336 }
337 }
338
339 if (SDDS_CheckColumn(&SDDSpoly, poly->coefColumn, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY) {
340 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
341 }
342
343 for (i = 0; i < poly->nInputs; i++) {
344 if (SDDS_CheckColumn(SDDSin, poly->inputColumn[i], NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY) {
345 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
346 }
347 if (SDDS_CheckColumn(&SDDSpoly, poly->powerColumn[i], NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY) {
348 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
349 }
350 }
351
352 if (SDDS_ReadPage(&SDDSpoly) <= 0) {
353 snprintf(buffer, sizeof(buffer), "problem with file %s\n", poly->filename);
354 SDDS_SetError(buffer);
355 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
356 }
357
358 if ((poly->nTerms = SDDS_RowCount(&SDDSpoly)) <= 0) {
359 snprintf(buffer, sizeof(buffer), "problem with file %s: no rows\n", poly->filename);
360 SDDS_SetError(buffer);
361 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
362 }
363
364 poly->coef = SDDS_GetColumnInDoubles(&SDDSpoly, poly->coefColumn);
365 if (!poly->coef) {
366 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
367 }
368
369 poly->power = SDDS_Malloc(sizeof(*(poly->power)) * poly->nInputs);
370 if (!poly->power) {
371 SDDS_Bomb("memory allocation failure");
372 }
373
374 for (i = 0; i < poly->nInputs; i++) {
375 poly->power[i] = SDDS_GetColumnInLong(&SDDSpoly, poly->powerColumn[i]);
376 if (!poly->power[i]) {
377 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
378 }
379 }
380
381 if (!SDDS_Terminate(&SDDSpoly)) {
382 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
383 }
384
385 poly->input = SDDS_Malloc(sizeof(*(poly->input)) * poly->nInputs);
386 if (!poly->input) {
387 SDDS_Bomb("memory allocation failure");
388 }
389
390 poly->inputData = SDDS_Malloc(sizeof(*(poly->inputData)) * poly->nInputs);
391 if (!poly->inputData) {
392 SDDS_Bomb("memory allocation failure");
393 }
394}
int32_t * SDDS_GetColumnInLong(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of 32-bit integers,...
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
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.
Definition SDDS_utils.c:432
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37

◆ main()

int main ( int argc,
char ** argv )

Definition at line 112 of file sddspoly.c.

112 {
114 long nPoly, iPoly, iInput;
115 int64_t row, rows;
116 int iArg;
117 char *input, *output;
118 unsigned long pipeFlags;
119 SCANNED_ARG *scanned;
120 SDDS_DATASET SDDSin, SDDSout;
121 double *outputData;
122
124 argc = scanargs(&scanned, argc, argv);
125 if (argc < 3) {
126 bomb(NULL, USAGE);
127 }
128
129 outputData = NULL;
130 input = output = NULL;
131 pipeFlags = 0;
132 poly = NULL;
133 nPoly = 0;
134
135 for (iArg = 1; iArg < argc; iArg++) {
136 if (scanned[iArg].arg_type == OPTION) {
137 /* process options here */
138 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
139 case CLO_EVALUATE:
140 poly = SDDS_Realloc(poly, sizeof(*poly) * (nPoly + 1));
141 if (!poly ||
142 !(poly[nPoly].inputColumn = SDDS_Malloc(sizeof(*(poly[nPoly].inputColumn)) * 5)) ||
143 !(poly[nPoly].powerColumn = SDDS_Malloc(sizeof(*(poly[nPoly].powerColumn)) * 5))) {
144 SDDS_Bomb("memory allocation failure");
145 }
146
147 scanned[iArg].n_items -= 1;
148 if (!scanItemList(&poly[nPoly].flags,
149 scanned[iArg].list + 1,
150 &scanned[iArg].n_items,
151 0,
152 "filename", SDDS_STRING, &(poly[nPoly].filename), 1, POLY_FILE_SEEN,
153 "output", SDDS_STRING, &(poly[nPoly].outputColumn), 1, POLY_OUTPUT_SEEN,
154 "coefficients", SDDS_STRING, &(poly[nPoly].coefColumn), 1, POLY_COEF_SEEN,
155 "input0", SDDS_STRING, poly[nPoly].inputColumn + 0, 1, POLY_IN0_SEEN,
156 "power0", SDDS_STRING, poly[nPoly].powerColumn + 0, 1, POLY_OUT0_SEEN,
157 "input1", SDDS_STRING, poly[nPoly].inputColumn + 1, 1, POLY_IN1_SEEN,
158 "power1", SDDS_STRING, poly[nPoly].powerColumn + 1, 1, POLY_OUT1_SEEN,
159 "input2", SDDS_STRING, poly[nPoly].inputColumn + 2, 1, POLY_IN2_SEEN,
160 "power2", SDDS_STRING, poly[nPoly].powerColumn + 2, 1, POLY_OUT2_SEEN,
161 "input3", SDDS_STRING, poly[nPoly].inputColumn + 3, 1, POLY_IN3_SEEN,
162 "power3", SDDS_STRING, poly[nPoly].powerColumn + 3, 1, POLY_OUT3_SEEN,
163 "input4", SDDS_STRING, poly[nPoly].inputColumn + 4, 1, POLY_IN4_SEEN,
164 "power4", SDDS_STRING, poly[nPoly].powerColumn + 4, 1, POLY_OUT4_SEEN,
165 NULL) ||
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)) {
171 SDDS_Bomb("invalid -evaluate syntax");
172 }
173 nPoly++;
174 break;
175
176 case CLO_PIPE:
177 if (!processPipeOption(scanned[iArg].list + 1,
178 scanned[iArg].n_items - 1,
179 &pipeFlags)) {
180 SDDS_Bomb("invalid -pipe syntax");
181 }
182 break;
183
184 default:
185 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
186 exit(EXIT_FAILURE);
187 break;
188 }
189 } else {
190 if (!input) {
191 input = scanned[iArg].list[0];
192 } else if (!output) {
193 output = scanned[iArg].list[0];
194 } else {
195 SDDS_Bomb("too many filenames seen");
196 }
197 }
198 }
199
200 processFilenames("sddspoly", &input, &output, pipeFlags, 0, NULL);
201
202 if (nPoly == 0) {
203 SDDS_Bomb("give at least one -evaluate option");
204 }
205
206 if (!SDDS_InitializeInput(&SDDSin, input)) {
207 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
208 }
209
210 if (!SDDS_InitializeCopy(&SDDSout, &SDDSin, output, "w")) {
211 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
212 }
213
214 for (iPoly = 0; iPoly < nPoly; iPoly++) {
215 initializePolynomial(&poly[iPoly], &SDDSin, &SDDSout);
216 }
217
218 if (!SDDS_WriteLayout(&SDDSout)) {
219 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
220 }
221
222 while (SDDS_ReadPage(&SDDSin) > 0) {
223 rows = SDDS_CountRowsOfInterest(&SDDSin);
224 if (!SDDS_CopyPage(&SDDSout, &SDDSin)) {
225 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
226 }
227
228 outputData = SDDS_Realloc(outputData, sizeof(*outputData) * rows);
229 if (!outputData) {
230 SDDS_Bomb("memory allocation failure");
231 }
232
233 for (iPoly = 0; iPoly < nPoly; iPoly++) {
234 for (iInput = 0; iInput < poly[iPoly].nInputs; iInput++) {
235 poly[iPoly].inputData[iInput] =
236 SDDS_GetColumnInDoubles(&SDDSin, poly[iPoly].inputColumn[iInput]);
237 if (!poly[iPoly].inputData[iInput]) {
238 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
239 }
240 }
241
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];
245 }
246 outputData[row] = evaluatePoly(poly[iPoly].coef,
247 poly[iPoly].power,
248 poly[iPoly].nTerms,
249 poly[iPoly].input,
250 poly[iPoly].nInputs);
251 }
252
253 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, outputData, rows, poly[iPoly].outputColumn)) {
254 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
255 }
256 }
257
258 if (!SDDS_WritePage(&SDDSout)) {
259 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
260 }
261 }
262
263 free(outputData);
264
265 if (!SDDS_Terminate(&SDDSin)) {
266 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
267 exit(EXIT_FAILURE);
268 }
269
270 if (!SDDS_Terminate(&SDDSout)) {
271 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
272 exit(EXIT_FAILURE);
273 }
274
275 free_scanargs(&scanned, argc);
276 FreePolynormialMemory(poly, nPoly);
277 free(poly);
278
279 return EXIT_SUCCESS;
280}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
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_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.