OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
SavitzkyGolay.cpp
Go to the documentation of this file.
2 #include "gsl/gsl_fft_real.h"
3 #include "gsl/gsl_fft_halfcomplex.h"
4 #include <iostream>
5 
6 using namespace std;
7 
8 SavitzkyGolayFilter::SavitzkyGolayFilter(int np, int nl, int nr, int m):
9  NumberPoints_m(np),
10  NumberPointsLeft_m(nl),
11  NumberPointsRight_m(nr),
12  PolynomialOrder_m(m),
13  Coefs_m(np, 0.0),
14  CoefsDeriv_m(np, 0.0) {
17 }
18 
19 void SavitzkyGolayFilter::apply(vector<double> &LineDensity) {
20  vector<double> temp(LineDensity.size(), 0.0);
21  convlv(LineDensity, Coefs_m, 1, temp);
22  LineDensity.assign(temp.begin(), temp.end());
23 }
24 
25 void SavitzkyGolayFilter::calc_derivative(vector<double> &LineDensity, const double &h) {
26  vector<double> temp(LineDensity.size(), 0.0);
27  convlv(LineDensity, CoefsDeriv_m, 1, temp);
28  LineDensity.assign(temp.begin(), temp.end());
29 }
30 
31 
32 void savgol(vector<double> &c, const int &np, const int &nl, const int &nr, const int &ld, const int &m) {
33  int j, k, imj, ipj, kk, mm;
34  double d, fac, sum;
35 
36  if(np < nl + nr + 1 || nl < 0 || nr < 0 || ld > m || nl + nr < m) {
37  cerr << "bad args in savgol" << endl;
38  return;
39  }
40  vector<int> indx(m + 1, 0);
41  vector<double> a((m + 1) * (m + 1), 0.0);
42  vector<double> b(m + 1, 0.0);
43 
44  for(ipj = 0; ipj <= (m << 1); ++ipj) {
45  sum = (ipj ? 0.0 : 1.0);
46  for(k = 1; k <= nr; ++k)
47  sum += (int)pow((double)k, (double)ipj);
48  for(k = 1; k <= nl; ++k)
49  sum += (int)pow((double) - k, (double)ipj);
50  mm = (ipj < 2 * m - ipj ? ipj : 2 * m - ipj);
51  for(imj = -mm; imj <= mm; imj += 2)
52  a[(ipj + imj) / 2 * (m + 1) + (ipj - imj) / 2] = sum;
53  }
54  ludcmp(a, indx, d);
55 
56  for(j = 0; j < m + 1; ++j)
57  b[j] = 0.0;
58  b[ld] = 1.0;
59 
60  lubksb(a, indx, b);
61  for(kk = 0; kk < np; ++kk)
62  c[kk] = 0.0;
63  for(k = -nl; k <= nr; ++k) {
64  sum = b[0];
65  fac = 1.0;
66  for(mm = 1; mm <= m; ++mm)
67  sum += b[mm] * (fac *= k);
68  kk = (np - k) % np;
69  c[kk] = sum;
70  }
71 
72 }
73 
74 void convlv(const vector<double> &data, const vector<double> &respns, const int &isign, vector<double> &ans) {
75  int n = data.size();
76  int m = respns.size();
77 
78  double tmp;
79 
80  double *tempfd1 = new double[n];
81  double *tempfd2 = new double[n];
82 
83  gsl_fft_halfcomplex_wavetable *hc;
84  gsl_fft_real_wavetable *real = gsl_fft_real_wavetable_alloc(n);
85  gsl_fft_real_workspace *work = gsl_fft_real_workspace_alloc(n);
86 
87 
88  for(int i = 0; i < n; ++ i) {
89  tempfd1[i] = 0.0;
90  tempfd2[i] = data[i];
91  }
92 
93  tempfd1[0] = respns[0];
94  for(int i = 1; i < (m + 1) / 2; ++i) {
95  tempfd1[i] = respns[i];
96  tempfd1[n - i] = respns[m - i];
97  }
98 
99  gsl_fft_real_transform(tempfd1, 1, n, real, work);
100  gsl_fft_real_transform(tempfd2, 1, n, real, work);
101 
102  gsl_fft_real_wavetable_free(real);
103  hc = gsl_fft_halfcomplex_wavetable_alloc(n);
104 
105  if(isign == 1) {
106  for(int i = 1; i < n - 1; i += 2) {
107  tmp = tempfd1[i];
108  tempfd1[i] = (tempfd1[i] * tempfd2[i] - tempfd1[i + 1] * tempfd2[i + 1]);
109  tempfd1[i + 1] = (tempfd1[i + 1] * tempfd2[i] + tmp * tempfd2[i + 1]);
110  }
111  tempfd1[0] *= tempfd2[0];
112  tempfd1[n - 1] *= tempfd2[n - 1];
113  }
114 
115  gsl_fft_halfcomplex_inverse(tempfd1, 1, n, hc, work);
116 
117  for(int i = 0; i < n; ++i) {
118  ans[i] = tempfd1[i];
119  }
120 
121  gsl_fft_halfcomplex_wavetable_free(hc);
122  gsl_fft_real_workspace_free(work);
123 
124  delete[] tempfd1;
125  delete[] tempfd2;
126 }
127 
128 void ludcmp(vector<double> &a, vector<int> &indx, double &d) {
129  const double TINY = 1.0e-20;
130  int i, imax = -1, j, k;
131  double big, dum, sum, temp;
132 
133  int n = indx.size();
134  vector<double> vv(n, 0.0);
135 
136  d = 1.0;
137  for(i = 0; i < n; ++i) {
138  big = 0.0;
139  for(j = 0; j < n; ++j)
140  if((temp = fabs(a[i * n + j])) > big) big = temp;
141 
142  if(big == 0.0) {
143  cerr << "Singular matrix in routine ludcmp" << endl;
144  return;
145  }
146  vv[i] = 1. / big;
147  }
148 
149  for(j = 0; j < n; ++j) {
150  for(i = 0; i < j; ++i) {
151  sum = a[i * n + j];
152  for(k = 0; k < i; ++k)
153  sum -= a[i * n + k] * a[k * n + j];
154  a[i * n + j] = sum;
155  }
156  big = 0.0;
157  for(i = j; i < n; ++i) {
158  sum = a[i * n + j];
159  for(k = 0; k < j; ++k)
160  sum -= a[i * n + k] * a[k * n + j];
161  a[i * n + j] = sum;
162  if((dum = vv[i] * fabs(sum)) >= big) {
163  big = dum;
164  imax = i;
165  }
166  }
167 
168  if(j != imax) {
169  for(k = 0; k < n; ++k) {
170  dum = a[imax * n + k];
171  a[imax * n + k] = a[j * n + k];
172  a[j * n + k] = dum;
173  }
174  d = -d;
175  vv[imax] = vv[j];
176  }
177  indx[j] = imax;
178  if(a[j * n + j] == 0.0) a[j * n + j] = TINY;
179  if(j != n - 1) {
180  dum = 1. / a[j * n + j];
181  for(i = j + 1; i < n; ++i)
182  a[i * n + j] *= dum;
183  }
184  }
185 }
186 
187 void lubksb(vector<double> &a, vector<int> &indx, vector<double> &b) {
188  int i, ii = 0, ip, j;
189  double sum;
190  int n = indx.size();
191 
192  for(i = 0; i < n; ++i) {
193  ip = indx[i];
194  sum = b[ip];
195  b[ip] = b[i];
196  if(ii != 0)
197  for(j = ii - 1; j < i; ++j)
198  sum -= a[i * n + j] * b[j];
199  else if(sum != 0.0)
200  ii = i + 1;
201  b[i] = sum;
202  }
203  for(i = n - 1; i >= 0; --i) {
204  sum = b[i];
205  for(j = i + 1; j < n; ++j)
206  sum -= a[i * n + j] * b[j];
207  b[i] = sum / a[i * n + i];
208  }
209 
210 }
void lubksb(vector< double > &a, vector< int > &indx, vector< double > &b)
void apply(std::vector< double > &histogram)
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
const int nr
Definition: ClassicRandom.h:24
void ludcmp(vector< double > &a, vector< int > &indx, double &d)
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1213
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
void savgol(double c[], int np, int nl, int nr, int ld, int m)
Definition: savgol.cpp:206
void convlv(double data[], int n, double respns[], int m, int isign, double ans[])
Definition: savgol.cpp:406
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
std::vector< double > CoefsDeriv_m
Definition: SavitzkyGolay.h:21
#define TINY
Definition: rk.cpp:296
std::vector< double > Coefs_m
Definition: SavitzkyGolay.h:20
void calc_derivative(std::vector< double > &histogram, const double &h)
SavitzkyGolayFilter(int np, int nl, int nr, int m)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42