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