OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
lomb.cpp
Go to the documentation of this file.
1/*****************************************************************************/
2/* */
3/* Class for Lomb Periodograms & Co. */
4/* ================================= */
5/* */
6/* (update: ASM, September 2001) */
7/*****************************************************************************/
8#include "lomb.h"
9
10#include "Physics/Physics.h"
11
12#include <iostream>
13
15/*---------------------------------------------------------------------------*
16 * constructor
17 * ===========
18 *
19 *---------------------------------------------------------------------------*/
20{}
21
22
24/*---------------------------------------------------------------------------*
25 * destructor
26 * ==========
27 *
28 *---------------------------------------------------------------------------*/
29{
30 // Do nothing......
31}
32
33
34int LOMB_class::period(std::vector<LOMB_TYPE> *indata, std::vector<LOMB_TYPE> *outdata,
35 double ofac, double hifac, int *nout, int *jmax, double *prob,
36 int amp)
37/*---------------------------------------------------------------------------*
38 * NR routine
39 * ==========
40 *
41 *---------------------------------------------------------------------------*/
42{
43 int i, j, ntmp;
44 int n = 0;
45 double ave, c, cc, cwtau, effm, expy, pnow, pymax, s, ss, sumc, sumcy, sums, sumsh, sumsy;
46 double swtau, var, wtau, xave, xdiff, xmax, xmin, yy;
47 //double arg,wtemp,*wi,*wpi,*wpr,*wr;
48 double arg, wtemp;
49
50 std::vector<double> wi, wpi, wpr, wr;
51
52 LOMB_TYPE pt;
53
54 CI_lt p, q;
55 /*---------------------------------------------------------------------------*/
56
57 wi.erase(wi.begin(), wi.end());
58 wpi.erase(wpi.begin(), wpi.end());
59 wpr.erase(wpr.begin(), wpr.end());
60 wr.erase(wr.begin(), wr.end());
61
62 p = indata->begin();
63 q = indata->end();
64
65 n = q - p;
66
67 ntmp = (int)(0.5 * ofac * hifac * n);
68
69 *nout = ntmp;
70
71
72 if(avevar(indata, &ave, &var) != 0) {
73 std::cerr << "LOMB: Average failed!\n";
74 return(-1);
75 }
76
77 p = indata->begin();
78 xmax = xmin = (*p).x;
79
80 for(p = indata->begin(); p != indata->end(); p++) {
81 if((*p).x > xmax) xmax = (*p).x;
82 if((*p).x < xmin) xmin = (*p).x;
83 }
84
85 xdiff = xmax - xmin;
86 xave = 0.5 * (xmax + xmin);
87 pymax = 0.0;
88 pnow = 1. / (xdiff * ofac);
89
90 for(p = indata->begin(); p != indata->end(); p++) {
91
92 arg = Physics::two_pi * (((*p).x - xave) * pnow);
93 wpr.push_back((-2. * pow(sin(0.5 * arg) , 2)));
94 wpi.push_back(sin(arg));
95 wr.push_back(cos(arg));
96 wi.push_back(sin(arg));
97
98 }
99
100 // check wr range and data range !!!!
101 if((wr.end() - wr.begin()) != n) {
102 std::cerr << "LOMB: Vector range mismatch!!!\n";
103 return(-1);
104 }
105
106 for(i = 0; i < (*nout); i++) {
107
108 pt.x = pnow;
109 sumsh = 0. ;
110 sumc = 0.;
111
112 for(j = 0; j < n; j++) {
113 c = wr[j];
114 s = wi[j];
115
116 sumsh += s * c;
117 sumc += (c - s) * (c + s);
118 }
119
120 wtau = 0.5 * atan2(2.0 * sumsh, sumc);
121 swtau = sin(wtau);
122 cwtau = cos(wtau);
123 sums = 0.;
124 sumc = 0.;
125 sumsy = 0.;
126 sumcy = 0.;
127
128 for(j = 0, p = indata->begin() ; j < n && p != indata->end() ; j++, p++) {
129
130 s = wi[j];
131 c = wr[j];
132 ss = s * cwtau - c * swtau;
133 cc = c * cwtau + s * swtau;
134 sums += ss * ss;
135 sumc += cc * cc;
136 yy = (*p).y - ave;
137 sumsy += yy * ss;
138 sumcy += yy * cc;
139 wtemp = wr[j];
140 wr[j] = (wr[j] * wpr[j] - wi[j] * wpi[j]) + wr[j];
141 wi[j] = (wi[j] * wpr[j] + wtemp * wpi[j]) + wi[j];
142
143 }
144
145 pt.y = 0.5 * (sumcy * sumcy / sumc + sumsy * sumsy / sums) / var;
146 if(amp) pt.y = sqrt(pow((sumcy / sumc), 2.) + pow((sumsy / sums), 2.));
147
148 if(pt.y >= pymax) {
149 pymax = pt.y;
150 *jmax = i;
151 }
152
153 outdata->push_back(pt);
154
155 pnow += 1. / (ofac * xdiff);
156
157 }
158
159 expy = exp(-pymax);
160 effm = 2. * (*nout) / ofac;
161 *prob = effm * expy;
162
163 if(*prob > 0.01) *prob = 1. - pow((1. - expy), effm);
164
165 wi.erase(wi.begin(), wi.end());
166 wpi.erase(wpi.begin(), wpi.end());
167 wpr.erase(wpr.begin(), wpr.end());
168 wr.erase(wr.begin(), wr.end());
169
170 return(0);
171
172}
173
174
175int LOMB_class::avevar(std::vector<LOMB_TYPE> *data, double *ave, double *var)
176/*---------------------------------------------------------------------------*
177 * NR routine
178 * ==========
179 *
180 *---------------------------------------------------------------------------*/
181{
182 int n;
183 double s, ep;
184
185 CI_lt p, q;
186
187 /*---------------------------------------------------------------------------*/
188
189
190 *ave = 0.;
191 p = data->begin();
192 q = data->end();
193
194 n = q - p;
195
196 if(n < 2) {
197 std::cerr << "Only one datapoint -> no averaging....\n";
198 return(-1);
199 }
200
201 for(p = data->begin(); p != data->end(); p++) *ave += (*p).y;
202
203 *ave = *ave / n;
204 *var = 0.;
205 ep = 0.;
206
207 for(p = data->begin(); p != data->end(); p++) {
208 s = (*p).y - *ave;
209 ep += s;
210 *var += s * s;
211 }
212
213 *var = (*var - ep * ep / n) / (n - 1);
214
215 return(0);
216
217}
218
219
220
221double LOMB_class::signi(double *peak, int *nout, double *ofac)
222/*---------------------------------------------------------------------------*
223 * Calculate the significance of a peak in an Lomb Periodogram
224 * ===========================================================
225 *
226 * Input: double* peak: Peak of periodogram
227 * int* nout: Number of frequencies
228 * double* ofac: Oversampling factor
229 * Output: double Sign: Significance of peak
230 *---------------------------------------------------------------------------*/
231{
232
233 double expy, effm, prob;
234
235 /*---------------------------------------------------------------------------*/
236
237 expy = exp(-1 * (*peak));
238 effm = 2. * (double)(*nout) / (*ofac);
239 prob = effm * expy ;
240 if(prob > 0.01) prob = 1. - pow((1. - expy), effm);
241
242 return(prob);
243
244
245}
246
247
248int LOMB_class::moment(std::vector<LOMB_TYPE> *indata, double *ave, double *adev,
249 double *sdev, double *var, double *skew, double *curt)
250/*---------------------------------------------------------------------------*
251 * Calculate the first moments of a distribution (free after NR)
252 * =============================================================
253 *
254 * Input: vector indata: (periodogram) value vector of type LOMB_TYPE
255 * Output: double* ave : average
256 * double* adev : average deviation
257 * double* sdev : standard deviation
258 * double* var : variance
259 * double* skew : skewness
260 * double* curt : kurtosis
261 *---------------------------------------------------------------------------*/
262{
263
264 int n;
265 double pnr, s, ep;
266
267 CI_lt p, q;
268 /*---------------------------------------------------------------------------*/
269
270 p = indata->begin();
271 q = indata->end();
272
273 n = q - p;
274
275 if(n < 2) {
276 std::cerr << "To few data points for moment analysis!\n";
277 return(-1);
278 }
279
280
281 /*
282 * First pass to get the mean
283 * --------------------------
284 */
285
286 s = 0;
287 double nn = 0;
288 for(p = indata->begin(); p != indata->end(); p++) {
289 s += (*p).y * (*p).x;
290 nn += (*p).y;
291 }
292
293 *ave = s / (double)nn;
294
295 /*
296 * Second pass
297 * ------------
298 */
299
300
301 *adev = 0.;
302 *var = 0.;
303 *skew = 0.;
304 *curt = 0.;
305 ep = 0.;
306
307 for(p = indata->begin(); p != indata->end(); p++) {
308
309 s = ((*p).x - *ave);
310 ep += s * (*p).y;
311 *adev = *adev + (double)std::abs((double)s);
312
313 pnr = s * s;
314 *var += pnr * (*p).y;
315
316 pnr *= s;
317 *skew += pnr * (*p).y;
318
319 pnr *= s;
320 *curt += pnr * (*p).y;
321
322 }
323
324 *adev = *adev / (double)nn;
325
326 *var = (*var - ep * ep / (double)nn) / ((double)(nn - 1));
327
328 *sdev = sqrt(*var);
329
330 if(*var != 0.) {
331 *skew = *skew / ((double)nn * pow(*sdev, 3.));
332 *curt = *curt / ((double)nn * pow(*var, 2.)) - 3.;
333 } else {
334 std::cerr << "No skew or kurtosis when zero variance in moment\n";
335 }
336
337 return(0);
338
339}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
std::vector< LOMB_TYPE >::const_iterator CI_lt
Definition: lomb.h:17
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
arg(a))
constexpr double two_pi
The value of.
Definition: Physics.h:33
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
Definition: lomb.h:13
double x
Definition: lomb.h:14
double y
Definition: lomb.h:14
virtual ~LOMB_class(void)
Definition: lomb.cpp:23
int avevar(std::vector< LOMB_TYPE > *data, double *ave, double *var)
Definition: lomb.cpp:175
LOMB_class(int)
Definition: lomb.cpp:14
double signi(double *peak, int *nout, double *ofac)
Definition: lomb.cpp:221
int moment(std::vector< LOMB_TYPE > *indata, double *ave, double *adev, double *sdev, double *var, double *skew, double *curt)
Definition: lomb.cpp:248
int period(std::vector< LOMB_TYPE > *indata, std::vector< LOMB_TYPE > *outdata, double ofac, double hifac, int *nout, int *jmax, double *prob, int amp)
Definition: lomb.cpp:34