OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
SavitzkyGolay.cpp
Go to the documentation of this file.
2#include <iostream>
3#include "Utilities/GSLFFT.h"
4
5#include <cmath>
6
8 : NumberPoints_m(np),
9 NumberPointsLeft_m(nl),
10 NumberPointsRight_m(nr),
11 PolynomialOrder_m(m),
12 Coefs_m(np, 0.0),
13 CoefsDeriv_m(np, 0.0) {
17}
18
19void SavitzkyGolayFilter::apply(std::vector<double>& LineDensity) {
20 std::vector<double> temp(LineDensity.size(), 0.0);
21 convlv(LineDensity, Coefs_m, 1, temp);
22 LineDensity.assign(temp.begin(), temp.end());
23}
24
25void SavitzkyGolayFilter::calc_derivative(std::vector<double>& LineDensity, const double& /*h*/) {
26 std::vector<double> temp(LineDensity.size(), 0.0);
27 convlv(LineDensity, CoefsDeriv_m, 1, temp);
28 LineDensity.assign(temp.begin(), temp.end());
29}
30
31void savgol(
32 std::vector<double>& c, const int& np, const int& nl, const int& nr, const int& ld,
33 const int& m) {
34 int j, k, imj, ipj, kk, mm;
35 double d, sum;
36
37 if (np < nl + nr + 1 || nl < 0 || nr < 0 || ld > m || nl + nr < m) {
38 std::cerr << "bad args in savgol" << std::endl;
39 return;
40 }
41 std::vector<int> indx(m + 1, 0);
42 std::vector<double> a((m + 1) * (m + 1), 0.0);
43 std::vector<double> b(m + 1, 0.0);
44
45 for (ipj = 0; ipj <= (m << 1); ++ipj) {
46 sum = (ipj ? 0.0 : 1.0);
47 for (k = 1; k <= nr; ++k)
48 sum += (int)pow((double)k, (double)ipj);
49 for (k = 1; k <= nl; ++k)
50 sum += (int)pow((double)-k, (double)ipj);
51 mm = (ipj < 2 * m - ipj ? ipj : 2 * m - ipj);
52 for (imj = -mm; imj <= mm; imj += 2)
53 a[(ipj + imj) / 2 * (m + 1) + (ipj - imj) / 2] = sum;
54 }
55 ludcmp(a, indx, d);
56
57 for (j = 0; j < m + 1; ++j)
58 b[j] = 0.0;
59 b[ld] = 1.0;
60
61 lubksb(a, indx, b);
62 for (kk = 0; kk < np; ++kk)
63 c[kk] = 0.0;
64 for (k = -nl; k <= nr; ++k) {
65 sum = b[0];
66 double fac = 1.0;
67 for (mm = 1; mm <= m; ++mm)
68 sum += b[mm] * (fac *= k);
69 kk = (np - k) % np;
70 c[kk] = sum;
71 }
72}
73
74void convlv(
75 const std::vector<double>& data, const std::vector<double>& respns, const int& isign,
76 std::vector<double>& ans) {
77 int n = data.size();
78 int m = respns.size();
79
80 double* tempfd1 = new double[n];
81 double* tempfd2 = new double[n];
82
86
87 for (int i = 0; i < n; ++i) {
88 tempfd1[i] = 0.0;
89 tempfd2[i] = data[i];
90 }
91
92 tempfd1[0] = respns[0];
93 for (int i = 1; i < (m + 1) / 2; ++i) {
94 tempfd1[i] = respns[i];
95 tempfd1[n - i] = respns[m - i];
96 }
97
98 gsl_fft_real_transform(tempfd1, 1, n, real, work);
99 gsl_fft_real_transform(tempfd2, 1, n, real, work);
100
103
104 if (isign == 1) {
105 for (int i = 1; i < n - 1; i += 2) {
106 double tmp = tempfd1[i];
107 tempfd1[i] = (tempfd1[i] * tempfd2[i] - tempfd1[i + 1] * tempfd2[i + 1]);
108 tempfd1[i + 1] = (tempfd1[i + 1] * tempfd2[i] + tmp * tempfd2[i + 1]);
109 }
110 tempfd1[0] *= tempfd2[0];
111 tempfd1[n - 1] *= tempfd2[n - 1];
112 }
113
114 gsl_fft_halfcomplex_inverse(tempfd1, 1, n, hc, work);
115
116 for (int i = 0; i < n; ++i) {
117 ans[i] = tempfd1[i];
118 }
119
122
123 delete[] tempfd1;
124 delete[] tempfd2;
125}
126
127void ludcmp(std::vector<double>& a, std::vector<int>& indx, double& d) {
128 const double TINY = 1.0e-20;
129 int i, imax = -1, j, k;
130 double big, dum, sum, temp;
131
132 int n = indx.size();
133 std::vector<double> vv(n, 0.0);
134
135 d = 1.0;
136 for (i = 0; i < n; ++i) {
137 big = 0.0;
138 for (j = 0; j < n; ++j)
139 if ((temp = std::abs(a[i * n + j])) > big) big = temp;
140
141 if (big == 0.0) {
142 std::cerr << "Singular matrix in routine ludcmp" << std::endl;
143 return;
144 }
145 vv[i] = 1. / big;
146 }
147
148 for (j = 0; j < n; ++j) {
149 for (i = 0; i < j; ++i) {
150 sum = a[i * n + j];
151 for (k = 0; k < i; ++k)
152 sum -= a[i * n + k] * a[k * n + j];
153 a[i * n + j] = sum;
154 }
155 big = 0.0;
156 for (i = j; i < n; ++i) {
157 sum = a[i * n + j];
158 for (k = 0; k < j; ++k)
159 sum -= a[i * n + k] * a[k * n + j];
160 a[i * n + j] = sum;
161 if ((dum = vv[i] * std::abs(sum)) >= big) {
162 big = dum;
163 imax = i;
164 }
165 }
166
167 if (j != imax) {
168 for (k = 0; k < n; ++k) {
169 dum = a[imax * n + k];
170 a[imax * n + k] = a[j * n + k];
171 a[j * n + k] = dum;
172 }
173 d = -d;
174 vv[imax] = vv[j];
175 }
176 indx[j] = imax;
177 if (a[j * n + j] == 0.0) a[j * n + j] = TINY;
178 if (j != n - 1) {
179 dum = 1. / a[j * n + j];
180 for (i = j + 1; i < n; ++i)
181 a[i * n + j] *= dum;
182 }
183 }
184}
185
186void lubksb(std::vector<double>& a, std::vector<int>& indx, std::vector<double>& b) {
187 int i, ii = 0, ip, j;
188 double sum;
189 int n = indx.size();
190
191 for (i = 0; i < n; ++i) {
192 ip = indx[i];
193 sum = b[ip];
194 b[ip] = b[i];
195 if (ii != 0)
196 for (j = ii - 1; j < i; ++j)
197 sum -= a[i * n + j] * b[j];
198 else if (sum != 0.0)
199 ii = i + 1;
200 b[i] = sum;
201 }
202 for (i = n - 1; i >= 0; --i) {
203 sum = b[i];
204 for (j = i + 1; j < n; ++j)
205 sum -= a[i * n + j] * b[j];
206 b[i] = sum / a[i * n + i];
207 }
208}
const int nr
gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc(size_t n)
Allocate a halfcomplex FFT wavetable of size .
Definition GSLFFT.h:181
void gsl_fft_real_wavetable_free(gsl_fft_real_wavetable *w)
Free a real FFT wavetable.
Definition GSLFFT.h:159
gsl_fft_real_workspace * gsl_fft_real_workspace_alloc(size_t n)
Allocate a real FFT workspace of size .
Definition GSLFFT.h:138
void gsl_fft_halfcomplex_inverse(double *data, size_t stride, size_t n, gsl_fft_halfcomplex_wavetable *wavetable, gsl_fft_halfcomplex_workspace *workspace)
Alias for halfcomplex inverse transform.
Definition GSLFFT.h:245
void gsl_fft_real_workspace_free(gsl_fft_real_workspace *w)
Free a real FFT workspace.
Definition GSLFFT.h:163
void gsl_fft_real_transform(double *data, size_t stride, size_t n, gsl_fft_real_wavetable *, gsl_fft_real_workspace *)
Forward real FFT with GSL-compatible packed output.
Definition GSLFFT.h:151
gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc(size_t n)
Allocate a real FFT wavetable of size .
Definition GSLFFT.h:129
void gsl_fft_halfcomplex_wavetable_free(gsl_fft_halfcomplex_wavetable *w)
Free a halfcomplex FFT wavetable.
Definition GSLFFT.h:233
Halfcomplex FFT types for inverse transforms.
Definition GSLFFT.h:167
GSL-compatible interface for FFT routines.
Definition GSLFFT.h:115
Workspace for real FFT routines.
Definition GSLFFT.h:121
void convlv(const std::vector< double > &data, const std::vector< double > &respns, const int &isign, std::vector< double > &ans)
void ludcmp(std::vector< double > &a, std::vector< int > &indx, double &d)
void lubksb(std::vector< double > &a, std::vector< int > &indx, std::vector< double > &b)
void savgol(std::vector< double > &c, const int &np, const int &nl, const int &nr, const int &ld, const int &m)
void convlv(const std::vector< double > &data, const std::vector< double > &respns, const int &isign, std::vector< double > &ans)
void savgol(std::vector< double > &c, const int &np, const int &nl, const int &nr, const int &ld, const int &m)
void apply(std::vector< double > &histogram)
std::vector< double > Coefs_m
std::vector< double > CoefsDeriv_m
SavitzkyGolayFilter(int np, int nl, int nr, int m)
void calc_derivative(std::vector< double > &histogram, const double &h)