105static char *option[N_OPTIONS] = {
119 "\nsddsdigfilter [<inputfile>] [<outputfile>] [-pipe=[input][,output]]\n"
120 " -columns=<xcol>,<ycol>[,...]\n"
122 " -proportional=<gain>\n"
123 " -lowpass=<gain>,<cutoff_freq>\n"
124 " -highpass=<gain>,<cutoff_freq>\n"
125 " -digitalfilter=<sddsfile>,<a_coeff_col>,<b_coeff_col>\n"
126 " or -digitalfilter=[A,<a0>,<a1>,...][,B,<b0>,<b1>,...]\n"
127 " -analogfilter=<sddsfile>,<c_coeff_col>,<d_coeff_col>\n"
128 " or -analogfilter=[C,<c0>,<c1>,...][,D,<d0>,<d1>,...]\n"
131 " -majorOrder=row|column\n"
132 "\nDigital filter form:\n"
133 " b0 + b1.z^-1 + ... + bn.z^-n\n"
134 " --------------------------------\n"
135 " a0 + a1.z^-1 + ... + an.z^-n\n"
136 "\nAnalog filter form:\n"
137 " d0 + d1.s^1 + ... + dn.s^n\n"
138 " ------------------------------\n"
139 " c0 + c1.s^1 + ... + cn.s^n\n\n";
165 long *type, numFilters;
166 double *time, *input, *output;
169long processFilterParams(
char **args,
long items,
char *fistStr,
char *nextStr,
ANADIG *ADptr);
170long processFilterParamsFromFile(
char *filename,
char *ACColumn,
char *BDColumn,
ANADIG *ADptr);
173long lowpass_function(
STAGE *stage,
long filterNum, int64_t npoints);
174long highpass_function(
STAGE *stage,
long filterNum, int64_t npoints);
175long proportional_function(
STAGE *stage,
long filterNum, int64_t npoints);
176long analog_function(
STAGE *stage,
long filterNum, int64_t npoints);
177long digital_function(
STAGE *stage,
long filterNum, int64_t npoints);
180long response(
double *input,
double *output, int64_t nInput, int64_t nOutput,
double *Bcoeff,
double *Acoeff, int64_t nBcoeffs, int64_t nAcoeffs);
182void dspbiln(
double *d,
double *c, int64_t ln,
double *b,
double *a,
double *work,
long *error);
183void dspfblt(
double *d,
double *c,
long ln,
long iband,
double fln,
double fhn,
double *b,
double *a,
double *work,
long *error);
184double dspbfct(
long *i1,
long *i2);
185double dpow_ri(
double *ap,
long *bp);
187long (*filter_funct[])(
STAGE *stage,
long filterNum, int64_t npoints) =
189 lowpass_function, highpass_function, proportional_function, analog_function, digital_function};
194int main(
int argc,
char *argv[]) {
197 char *inputfile, *outputfile, *xcolName, **ycolName, **ycolMatch;
198 long columnsupplied, totalFilterCount, totalStages, tmpfileUsed;
200 int32_t yColumns, ycolMatches;
201 long i, j, i_arg, filterNum, stageNum, currentFilter, currentStage, filterType, error;
202 unsigned long pipeFlags, majorOrderFlag;
203 char outColName[256], outColDesc[256];
205 short columnMajorOrder = -1;
213 argc =
scanargs(&s_arg, argc, argv);
222 inputfile = outputfile = xcolName = NULL;
223 ycolName = ycolMatch = NULL;
224 yColumns = ycolMatches = 0;
227 totalFilterCount = 0;
232 stage = (
STAGE *)malloc(
sizeof(*stage));
233 stage[0].filter = (
void *)malloc(
sizeof(*stage[0].filter));
234 stage[0].type = (
long *)malloc(
sizeof(*stage[0].type));
236 for (i_arg = 1; i_arg < argc; i_arg++) {
237 if (s_arg[i_arg].arg_type == OPTION) {
239 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
240 case CLO_MAJOR_ORDER:
242 s_arg[i_arg].n_items--;
243 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)))
244 SDDS_Bomb(
"invalid -majorOrder syntax/values");
245 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
246 columnMajorOrder = 1;
247 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
248 columnMajorOrder = 0;
251 if (s_arg[i_arg].n_items < 2)
253 LHptr = (
LOWHIGH *)malloc(
sizeof(*LHptr));
254 if (!
get_double(&(LHptr->gain), s_arg[i_arg].list[1]))
255 SDDS_Bomb(
"Invalid -lowpass value provided.");
256 if (s_arg[i_arg].n_items > 2 && !
get_double(&(LHptr->cutoff), s_arg[i_arg].list[2]))
257 SDDS_Bomb(
"Invalid -lowpass value provided.");
258 stage[stageNum].filter[filterNum] = LHptr;
259 stage[stageNum].type[filterNum] = CLO_LOWPASS;
260 stage[stageNum].numFilters = ++filterNum;
263 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
264 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
267 if (s_arg[i_arg].n_items < 2)
269 LHptr = (
LOWHIGH *)malloc(
sizeof(*LHptr));
270 if (!
get_double(&(LHptr->gain), s_arg[i_arg].list[1]))
271 SDDS_Bomb(
"Invalid -highpass value provided.");
272 if (s_arg[i_arg].n_items > 2 && !
get_double(&(LHptr->cutoff), s_arg[i_arg].list[2]))
273 SDDS_Bomb(
"Invalid -highpass value provided.");
274 stage[stageNum].filter[filterNum] = LHptr;
275 stage[stageNum].type[filterNum] = CLO_HIGHPASS;
276 stage[stageNum].numFilters = ++filterNum;
279 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
280 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
282 case CLO_PROPORTIONAL:
283 if (s_arg[i_arg].n_items != 2)
284 SDDS_Bomb(
"Invalid -proportional option.");
285 Gptr = (
GAIN *)malloc(
sizeof(*Gptr));
286 if (!
get_double(&(Gptr->gain), s_arg[i_arg].list[1]))
287 SDDS_Bomb(
"Invalid -proportional value provided.");
288 stage[stageNum].filter[filterNum] = Gptr;
289 stage[stageNum].type[filterNum] = CLO_PROPORTIONAL;
290 stage[stageNum].numFilters = ++filterNum;
293 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
294 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
296 case CLO_ANALOGFILTER:
297 if (s_arg[i_arg].n_items < 2)
298 SDDS_Bomb(
"Invalid -analogfilter option.");
299 ADptr = (
ANADIG *)malloc(
sizeof(*ADptr));
300 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
301 if (strcasecmp(s_arg[i_arg].list[1],
"C") == 0 || strcasecmp(s_arg[i_arg].list[1],
"D") == 0) {
302 processFilterParams(s_arg[i_arg].list, s_arg[i_arg].n_items,
"C",
"D", ADptr);
304 if (s_arg[i_arg].n_items != 4)
305 SDDS_Bomb(
"Invalid -analogfilter option for providing coefficient file and coefficient column names.");
306 processFilterParamsFromFile(s_arg[i_arg].list[1], s_arg[i_arg].list[2], s_arg[i_arg].list[3], ADptr);
308 stage[stageNum].filter[filterNum] = ADptr;
309 stage[stageNum].type[filterNum] = CLO_ANALOGFILTER;
310 stage[stageNum].numFilters = ++filterNum;
313 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
314 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
316 case CLO_DIGITALFILTER:
317 if (s_arg[i_arg].n_items < 2)
318 SDDS_Bomb(
"Invalid -digitalfilter option.");
319 ADptr = (
ANADIG *)malloc(
sizeof(*ADptr));
320 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
321 if (strcasecmp(s_arg[i_arg].list[1],
"A") == 0 || strcasecmp(s_arg[i_arg].list[1],
"B") == 0) {
322 processFilterParams(s_arg[i_arg].list, s_arg[i_arg].n_items,
"A",
"B", ADptr);
324 if (s_arg[i_arg].n_items != 4)
325 SDDS_Bomb(
"Invalid -digitalfilter option for providing coefficient file and coefficient column names.");
326 processFilterParamsFromFile(s_arg[i_arg].list[1], s_arg[i_arg].list[2], s_arg[i_arg].list[3], ADptr);
328 stage[stageNum].filter[filterNum] = ADptr;
329 stage[stageNum].type[filterNum] = CLO_DIGITALFILTER;
330 stage[stageNum].numFilters = ++filterNum;
333 stage[stageNum].filter = (
void *)realloc(stage[stageNum].filter,
sizeof(*stage[stageNum].filter) * (filterNum + 1));
334 stage[stageNum].type = (
long *)realloc(stage[stageNum].type,
sizeof(*stage[stageNum].type) * (filterNum + 1));
339 stage = (
STAGE *)realloc(stage,
sizeof(*stage) * (stageNum + 1));
340 stage[stageNum].filter = (
void *)malloc(
sizeof(*stage[stageNum].filter));
341 stage[stageNum].type = (
long *)malloc(
sizeof(*stage[stageNum].type));
343 stage[stageNum].numFilters = filterNum;
346 if (s_arg[i_arg].n_items < 3)
348 xcolName = s_arg[i_arg].list[1];
349 ycolMatches = s_arg[i_arg].n_items - 2;
350 ycolMatch = malloc(
sizeof(*ycolMatch) * ycolMatches);
351 for (i = 2; i < s_arg[i_arg].n_items; i++)
352 ycolMatch[i - 2] = s_arg[i_arg].list[i];
356 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
363 fprintf(stderr,
"Error (%s): unknown switch: %s\n", argv[0], s_arg[i_arg].list[0]);
368 if (inputfile == NULL)
369 inputfile = s_arg[i_arg].list[0];
370 else if (outputfile == NULL)
371 outputfile = s_arg[i_arg].list[0];
377 processFilenames(
"sddsdigfilter", &inputfile, &outputfile, pipeFlags, 1, &tmpfileUsed);
379 if (totalFilterCount == 0 || columnsupplied == 0) {
380 fprintf(stderr,
"no filter or no columns supplied.\n");
383 totalStages = stageNum + 1;
386 if (
SDDS_CheckColumn(&SDDS_input, xcolName, NULL, 0, stderr) != SDDS_CHECK_OKAY) {
387 fprintf(stderr,
"xColumn %s does not exist.\n", xcolName);
390 ycolName =
getMatchingSDDSNames(&SDDS_input, ycolMatch, ycolMatches, &yColumns, SDDS_MATCH_COLUMN);
391 for (i = 0; i < yColumns; i++) {
392 if (
SDDS_CheckColumn(&SDDS_input, ycolName[i], NULL, 0, stderr) != SDDS_CHECK_OKAY) {
393 fprintf(stderr,
"yColumn %s does not exist.\n", ycolName[i]);
399 if (columnMajorOrder != -1)
400 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
402 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
403 for (i = 0; i < yColumns; i++) {
404 sprintf(outColName,
"DigFiltered%s", ycolName[i]);
405 sprintf(outColDesc,
"Digital Filtered %s", ycolName[i]);
421 for (i = 0; i < yColumns; i++) {
422 sprintf(outColName,
"DigFiltered%s", ycolName[i]);
426 for (currentStage = 0; currentStage < totalStages; currentStage++) {
428 fprintf(stdout,
"STAGE %ld\n", currentStage);
431 stage[currentStage].time = xcol;
433 if (currentStage == 0) {
434 stage[currentStage].input = ycol;
436 stage[currentStage].input = stage[currentStage - 1].output;
439 stage[currentStage].output = (
double *)calloc(npoints,
sizeof(*stage[currentStage].output));
441 for (currentFilter = 0; currentFilter < stage[currentStage].numFilters; currentFilter++) {
443 fprintf(stdout,
"filter %ld\n", currentFilter);
446 filterType = stage[currentStage].type[currentFilter];
447 error = (*filter_funct[filterType])(&(stage[currentStage]), currentFilter, npoints);
449 fprintf(stderr,
"nyquist violation.\n");
462 for (currentStage = 0; currentStage < totalStages; currentStage++)
463 free(stage[currentStage].output);
472 for (i = 0; i < totalStages; i++) {
473 for (j = 0; j < stage[i].numFilters; j++) {
474 switch (stage[i].type[j]) {
475 case CLO_ANALOGFILTER:
476 case CLO_DIGITALFILTER:
477 free(((
ANADIG *)(stage[i].filter[j]))->ACcoeff);
478 free(((
ANADIG *)(stage[i].filter[j]))->BDcoeff);
479 free((
ANADIG *)(stage[i].filter[j]));
481 case CLO_PROPORTIONAL:
482 free((
GAIN *)(stage[i].filter[j]));
486 free((
LOWHIGH *)(stage[i].filter[j]));
490 free(stage[i].filter);
498 return (EXIT_SUCCESS);
503long lowpass_function(
STAGE *stage,
long filterNum, int64_t npoints) {
505 double C_coeff[2] = {1.0, 1.0};
506 double D_coeff[2] = {1.0, 0.0};
508 double A_coeff[2], B_coeff[2];
509 double timePerPoint, normFrequency;
510 double *work, *tmpoutput;
517 filter_ptr = stage->filter[filterNum];
519 timePerPoint = (stage->time[1]) - (stage->time[0]);
520 if (timePerPoint < 0)
521 timePerPoint *= -1.0;
523 if (filter_ptr->gain == 0.0) {
524 for (i = 0; i < npoints; i++) {
525 stage->output[i] = 0.0;
530 work = (
double *)calloc(npoints,
sizeof(*work));
531 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
533 normFrequency = timePerPoint * (filter_ptr->cutoff);
536 dspfblt(D_coeff, C_coeff, 1, 1, normFrequency, 0.0, B_coeff, A_coeff, work, &error);
543 A_coeff[1] = A_coeff[0];
547 fprintf(stdout,
"a0: %f\tb0: %f\n", A_coeff[0], B_coeff[0]);
548 fprintf(stdout,
"a1: %f\tb1: %f\n\n", A_coeff[1], B_coeff[1]);
552 if (response(stage->input, tmpoutput, npoints, npoints, B_coeff, A_coeff, 2, 2)) {
553 fprintf(stderr,
"Invalid coeffs in lowpass filter.\n");
560 for (i = 0; i < npoints; i++) {
561 stage->output[i] += (filter_ptr->gain) * tmpoutput[i];
573long highpass_function(
STAGE *stage,
long filterNum, int64_t npoints) {
575 double C_coeff[] = {1.0, 1.0};
576 double D_coeff[] = {1.0, 0.0};
578 double A_coeff[2], B_coeff[2];
579 double timePerPoint, normFrequency;
580 double *work, *tmpoutput;
587 filter_ptr = stage->filter[filterNum];
589 timePerPoint = (stage->time[1]) - (stage->time[0]);
590 if (timePerPoint < 0)
591 timePerPoint *= -1.0;
593 if (filter_ptr->gain == 0.0) {
594 for (i = 0; i < npoints; i++) {
595 stage->output[i] = 0.0;
600 work = (
double *)calloc(npoints,
sizeof(*work));
601 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
603 normFrequency = timePerPoint * (filter_ptr->cutoff);
606 dspfblt(D_coeff, C_coeff, 1, 2, normFrequency, 0.0, B_coeff, A_coeff, work, &error);
613 A_coeff[1] = A_coeff[0];
617 fprintf(stdout,
"a0: %6.6g\tb0: %6.6g\n", A_coeff[0], B_coeff[0]);
618 fprintf(stdout,
"a1: %6.6g\tb1: %6.6g\n\n", A_coeff[1], B_coeff[1]);
622 if (response(stage->input, tmpoutput, npoints, npoints, B_coeff, A_coeff, 2, 2)) {
623 fprintf(stderr,
"invalid coeffs in highpass filter.\n");
630 for (i = 0; i < npoints; i++) {
631 stage->output[i] += (filter_ptr->gain) * tmpoutput[i];
644long digital_function(
STAGE *stage,
long filterNum, int64_t npoints) {
652 filter_ptr = stage->filter[filterNum];
654 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
657 for (i = 0; i < filter_ptr->ncoeffs; i++) {
658 fprintf(stdout,
"a%" PRId64
": %6.6g\tb%" PRId64
" %6.6g\n", i, filter_ptr->ACcoeff[i], i, filter_ptr->BDcoeff[i]);
663 if (response(stage->input, tmpoutput, npoints, npoints, filter_ptr->BDcoeff, filter_ptr->ACcoeff, (filter_ptr->ncoeffs), (filter_ptr->ncoeffs))) {
664 fprintf(stderr,
"Invalid coefficients in digitalfilter.\n");
670 for (i = 0; i < npoints; i++) {
671 stage->output[i] += tmpoutput[i];
683long analog_function(
STAGE *stage,
long filterNum, int64_t npoints) {
684 double sampleFrequency, sampleTime;
685 double *tmpoutput, *work;
686 double *Bcoeff, *Acoeff;
692 filter_ptr = stage->filter[filterNum];
693 work = (
double *)calloc(npoints,
sizeof(*work));
694 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
695 Bcoeff = (
double *)calloc(filter_ptr->ncoeffs,
sizeof(*Bcoeff));
696 Acoeff = (
double *)calloc(filter_ptr->ncoeffs,
sizeof(*Acoeff));
701 sampleTime = (stage->time[1] - stage->time[0]);
702 sampleFrequency = 2.0 / sampleTime;
703 if (sampleFrequency < 0.0)
704 sampleFrequency *= -1.0;
706 for (i = 0; i < filter_ptr->ncoeffs; i++) {
707 filter_ptr->BDcoeff[i] *= pow(sampleFrequency, i);
708 filter_ptr->ACcoeff[i] *= pow(sampleFrequency, i);
712 dspbiln(filter_ptr->BDcoeff, filter_ptr->ACcoeff, (filter_ptr->ncoeffs) - 1, Bcoeff, Acoeff, work, &error);
714 fprintf(stderr,
"Error(%ld): invalid or all-zero analog transfer function\n", error);
723 for (i = filter_ptr->ncoeffs - 1; i > 0; i--) {
724 Acoeff[i] = Acoeff[i - 1];
729 for (i = 0; i < filter_ptr->ncoeffs; i++) {
730 fprintf(stdout,
"c%" PRId64
": %6.6g\td%" PRId64
": %6.6g\ta%" PRId64
": %6.6g\tb%" PRId64
": %6.6g\n",
731 i, filter_ptr->ACcoeff[i],
732 i, filter_ptr->BDcoeff[i],
739 if (response(stage->input, tmpoutput, npoints, npoints, Bcoeff, Acoeff, (filter_ptr->ncoeffs), (filter_ptr->ncoeffs))) {
740 fprintf(stderr,
"Invalid coefficients in analogfilter.\n");
749 for (i = 0; i < npoints; i++) {
750 stage->output[i] += tmpoutput[i];
766long proportional_function(
STAGE *stage,
long filterNum, int64_t npoints) {
772 tmpoutput = (
double *)calloc(npoints,
sizeof(*tmpoutput));
773 filter_ptr = stage->filter[filterNum];
775 for (i = 0; i < npoints; i++) {
776 tmpoutput[i] = (stage->input[i]) * (filter_ptr->gain);
780 for (i = 0; i < npoints; i++) {
781 stage->output[i] += tmpoutput[i];
792long response(
double *input,
double *output, int64_t nInput, int64_t nOutput,
double *Bcoeff,
double *Acoeff, int64_t nBcoeffs, int64_t nAcoeffs) {
805 int64_t k, n, m, max, inputPoint;
807 if (Acoeff[0] == 0.0 || nAcoeffs < 1 || nBcoeffs < 1) {
811 for (k = 0; k < nOutput; k++) {
814 max = (k < nBcoeffs) ? k : nBcoeffs;
815 for (n = 0; n < max; n++) {
818 inputPoint = ((k - n) < nInput) ? (k - n) : (nInput - 1);
819 output[k] += Bcoeff[n] * input[inputPoint];
823 max = (k < nAcoeffs) ? k : nAcoeffs;
824 for (m = 1; m < max; m++) {
826 output[k] -= Acoeff[m] * output[k - m];
830 output[k] /= Acoeff[0];
856void dspbiln(
double *d,
double *c, int64_t ln,
double *b,
double *a,
double *work,
long *error) {
859 int64_t i, j, l, work_dim1;
866 for (i = ln; i >= 0 && zero_func; --i) {
867 if (c[i] != 0.0 || d[i] != 0.0) {
880 for (j = 0; j <= l; ++j) {
881 work[j * work_dim1] = 1.0;
885 for (i = 1; i <= l; ++i) {
886 tmp = tmp * (double)(l - i + 1) / (double)i;
890 for (i = 1; i <= l; ++i) {
891 for (j = 1; j <= l; ++j) {
892 work[i + j * work_dim1] = work[i + (j - 1) * work_dim1] - work[i - 1 + j * work_dim1] - work[i - 1 + (j - 1) * work_dim1];
896 for (i = l; i >= 0; --i) {
900 for (j = 0; j <= l; ++j) {
901 b[i] += work[i + j * work_dim1] * d[j];
902 atmp += (double)work[i + j * work_dim1] * c[j];
905 scale = (double)atmp;
908 a[i - 1] = (double)atmp;
918 for (i = 1; i <= l; ++i) {
924 for (i = l + 1; i <= ln; ++i) {
958void dspfblt(
double *d,
double *c,
long ln,
long iband,
double fln,
double fhn,
double *b,
double *a,
double *work,
long *error) {
960 long work_dim1, tmp_int, i, k, l, m, zero_func, ll, mm, ls;
961 double tmpc, tmpd, w = 0, w1, w2, w02 = 0, tmp;
963 if (iband < 1 || iband > 4) {
967 if ((fln <= 0.0 || fln > 0.5) || (iband >= 3 && (fln >= fhn || fhn > 0.5))) {
973 for (i = ln; i >= 0 && zero_func; --i) {
974 if (c[i] != 0.0 || d[i] != 0.0) {
987 w1 = (double)tan(PI * fln);
991 w2 = (double)tan(PI * fhn);
1006 for (mm = 0; mm <= m; ++mm) {
1007 d[mm] /= dpow_ri(&w1, &mm);
1008 c[mm] /= dpow_ri(&w1, &mm);
1017 for (mm = 0; mm <= (m / 2); ++mm) {
1028 for (mm = 0; mm <= m; ++mm) {
1029 d[mm] /= dpow_ri(&w1, &mm);
1030 c[mm] /= dpow_ri(&w1, &mm);
1039 for (ll = 0; ll <= l; ++ll) {
1041 work[ll + work_dim1] = 0.0;
1044 for (mm = 0; mm <= m; ++mm) {
1046 tmpd = d[mm] * dpow_ri(&w, &tmp_int);
1047 tmpc = c[mm] * dpow_ri(&w, &tmp_int);
1049 for (k = 0; k <= mm; ++k) {
1050 ls = m + mm - (k * 2);
1052 tmp = dspbfct(&mm, &mm) / (dspbfct(&k, &k) * dspbfct(&tmp_int, &tmp_int));
1053 work[ls] += tmpd * dpow_ri(&w02, &k) * tmp;
1054 work[ls + work_dim1] += tmpc * dpow_ri(&w02, &k) * tmp;
1058 for (ll = 0; ll <= l; ++ll) {
1060 c[ll] = work[ll + work_dim1];
1069 for (mm = 0; mm <= (m / 2); ++mm) {
1080 for (ll = 0; ll <= l; ++ll) {
1082 work[ll + work_dim1] = 0.0;
1085 for (mm = 0; mm <= m; ++mm) {
1087 tmpd = d[mm] * dpow_ri(&w, &tmp_int);
1088 tmpc = c[mm] * dpow_ri(&w, &tmp_int);
1090 for (k = 0; k <= mm; ++k) {
1091 ls = m + mm - (k * 2);
1093 tmp = dspbfct(&mm, &mm) / (dspbfct(&k, &k) * dspbfct(&tmp_int, &tmp_int));
1094 work[ls] += tmpd * dpow_ri(&w02, &k) * tmp;
1095 work[ls + work_dim1] += tmpc * dpow_ri(&w02, &k) * tmp;
1099 for (ll = 0; ll <= l; ++ll) {
1101 c[ll] = work[ll + work_dim1];
1107 dspbiln(d, c, ln, b, a, work, error);
1120double dspbfct(
long *i1,
long *i2) {
1126 if (*i1 < 0 || *i2 < 0 || *i2 > *i1) {
1131 for (i = *i1; i >= (*i1 - *i2 + 1); --i) {
1132 ret_val *= (double)i;
1141double dpow_ri(
double *ap,
long *bp) {
1177long processFilterParams(
char **args,
long items,
char *firstStr,
char *nextStr,
ANADIG *ADptr) {
1178 long a, b, aFlag, bFlag, i;
1180 a = b = aFlag = bFlag = 0;
1181 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
1182 for (i = 1; i < items; i++) {
1183 if (strcasecmp(args[i], firstStr) == 0) {
1186 }
else if (strcasecmp(args[i], nextStr) == 0) {
1191 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * (a + 1));
1192 if (!
get_double(&(ADptr->ACcoeff[a]), args[i]))
1193 SDDS_Bomb(
"Invalid filter coefficient provided.");
1197 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * (b + 1));
1198 if (!
get_double(&(ADptr->BDcoeff[b]), args[i]))
1199 SDDS_Bomb(
"Invalid filter coefficient provided.");
1204 if (a == 0 && b == 0)
1207 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * (a + 1));
1208 ADptr->ACcoeff[0] = 1.0;
1212 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * (b + 1));
1213 ADptr->BDcoeff[0] = 1.0;
1216 ADptr->ncoeffs = a > b ? a : b;
1217 if (a < ADptr->ncoeffs) {
1218 ADptr->ACcoeff =
SDDS_Realloc(ADptr->ACcoeff,
sizeof(*(ADptr->ACcoeff)) * ADptr->ncoeffs);
1219 for (i = a; i < ADptr->ncoeffs; i++)
1220 ADptr->ACcoeff[i] = 0.0;
1222 if (b < ADptr->ncoeffs) {
1223 ADptr->BDcoeff =
SDDS_Realloc(ADptr->BDcoeff,
sizeof(*(ADptr->BDcoeff)) * ADptr->ncoeffs);
1224 for (i = b; i < ADptr->ncoeffs; i++)
1225 ADptr->BDcoeff[i] = 0.0;
1230long processFilterParamsFromFile(
char *filename,
char *ACColumn,
char *BDColumn,
ANADIG *ADptr) {
1234 fprintf(stderr,
"error: problem reading %s\n", filename);
1235 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1238 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1240 fprintf(stderr,
"error: problem counting rows in file %s\n", filename);
1241 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1243 ADptr->ncoeffs = rows;
1244 ADptr->ACcoeff = ADptr->BDcoeff = NULL;
1246 fprintf(stderr,
"error: unable to read AC coefficient column.\n");
1247 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1250 fprintf(stderr,
"error: unable to read BD coefficient column.\n");
1251 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1254 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.
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.
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.