26 static double *vector(
long n)
31 v = (
double *)malloc((
size_t)((n + 1) *
sizeof(
double)));
45 v = (
int *)malloc((
size_t)((n + 1) *
sizeof(
int)));
54 static double **matrix(
long nr,
long nc)
65 m = (
double **) malloc((
size_t)((nrow + 1) *
sizeof(
double *)));
72 m[0] = (
double *) malloc((
size_t)((nrow * ncol + 1) *
sizeof(
double)));
78 for(i = 1; i <=
nr; i++) m[i] = m[i-1] + ncol;
84 static void free_matrix(
double **a) {
91 static int minarg1, minarg2;
92 #define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
93 (minarg1) : (minarg2))
106 static void lubksb(
double **a,
int n,
int *indx,
double b[]) {
107 int i, ii = 0, ip, j;
110 for(i = 1; i <=
n; i++) {
115 for(j = ii; j <= i - 1; j++) sum -= a[i][j] * b[j];
119 for(i = n; i >= 1; i--) {
121 for(j = i + 1; j <=
n; j++) sum -= a[i][j] * b[j];
122 b[i] = sum / a[i][i];
126 #define TINY 1.0e-20;
137 static void ludcmp(
double **a,
int n,
int *indx,
double *d) {
138 int i, imax = -1, j, k;
139 double big, dum,
sum, temp;
144 for(i = 1; i <=
n; i++) {
146 for(j = 1; j <=
n; j++)
147 if((temp =
fabs(a[i][j])) > big) big = temp;
156 for(j = 1; j <=
n; j++) {
157 for(i = 1; i < j; i++) {
159 for(k = 1; k < i; k++) sum -= a[i][k] * a[k][j];
163 for(i = j; i <=
n; i++) {
165 for(k = 1; k < j; k++)
166 sum -= a[i][k] * a[k][j];
168 if((dum = vv[i] *
fabs(sum)) >= big) {
174 for(k = 1; k <=
n; k++) {
176 a[imax][k] = a[j][k];
183 if(a[j][j] == 0.0) a[j][j] =
TINY;
185 dum = 1.0 / (a[j][j]);
186 for(i = j + 1; i <=
n; i++) a[i][j] *= dum;
206 void savgol(
double c[],
int np,
int nl,
int nr,
int ld,
int m) {
207 int imj, ipj, j, k, kk, mm, *indx;
208 double d, fac,
sum, **a, *b;
210 if(np < nl + nr + 1 || nl < 0 || nr < 0 || ld > m || nl + nr < m) {
216 a = matrix(m + 1, m + 1);
218 for(ipj = 0; ipj <= (m << 1); ipj++) {
219 sum = (ipj ? 0.0 : 1.0);
220 for(k = 1; k <=
nr; k++) sum +=
pow((
double)k, ipj);
221 for(k = 1; k <= nl; k++) sum +=
pow((
double) - k, ipj);
222 mm =
FMIN(ipj, 2 * m - ipj);
223 for(imj = -mm; imj <= mm; imj += 2) a[1+(ipj+imj)/2][1+(ipj-imj)/2] = sum;
225 ludcmp(a, m + 1, indx, &d);
226 for(j = 1; j <= m + 1; j++) b[j] = 0.0;
228 lubksb(a, m + 1, indx, b);
229 for(kk = 1; kk <= np; kk++) c[kk] = 0.0;
230 for(k = -nl; k <=
nr; k++) {
233 for(mm = 1; mm <= m; mm++) sum += b[mm+1] * (fac *= k);
234 kk = ((np - k) % np) + 1;
244 #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
253 void four1(
double data[],
int nn,
int isign) {
254 int n, mmax, m, j, istep, i;
255 double wtemp, wr, wpr, wpi, wi, theta;
260 for(i = 1; i <
n; i += 2) {
262 SWAP(data[j], data[i]);
263 SWAP(data[j+1], data[i+1]);
266 while(m >= 2 && j > m) {
275 theta = isign * (6.28318530717959 / mmax);
276 wtemp =
sin(0.5 * theta);
277 wpr = -2.0 * wtemp * wtemp;
281 for(m = 1; m < mmax; m += 2) {
282 for(i = m; i <=
n; i += istep) {
284 tempr = wr * data[j] - wi * data[j+1];
285 tempi = wr * data[j+1] + wi * data[j];
286 data[j] = data[i] - tempr;
287 data[j+1] = data[i+1] - tempi;
291 wr = (wtemp = wr) * wpr - wi * wpi + wr;
292 wi = wi * wpr + wtemp * wpi + wi;
309 static void realft(
double data[],
int n,
int isign) {
310 void four1(
double data[],
int nn,
int isign);
311 int i, i1, i2, i3, i4, np3;
312 double c1 = 0.5, c2, h1r, h1i, h2r, h2i;
313 double wr, wi, wpr, wpi, wtemp, theta;
315 theta = 3.141592653589793 / (double)(n >> 1);
318 four1(data, n >> 1, 1);
323 wtemp =
sin(0.5 * theta);
324 wpr = -2.0 * wtemp * wtemp;
329 for(i = 2; i <= (n >> 2); i++) {
330 i4 = 1 + (i3 = np3 - (i2 = 1 + (i1 = i + i - 1)));
331 h1r = c1 * (data[i1] + data[i3]);
332 h1i = c1 * (data[i2] - data[i4]);
333 h2r = -c2 * (data[i2] + data[i4]);
334 h2i = c2 * (data[i1] - data[i3]);
335 data[i1] = h1r + wr * h2r - wi * h2i;
336 data[i2] = h1i + wr * h2i + wi * h2r;
337 data[i3] = h1r - wr * h2r + wi * h2i;
338 data[i4] = -h1i + wr * h2i + wi * h2r;
339 wr = (wtemp = wr) * wpr - wi * wpi + wr;
340 wi = wi * wpr + wtemp * wpi + wi;
343 data[1] = (h1r = data[1]) + data[2];
344 data[2] = h1r - data[2];
346 data[1] = c1 * ((h1r = data[1]) + data[2]);
347 data[2] = c1 * (h1r - data[2]);
348 four1(data, n >> 1, -1);
359 static void twofft(
double data1[],
double data2[],
double fft1[],
double fft2[],
361 void four1(
double data[],
int nn,
int isign);
363 double rep, rem, aip, aim;
365 nn3 = 1 + (nn2 = 2 + n +
n);
366 for(j = 1, jj = 2; j <=
n; j++, jj += 2) {
367 fft1[jj-1] = data1[j];
372 fft1[2] = fft2[2] = 0.0;
373 for(j = 3; j <= n + 1; j += 2) {
374 rep = 0.5 * (fft1[j] + fft1[nn2-j]);
375 rem = 0.5 * (fft1[j] - fft1[nn2-j]);
376 aip = 0.5 * (fft1[j+1] + fft1[nn3-j]);
377 aim = 0.5 * (fft1[j+1] - fft1[nn3-j]);
390 #define SQR(a) (a == 0.0 ? 0.0 : a*a)//sqrarg*sqrarg)
406 void convlv(
double data[],
int n,
double respns[],
int m,
407 int isign,
double ans[]) {
409 double dum, mag2, *fft;
411 fft = vector(n << 1);
413 for(i = 1; i <= (m - 1) / 2; i++)
414 respns[n+1-i] = respns[m+1-i];
415 for(i = (m + 3) / 2; i <= n - (m - 1) / 2; i++)
417 twofft(data, respns, fft, ans, n);
419 for(i = 2; i <= n + 2; i += 2) {
421 ans[i-1] = (fft[i-1] * (dum = ans[i-1]) - fft[i] * ans[i]) / no2;
422 ans[i] = (fft[i] * dum + fft[i-1] * ans[i]) / no2;
423 }
else if(isign == -1) {
424 if((mag2 =
SQR(ans[i-1]) +
SQR(ans[i])) == 0.0) {
427 writeBetError(
"savgol.C Deconvoloving at repsonse zero in convlv");
430 ans[i-1] = (fft[i-1] * (dum = ans[i-1]) + fft[i] * ans[i]) / mag2 / no2;
431 ans[i] = (fft[i] * dum - fft[i-1] * ans[i]) / mag2 / no2;
457 void sgSmooth(
double *
c,
int n,
int nl,
int nr,
int ld,
int m) {
466 nn = (int)
pow(2.0, (
int)(
log(1.0 * n) /
log(2.0)) + 1);
472 cOut = vector(nn * 2);
476 memcpy(&cIn[1], c,
sizeof(
double)*n);
477 for(i = n + 1; i <= nn; i++) cIn[i] = 0.0;
481 if((np % 2) == 0) ++np;
482 savgol(cf, np, nl, nr, ld, m);
486 convlv(cIn, nn, cf, np, isign, cOut);
489 memcpy(c, &cOut[1],
sizeof(
double)*n);
void sgSmooth(double *c, int n, int nl, int nr, int ld, int m)
void writeBetError(std::string err)
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Tps< T > sin(const Tps< T > &x)
Sine.
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Tps< T > log(const Tps< T > &x)
Natural logarithm.
void savgol(double c[], int np, int nl, int nr, int ld, int m)
void convlv(double data[], int n, double respns[], int m, int isign, double ans[])
constexpr double c
The velocity of light in m/s.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
void four1(double data[], int nn, int isign)