68static char *option[N_OPTIONS] = {
82 "\nUsage: sddsdigfilter [<inputfile>] [<outputfile>] [-pipe=[input][,output]]\n"
83 " -columns=<xcol>,<ycol>[,...]\n"
85 " -proportional=<gain>\n"
86 " -lowpass=<gain>,<cutoff_freq>\n"
87 " -highpass=<gain>,<cutoff_freq>\n"
88 " -digitalfilter=<sddsfile>,<a_coeff_col>,<b_coeff_col>\n"
89 " or -digitalfilter=[A,<a0>,<a1>,...][,B,<b0>,<b1>,...]\n"
90 " -analogfilter=<sddsfile>,<c_coeff_col>,<d_coeff_col>\n"
91 " or -analogfilter=[C,<c0>,<c1>,...][,D,<d0>,<d1>,...]\n"
94 " -majorOrder=row|column\n"
95 "\nDigital filter form:\n"
96 " b0 + b1.z^-1 + ... + bn.z^-n\n"
97 " --------------------------------\n"
98 " a0 + a1.z^-1 + ... + an.z^-n\n"
99 "\nAnalog filter form:\n"
100 " d0 + d1.s^1 + ... + dn.s^n\n"
101 " ------------------------------\n"
102 " c0 + c1.s^1 + ... + cn.s^n\n\n";
128 long *type, numFilters;
129 double *time, *input, *output;
132long processFilterParams(
char **args,
long items,
char *fistStr,
char *nextStr,
ANADIG *ADptr);
133long processFilterParamsFromFile(
char *filename,
char *ACColumn,
char *BDColumn,
ANADIG *ADptr);
136long lowpass_function(
STAGE *stage,
long filterNum, int64_t npoints);
137long highpass_function(
STAGE *stage,
long filterNum, int64_t npoints);
138long proportional_function(
STAGE *stage,
long filterNum, int64_t npoints);
139long analog_function(
STAGE *stage,
long filterNum, int64_t npoints);
140long digital_function(
STAGE *stage,
long filterNum, int64_t npoints);
143long response(
double *input,
double *output, int64_t nInput, int64_t nOutput,
double *Bcoeff,
double *Acoeff, int64_t nBcoeffs, int64_t nAcoeffs);
145void dspbiln(
double *d,
double *c, int64_t ln,
double *b,
double *a,
double *work,
long *error);
146void dspfblt(
double *d,
double *c,
long ln,
long iband,
double fln,
double fhn,
double *b,
double *a,
double *work,
long *error);
147double dspbfct(
long *i1,
long *i2);
148double dpow_ri(
double *ap,
long *bp);
150long (*filter_funct[])(
STAGE *stage,
long filterNum, int64_t npoints) =
152 lowpass_function, highpass_function, proportional_function, analog_function, digital_function};
157int main(
int argc,
char *argv[]) {
160 char *inputfile, *outputfile, *xcolName, **ycolName, **ycolMatch;
161 long columnsupplied, totalFilterCount, totalStages, tmpfileUsed;
163 int32_t yColumns, ycolMatches;
164 long i, j, i_arg, filterNum, stageNum, currentFilter, currentStage, filterType, error;
165 unsigned long pipeFlags, majorOrderFlag;
166 char outColName[256], outColDesc[256];
168 short columnMajorOrder = -1;
176 argc =
scanargs(&s_arg, argc, argv);
185 inputfile = outputfile = xcolName = NULL;
186 ycolName = ycolMatch = NULL;
187 yColumns = ycolMatches = 0;
190 totalFilterCount = 0;
195 stage = (
STAGE *)malloc(
sizeof(*stage));
196 stage[0].filter = (
void *)malloc(
sizeof(*stage[0].filter));
197 stage[0].type = (
long *)malloc(
sizeof(*stage[0].type));
199 for (i_arg = 1; i_arg < argc; i_arg++) {
200 if (s_arg[i_arg].arg_type == OPTION) {
202 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
203 case CLO_MAJOR_ORDER:
205 s_arg[i_arg].n_items--;
206 if (s_arg[i_arg].n_items > 0 && (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
"row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
"column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
207 SDDS_Bomb(
"invalid -majorOrder syntax/values");
208 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
209 columnMajorOrder = 1;
210 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
211 columnMajorOrder = 0;
214 if (s_arg[i_arg].n_items < 2)
216 LHptr = (
LOWHIGH *)malloc(
sizeof(*LHptr));
217 if (!
get_double(&(LHptr->gain), s_arg[i_arg].list[1]))
218 SDDS_Bomb(
"Invalid -lowpass value provided.");
219 if (s_arg[i_arg].n_items > 2 && !
get_double(&(LHptr->cutoff), s_arg[i_arg].list[2]))
220 SDDS_Bomb(
"Invalid -lowpass value provided.");
221 stage[stageNum].filter[filterNum] = LHptr;
222 stage[stageNum].type[filterNum] = CLO_LOWPASS;
223 stage[stageNum].numFilters = ++filterNum;
226 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
227 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
230 if (s_arg[i_arg].n_items < 2)
232 LHptr = (
LOWHIGH *)malloc(
sizeof(*LHptr));
233 if (!
get_double(&(LHptr->gain), s_arg[i_arg].list[1]))
234 SDDS_Bomb(
"Invalid -highpass value provided.");
235 if (s_arg[i_arg].n_items > 2 && !
get_double(&(LHptr->cutoff), s_arg[i_arg].list[2]))
236 SDDS_Bomb(
"Invalid -highpass value provided.");
237 stage[stageNum].filter[filterNum] = LHptr;
238 stage[stageNum].type[filterNum] = CLO_HIGHPASS;
239 stage[stageNum].numFilters = ++filterNum;
242 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
243 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
245 case CLO_PROPORTIONAL:
246 if (s_arg[i_arg].n_items != 2)
247 SDDS_Bomb(
"Invalid -proportional option.");
248 Gptr = (
GAIN *)malloc(
sizeof(*Gptr));
249 if (!
get_double(&(Gptr->gain), s_arg[i_arg].list[1]))
250 SDDS_Bomb(
"Invalid -proportional value provided.");
251 stage[stageNum].filter[filterNum] = Gptr;
252 stage[stageNum].type[filterNum] = CLO_PROPORTIONAL;
253 stage[stageNum].numFilters = ++filterNum;
256 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
257 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
259 case CLO_ANALOGFILTER:
260 if (s_arg[i_arg].n_items < 2)
261 SDDS_Bomb(
"Invalid -analogfilter option.");
262 ADptr = (
ANADIG *)malloc(
sizeof(*ADptr));
263 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
264 if (strcasecmp(s_arg[i_arg].list[1],
"C") == 0 || strcasecmp(s_arg[i_arg].list[1],
"D") == 0) {
265 processFilterParams(s_arg[i_arg].list, s_arg[i_arg].n_items,
"C",
"D", ADptr);
267 if (s_arg[i_arg].n_items != 4)
268 SDDS_Bomb(
"Invalid -analogfilter option for providing coefficient file and coefficient column names.");
269 processFilterParamsFromFile(s_arg[i_arg].list[1], s_arg[i_arg].list[2], s_arg[i_arg].list[3], ADptr);
271 stage[stageNum].filter[filterNum] = ADptr;
272 stage[stageNum].type[filterNum] = CLO_ANALOGFILTER;
273 stage[stageNum].numFilters = ++filterNum;
276 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
277 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
279 case CLO_DIGITALFILTER:
280 if (s_arg[i_arg].n_items < 2)
281 SDDS_Bomb(
"Invalid -digitalfilter option.");
282 ADptr = (
ANADIG *)malloc(
sizeof(*ADptr));
283 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
284 if (strcasecmp(s_arg[i_arg].list[1],
"A") == 0 || strcasecmp(s_arg[i_arg].list[1],
"B") == 0) {
285 processFilterParams(s_arg[i_arg].list, s_arg[i_arg].n_items,
"A",
"B", ADptr);
287 if (s_arg[i_arg].n_items != 4)
288 SDDS_Bomb(
"Invalid -digitalfilter option for providing coefficient file and coefficient column names.");
289 processFilterParamsFromFile(s_arg[i_arg].list[1], s_arg[i_arg].list[2], s_arg[i_arg].list[3], ADptr);
291 stage[stageNum].filter[filterNum] = ADptr;
292 stage[stageNum].type[filterNum] = CLO_DIGITALFILTER;
293 stage[stageNum].numFilters = ++filterNum;
296 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
297 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
302 stage = (
STAGE *)realloc(stage,
sizeof(*stage) * (stageNum + 1));
303 stage[stageNum].filter = (
void *)malloc(
sizeof(*stage[stageNum].filter));
304 stage[stageNum].type = (
long *)malloc(
sizeof(*stage[stageNum].type));
306 stage[stageNum].numFilters = filterNum;
309 if (s_arg[i_arg].n_items < 3)
311 xcolName = s_arg[i_arg].list[1];
312 ycolMatches = s_arg[i_arg].n_items - 2;
313 ycolMatch = malloc(
sizeof(*ycolMatch) * ycolMatches);
314 for (i = 2; i < s_arg[i_arg].n_items; i++)
315 ycolMatch[i - 2] = s_arg[i_arg].list[i];
319 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
326 fprintf(stderr,
"Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
331 if (inputfile == NULL)
332 inputfile = s_arg[i_arg].list[0];
333 else if (outputfile == NULL)
334 outputfile = s_arg[i_arg].list[0];
340 processFilenames(
"sddsdigfilter", &inputfile, &outputfile, pipeFlags, 1, &tmpfileUsed);
342 if (totalFilterCount == 0 || columnsupplied == 0) {
343 fprintf(stderr,
"no filter or no columns supplied.\n");
346 totalStages = stageNum + 1;
349 if (
SDDS_CheckColumn(&SDDS_input, xcolName, NULL, 0, stderr) != SDDS_CHECK_OKAY) {
350 fprintf(stderr,
"xColumn %s does not exist.\n", xcolName);
353 ycolName =
getMatchingSDDSNames(&SDDS_input, ycolMatch, ycolMatches, &yColumns, SDDS_MATCH_COLUMN);
354 for (i = 0; i < yColumns; i++) {
355 if (
SDDS_CheckColumn(&SDDS_input, ycolName[i], NULL, 0, stderr) != SDDS_CHECK_OKAY) {
356 fprintf(stderr,
"yColumn %s does not exist.\n", ycolName[i]);
362 if (columnMajorOrder != -1)
363 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
365 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
366 for (i = 0; i < yColumns; i++) {
367 sprintf(outColName,
"DigFiltered%s", ycolName[i]);
368 sprintf(outColDesc,
"Digital Filtered %s", ycolName[i]);
384 for (i = 0; i < yColumns; i++) {
385 sprintf(outColName,
"DigFiltered%s", ycolName[i]);
389 for (currentStage = 0; currentStage < totalStages; currentStage++) {
391 fprintf(stdout,
"STAGE %ld\n", currentStage);
394 stage[currentStage].time = xcol;
396 if (currentStage == 0) {
397 stage[currentStage].input = ycol;
399 stage[currentStage].input = stage[currentStage - 1].output;
402 stage[currentStage].output = (
double *)calloc(npoints,
sizeof(*stage[currentStage].output));
404 for (currentFilter = 0; currentFilter < stage[currentStage].numFilters; currentFilter++) {
406 fprintf(stdout,
"filter %ld\n", currentFilter);
409 filterType = stage[currentStage].type[currentFilter];
410 error = (*filter_funct[filterType])(&(stage[currentStage]), currentFilter, npoints);
412 fprintf(stderr,
"nyquist violation.\n");
425 for (currentStage = 0; currentStage < totalStages; currentStage++)
426 free(stage[currentStage].output);
435 for (i = 0; i < totalStages; i++) {
436 for (j = 0; j < stage[i].numFilters; j++) {
437 switch (stage[i].type[j]) {
438 case CLO_ANALOGFILTER:
439 case CLO_DIGITALFILTER:
440 free(((
ANADIG *)(stage[i].filter[j]))->ACcoeff);
441 free(((
ANADIG *)(stage[i].filter[j]))->BDcoeff);
442 free((
ANADIG *)(stage[i].filter[j]));
444 case CLO_PROPORTIONAL:
445 free((
GAIN *)(stage[i].filter[j]));
449 free((
LOWHIGH *)(stage[i].filter[j]));
453 free(stage[i].filter);
461 return (EXIT_SUCCESS);
466long lowpass_function(
STAGE *stage,
long filterNum, int64_t npoints) {
468 double C_coeff[2] = {1.0, 1.0};
469 double D_coeff[2] = {1.0, 0.0};
471 double A_coeff[2], B_coeff[2];
472 double timePerPoint, normFrequency;
473 double *work, *tmpoutput;
480 filter_ptr = stage->filter[filterNum];
482 timePerPoint = (stage->time[1]) - (stage->time[0]);
483 if (timePerPoint < 0)
484 timePerPoint *= -1.0;
486 if (filter_ptr->gain == 0.0) {
487 for (i = 0; i < npoints; i++) {
488 stage->output[i] = 0.0;
493 work = (
double *)calloc(npoints,
sizeof(*work));
494 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
496 normFrequency = timePerPoint * (filter_ptr->cutoff);
499 dspfblt(D_coeff, C_coeff, 1, 1, normFrequency, 0.0, B_coeff, A_coeff, work, &error);
506 A_coeff[1] = A_coeff[0];
510 fprintf(stdout,
"a0: %f\tb0: %f\n", A_coeff[0], B_coeff[0]);
511 fprintf(stdout,
"a1: %f\tb1: %f\n\n", A_coeff[1], B_coeff[1]);
515 if (response(stage->input, tmpoutput, npoints, npoints, B_coeff, A_coeff, 2, 2)) {
516 fprintf(stderr,
"Invalid coeffs in lowpass filter.\n");
523 for (i = 0; i < npoints; i++) {
524 stage->output[i] += (filter_ptr->gain) * tmpoutput[i];
536long highpass_function(
STAGE *stage,
long filterNum, int64_t npoints) {
538 double C_coeff[] = {1.0, 1.0};
539 double D_coeff[] = {1.0, 0.0};
541 double A_coeff[2], B_coeff[2];
542 double timePerPoint, normFrequency;
543 double *work, *tmpoutput;
550 filter_ptr = stage->filter[filterNum];
552 timePerPoint = (stage->time[1]) - (stage->time[0]);
553 if (timePerPoint < 0)
554 timePerPoint *= -1.0;
556 if (filter_ptr->gain == 0.0) {
557 for (i = 0; i < npoints; i++) {
558 stage->output[i] = 0.0;
563 work = (
double *)calloc(npoints,
sizeof(*work));
564 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
566 normFrequency = timePerPoint * (filter_ptr->cutoff);
569 dspfblt(D_coeff, C_coeff, 1, 2, normFrequency, 0.0, B_coeff, A_coeff, work, &error);
576 A_coeff[1] = A_coeff[0];
580 fprintf(stdout,
"a0: %6.6g\tb0: %6.6g\n", A_coeff[0], B_coeff[0]);
581 fprintf(stdout,
"a1: %6.6g\tb1: %6.6g\n\n", A_coeff[1], B_coeff[1]);
585 if (response(stage->input, tmpoutput, npoints, npoints, B_coeff, A_coeff, 2, 2)) {
586 fprintf(stderr,
"invalid coeffs in highpass filter.\n");
593 for (i = 0; i < npoints; i++) {
594 stage->output[i] += (filter_ptr->gain) * tmpoutput[i];
607long digital_function(
STAGE *stage,
long filterNum, int64_t npoints) {
615 filter_ptr = stage->filter[filterNum];
617 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
620 for (i = 0; i < filter_ptr->ncoeffs; i++) {
621 fprintf(stdout,
"a%" PRId64
": %6.6g\tb%" PRId64
" %6.6g\n", i, filter_ptr->ACcoeff[i], i, filter_ptr->BDcoeff[i]);
626 if (response(stage->input, tmpoutput, npoints, npoints, filter_ptr->BDcoeff, filter_ptr->ACcoeff, (filter_ptr->ncoeffs), (filter_ptr->ncoeffs))) {
627 fprintf(stderr,
"Invalid coefficients in digitalfilter.\n");
633 for (i = 0; i < npoints; i++) {
634 stage->output[i] += tmpoutput[i];
646long analog_function(
STAGE *stage,
long filterNum, int64_t npoints) {
647 double sampleFrequency, sampleTime;
648 double *tmpoutput, *work;
649 double *Bcoeff, *Acoeff;
655 filter_ptr = stage->filter[filterNum];
656 work = (
double *)calloc(npoints,
sizeof(*work));
657 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
658 Bcoeff = (
double *)calloc(filter_ptr->ncoeffs,
sizeof(*Bcoeff));
659 Acoeff = (
double *)calloc(filter_ptr->ncoeffs,
sizeof(*Acoeff));
664 sampleTime = (stage->time[1] - stage->time[0]);
665 sampleFrequency = 2.0 / sampleTime;
666 if (sampleFrequency < 0.0)
667 sampleFrequency *= -1.0;
669 for (i = 0; i < filter_ptr->ncoeffs; i++) {
670 filter_ptr->BDcoeff[i] *= pow(sampleFrequency, i);
671 filter_ptr->ACcoeff[i] *= pow(sampleFrequency, i);
675 dspbiln(filter_ptr->BDcoeff, filter_ptr->ACcoeff, (filter_ptr->ncoeffs) - 1, Bcoeff, Acoeff, work, &error);
677 fprintf(stderr,
"Error(%ld): invalid or all-zero analog transfer function\n", error);
686 for (i = filter_ptr->ncoeffs - 1; i > 0; i--) {
687 Acoeff[i] = Acoeff[i - 1];
692 for (i = 0; i < filter_ptr->ncoeffs; i++) {
693 fprintf(stdout,
"c%" PRId64
": %6.6g\td%" PRId64
": %6.6g\ta%" PRId64
": %6.6g\tb%" PRId64
": %6.6g\n",
694 i, filter_ptr->ACcoeff[i],
695 i, filter_ptr->BDcoeff[i],
702 if (response(stage->input, tmpoutput, npoints, npoints, Bcoeff, Acoeff, (filter_ptr->ncoeffs), (filter_ptr->ncoeffs))) {
703 fprintf(stderr,
"Invalid coefficients in analogfilter.\n");
712 for (i = 0; i < npoints; i++) {
713 stage->output[i] += tmpoutput[i];
729long proportional_function(
STAGE *stage,
long filterNum, int64_t npoints) {
735 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
736 filter_ptr = stage->filter[filterNum];
738 for (i = 0; i < npoints; i++) {
739 tmpoutput[i] = (stage->input[i]) * (filter_ptr->gain);
743 for (i = 0; i < npoints; i++) {
744 stage->output[i] += tmpoutput[i];
755long response(
double *input,
double *output, int64_t nInput, int64_t nOutput,
double *Bcoeff,
double *Acoeff, int64_t nBcoeffs, int64_t nAcoeffs) {
768 int64_t k, n, m, max, inputPoint;
770 if (Acoeff[0] == 0.0 || nAcoeffs < 1 || nBcoeffs < 1) {
774 for (k = 0; k < nOutput; k++) {
777 max = (k < nBcoeffs) ? k : nBcoeffs;
778 for (n = 0; n < max; n++) {
781 inputPoint = ((k - n) < nInput) ? (k - n) : (nInput - 1);
782 output[k] += Bcoeff[n] * input[inputPoint];
786 max = (k < nAcoeffs) ? k : nAcoeffs;
787 for (m = 1; m < max; m++) {
789 output[k] -= Acoeff[m] * output[k - m];
793 output[k] /= Acoeff[0];
819void dspbiln(
double *d,
double *c, int64_t ln,
double *b,
double *a,
double *work,
long *error) {
822 int64_t i, j, l, work_dim1;
829 for (i = ln; i >= 0 && zero_func; --i) {
830 if (c[i] != 0.0 || d[i] != 0.0) {
843 for (j = 0; j <= l; ++j) {
844 work[j * work_dim1] = 1.0;
848 for (i = 1; i <= l; ++i) {
849 tmp = tmp * (double)(l - i + 1) / (double)i;
853 for (i = 1; i <= l; ++i) {
854 for (j = 1; j <= l; ++j) {
855 work[i + j * work_dim1] = work[i + (j - 1) * work_dim1] - work[i - 1 + j * work_dim1] - work[i - 1 + (j - 1) * work_dim1];
859 for (i = l; i >= 0; --i) {
863 for (j = 0; j <= l; ++j) {
864 b[i] += work[i + j * work_dim1] * d[j];
865 atmp += (double)work[i + j * work_dim1] * c[j];
868 scale = (double)atmp;
871 a[i - 1] = (double)atmp;
881 for (i = 1; i <= l; ++i) {
887 for (i = l + 1; i <= ln; ++i) {
921void dspfblt(
double *d,
double *c,
long ln,
long iband,
double fln,
double fhn,
double *b,
double *a,
double *work,
long *error) {
923 long work_dim1, tmp_int, i, k, l, m, zero_func, ll, mm, ls;
924 double tmpc, tmpd, w = 0, w1, w2, w02 = 0, tmp;
926 if (iband < 1 || iband > 4) {
930 if ((fln <= 0.0 || fln > 0.5) || (iband >= 3 && (fln >= fhn || fhn > 0.5))) {
936 for (i = ln; i >= 0 && zero_func; --i) {
937 if (c[i] != 0.0 || d[i] != 0.0) {
950 w1 = (double)tan(PI * fln);
954 w2 = (double)tan(PI * fhn);
969 for (mm = 0; mm <= m; ++mm) {
970 d[mm] /= dpow_ri(&w1, &mm);
971 c[mm] /= dpow_ri(&w1, &mm);
980 for (mm = 0; mm <= (m / 2); ++mm) {
991 for (mm = 0; mm <= m; ++mm) {
992 d[mm] /= dpow_ri(&w1, &mm);
993 c[mm] /= dpow_ri(&w1, &mm);
1002 for (ll = 0; ll <= l; ++ll) {
1004 work[ll + work_dim1] = 0.0;
1007 for (mm = 0; mm <= m; ++mm) {
1009 tmpd = d[mm] * dpow_ri(&w, &tmp_int);
1010 tmpc = c[mm] * dpow_ri(&w, &tmp_int);
1012 for (k = 0; k <= mm; ++k) {
1013 ls = m + mm - (k * 2);
1015 tmp = dspbfct(&mm, &mm) / (dspbfct(&k, &k) * dspbfct(&tmp_int, &tmp_int));
1016 work[ls] += tmpd * dpow_ri(&w02, &k) * tmp;
1017 work[ls + work_dim1] += tmpc * dpow_ri(&w02, &k) * tmp;
1021 for (ll = 0; ll <= l; ++ll) {
1023 c[ll] = work[ll + work_dim1];
1032 for (mm = 0; mm <= (m / 2); ++mm) {
1043 for (ll = 0; ll <= l; ++ll) {
1045 work[ll + work_dim1] = 0.0;
1048 for (mm = 0; mm <= m; ++mm) {
1050 tmpd = d[mm] * dpow_ri(&w, &tmp_int);
1051 tmpc = c[mm] * dpow_ri(&w, &tmp_int);
1053 for (k = 0; k <= mm; ++k) {
1054 ls = m + mm - (k * 2);
1056 tmp = dspbfct(&mm, &mm) / (dspbfct(&k, &k) * dspbfct(&tmp_int, &tmp_int));
1057 work[ls] += tmpd * dpow_ri(&w02, &k) * tmp;
1058 work[ls + work_dim1] += tmpc * dpow_ri(&w02, &k) * tmp;
1062 for (ll = 0; ll <= l; ++ll) {
1064 c[ll] = work[ll + work_dim1];
1070 dspbiln(d, c, ln, b, a, work, error);
1083double dspbfct(
long *i1,
long *i2) {
1089 if (*i1 < 0 || *i2 < 0 || *i2 > *i1) {
1094 for (i = *i1; i >= (*i1 - *i2 + 1); --i) {
1095 ret_val *= (double)i;
1104double dpow_ri(
double *ap,
long *bp) {
1140long processFilterParams(
char **args,
long items,
char *firstStr,
char *nextStr,
ANADIG *ADptr) {
1141 long a, b, aFlag, bFlag, i;
1143 a = b = aFlag = bFlag = 0;
1144 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
1145 for (i = 1; i < items; i++) {
1146 if (strcasecmp(args[i], firstStr) == 0) {
1149 }
else if (strcasecmp(args[i], nextStr) == 0) {
1154 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * (a + 1));
1155 if (!
get_double(&(ADptr->ACcoeff[a]), args[i]))
1156 SDDS_Bomb(
"Invalid filter coefficient provided.");
1160 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * (b + 1));
1161 if (!
get_double(&(ADptr->BDcoeff[b]), args[i]))
1162 SDDS_Bomb(
"Invalid filter coefficient provided.");
1167 if (a == 0 && b == 0)
1170 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * (a + 1));
1171 ADptr->ACcoeff[0] = 1.0;
1175 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * (b + 1));
1176 ADptr->BDcoeff[0] = 1.0;
1179 ADptr->ncoeffs = a > b ? a : b;
1180 if (a < ADptr->ncoeffs) {
1181 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * ADptr->ncoeffs);
1182 for (i = a; i < ADptr->ncoeffs; i++)
1183 ADptr->ACcoeff[i] = 0.0;
1185 if (b < ADptr->ncoeffs) {
1186 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * ADptr->ncoeffs);
1187 for (i = b; i < ADptr->ncoeffs; i++)
1188 ADptr->BDcoeff[i] = 0.0;
1193long processFilterParamsFromFile(
char *filename,
char *ACColumn,
char *BDColumn,
ANADIG *ADptr) {
1197 fprintf(stderr,
"error: problem reading %s\n", filename);
1198 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1201 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1203 fprintf(stderr,
"error: problem counting rows in file %s\n", filename);
1204 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1206 ADptr->ncoeffs = rows;
1207 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
1209 fprintf(stderr,
"error: unable to read AC coefficient column.\n");
1210 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1213 fprintf(stderr,
"error: unable to read BD coefficient column.\n");
1214 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1217 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
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_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_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_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
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_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_DOUBLE
Identifier for the double data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
int get_double(double *dptr, char *s)
Parses a double value from the given string.
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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)
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.