32long SavitzkyGolaySmooth(
double *data,
long rows,
long order,
long nLeft,
long nRight,
long derivativeOrder) {
33 static double *FFTdata = NULL, *FFTfilter = NULL, *TMPdata = NULL;
34 static long arraySize = 0, TMParraySize = 0;
35 long i, nfreq, sizeNeeded;
38 fprintf(stderr,
"order<0 (SavitzkyGolaySmooth)\n");
42 fprintf(stderr,
"nLeft<0 (SavitzkyGolaySmooth)\n");
46 fprintf(stderr,
"nRight<0 (SavitzkyGolaySmooth)\n");
49 if (derivativeOrder < 0) {
50 fprintf(stderr,
"derivativeOrder<0 (SavitzkyGolaySmooth)\n");
53 if (derivativeOrder > order) {
54 fprintf(stderr,
"derivativeOrder>order (SavitzkyGolaySmooth)\n");
57 if ((nLeft + nRight) < order) {
58 fprintf(stderr,
"(nLeft+nRight)<order (SavitzkyGolaySmooth)\n");
61 if ((nLeft + nRight) == 0) {
62 fprintf(stderr,
"(nLeft+nRight)==0 (SavitzkyGolaySmooth)\n");
65 if (rows < (nLeft + nRight + 1)) {
66 fprintf(stderr,
"rows<(nLeft+nRight+1) (SavitzkyGolaySmooth)\n");
70 if ((order == 1) && (nLeft == nRight) && (derivativeOrder == 0)) {
73 long np = nLeft + nRight + 1;
74 double scale = 1.0 / np;
77 if (TMParraySize < sizeNeeded && (!(TMPdata = realloc(TMPdata,
sizeof(*TMPdata) * (TMParraySize = sizeNeeded))))) {
78 fprintf(stderr,
"Error: memory allocation failure (SavitzkyGolaySmooth)\n");
82 for (i = 0; i < rows; i++) {
83 data[i] = scale * data[i];
88 for (i = 1; i <= nRight; i++)
90 data[0] += nLeft * TMPdata[0];
92 for (i = 1; i <= nLeft; i++) {
93 data[i] = data[i - 1] + data[i + nRight] - TMPdata[0];
97 for (i = nLeft + 1; i < rows - nRight; i++) {
98 data[i] = data[i - 1] + data[i + nRight] - TMPdata[i - nLeft - 1];
102 for (i = rows - nRight; i < rows; i++) {
103 data[i] = data[i - 1] + data[rows - 1] - TMPdata[i - nLeft - 1];
108 long np = nLeft + nRight + 1, j;
109 static long coeffArraySize = 0;
110 static double *filterCoeff = NULL;
112 sizeNeeded = rows + nLeft + nRight;
113 if (TMParraySize < sizeNeeded && (!(TMPdata = realloc(TMPdata,
sizeof(*TMPdata) * (TMParraySize = sizeNeeded))))) {
114 fprintf(stderr,
"Error: memory allocation failure (SavitzkyGolaySmooth)\n");
117 if (coeffArraySize < np && (!(filterCoeff = realloc(filterCoeff,
sizeof(*filterCoeff) * (coeffArraySize = np))))) {
118 fprintf(stderr,
"Error: memory allocation failure (SavitzkyGolaySmooth)\n");
123 for (i = 0; i < rows; i++)
124 TMPdata[i + nLeft] = data[i];
125 for (i = 0; i < nLeft; i++)
126 TMPdata[i] = data[0];
127 for (i = 0; i < nRight; i++)
128 TMPdata[rows + nLeft + i] = data[rows - 1];
131 SavitzkyGolayCoefficients(filterCoeff, np, order, nLeft, nRight, derivativeOrder, 1);
133 for (i = 0; i < rows; i++) {
134 data[i] = data[i] * filterCoeff[0];
135 for (j = 1; j <= nLeft; j++)
136 data[i] += TMPdata[i + nLeft - j] * filterCoeff[j];
137 for (j = 1; j <= nRight; j++)
138 data[i] += TMPdata[i + nLeft + j] * filterCoeff[np - j];
144 sizeNeeded = 2 * (rows + 1 + nLeft + nRight);
145 if (arraySize < sizeNeeded && (!(FFTdata = realloc(FFTdata,
sizeof(*FFTdata) * (arraySize = sizeNeeded))) || !(FFTfilter = realloc(FFTfilter,
sizeof(*FFTfilter) * (arraySize = sizeNeeded))))) {
146 fprintf(stderr,
"Error: memory allocation failure (SavitzkyGolaySmooth)\n");
149 for (i = 0; i < arraySize; i++)
150 FFTdata[i] = FFTfilter[i] = 0;
153 SavitzkyGolayCoefficients(FFTfilter, 2 * (rows + nLeft + nRight), order, nLeft, nRight, derivativeOrder, 1);
156 for (i = 0; i < rows; i++)
157 FFTdata[i + nLeft] = data[i];
158 for (i = 0; i < nLeft; i++)
159 FFTdata[i] = data[0];
160 for (i = 0; i < nRight; i++)
161 FFTdata[rows + nLeft + i] = data[rows - 1];
164 realFFT2(FFTdata, FFTdata, 2 * (rows + nLeft + nRight), 0);
165 realFFT2(FFTfilter, FFTfilter, 2 * (rows + nLeft + nRight), 0);
168 nfreq = rows + nLeft + nRight + 1;
169 for (i = 0; i < nfreq; i++)
170 complex_multiply(FFTdata + 2 * i, FFTdata + 2 * i + 1, FFTdata[2 * i], FFTdata[2 * i + 1], FFTfilter[2 * i], FFTfilter[2 * i + 1]);
173 realFFT2(FFTdata, FFTdata, 2 * (rows + nLeft + nRight), INVERSE_FFT);
174 for (i = 0; i < rows; i++)
175 data[i] = FFTdata[i + nLeft] * 2 * (rows + nLeft + nRight);