TS++ library: time series library
filter.cc
Go to the documentation of this file.
1 
61 #define TF_FILTER_CC_VERSION \
62  "TF_FILTER_CC V1.12"
63 
64 #include <cmath>
65 #include <sstream>
66 #include <algorithm>
67 #include <tsxx/random.h>
68 #include <tsxx/filter.h>
69 #include <tsxx/filter_usage_text.h>
70 #include <aff/functions/avg.h>
71 #include <aff/functions/absmax.h>
72 #include <aff/seriesoperators.h>
73 #include <aff/subarray.h>
74 #include <tsxx/error.h>
75 #include <tsxx/debug.h>
76 
77 namespace ts {
78 
79  namespace filter {
80 
81  typedef aff::Tsubscript Tindex;
82  typedef aff::Tsize Tsize;
85 
88  const bool& debug) const
89  {
90  /*
91  * The trend function (index l) is
92  *
93  * f(l)= a + b * l
94  *
95  * We minimize
96  *
97  * \sum_l ( x(l) - a - b * l )**2
98  *
99  * where x(l) is the time series.
100  *
101  * The least squares condition is satisfied for a and b that satisfy
102  *
103  * a * N + b * sum_l l = sum_l x(l)
104  * a * sum_l l + b * sum_l l**2 = sum_l l * x(l)
105  *
106  * N = number of samples
107  *
108  * in case the summation starts at index 1:
109  *
110  * sum_l l = 0.5 * N * ( N + 1 )
111  * sum_l l**2 = N * ( N + 1 ) * ( 2 * N + 1 ) / 6
112  */
113  // shift first index to 1 (to make values given above applicable)
114  Tseries x=s;
115  x.shift(1-x.f());
116  Tsize n= (Mn<1) ? x.size() : Mn;
117  n= (n < x.size()) ? n : x.size();
118  /*
119  double m11=n;
120  double m12=0.5*n*(n+1);
121  double m21=m12;
122  double m22=n*(n+1)*(2*n+1)/6.;
123  double det=m11*m22-m12*m21;
124  */
125  // calculate inverse
126  double dn=n;
127  double w11=2.*(2.*dn+1.)/(dn*(dn-1));
128  double w12=-6./(dn*(dn-1.));
129  double w21=w12;
130  double w22=12./(dn*(dn+1.)*(dn-1.));
131 
132  double L1=0, L2=0;
133  for (Tindex l=x.f(); l<=Tindex(n); ++l)
134  {
135  L1 += x(l);
136  L2 += double(l)*x(l);
137  }
138  /*
139  double a=(L1*m22-L2*m12)/det;
140  double b=(-L1*m21+L2*m11)/det;
141  */
142  // apply inverse
143  double a = L1 * w11 + L2 * w12;
144  double b = L1 * w21 + L2 * w22;
145  for (Tindex l=x.f(); l<=x.l(); ++l)
146  { x(l) -= (a+double(l)*b); }
147  return s;
148  }
149 
150  /*----------------------------------------------------------------------*/
151 
154  const bool& debug) const
155  {
156  Tseries x=s;
157  int ifirst=x.f() > Mn1? x.f() : Mn1;
158  int ilast=x.l() < Mn2? x.l() : Mn2;
159  TSXX_assert(ifirst <= ilast,
160  "ERROR (SetByIndex): illegal sample index range");
161  for (Tindex l=ifirst; l<=ilast; ++l)
162  { x(l) = Mv; }
163  return s;
164  }
165 
166  /*----------------------------------------------------------------------*/
167 
170  const bool& debug) const
171  {
172  Tseries x=s;
173  for (Tindex l=x.f(); l<=x.l(); ++l)
174  { x(l) = std::sqrt(x(l)); }
175  return s;
176  }
177 
178  /*----------------------------------------------------------------------*/
179 
182  const bool& debug) const
183  {
184  Tseries x=s;
185  for (Tindex l=x.f(); l<=x.l(); ++l)
186  { x(l) = x(l)*x(l); }
187  return s;
188  }
189 
190  /*----------------------------------------------------------------------*/
191 
194  const bool& debug) const
195  {
196  Tseries x=s;
197  for (Tindex l=x.f(); l<=x.l(); ++l)
198  { x(l) = std::pow(x(l),Mv); }
199  return s;
200  }
201 
202  /*----------------------------------------------------------------------*/
203 
206  const bool& debug) const
207  {
208  Tseries x=s;
209  Tseries n=ts::rnd::dugauss(x.size())*Ma;
210  x += n;
211  return s;
212  }
213 
214  /*----------------------------------------------------------------------*/
215 
218  const bool& debug) const
219  {
220  Tseries x=s;
221  for (Tindex l=x.f(); l<=x.l(); ++l)
222  { x(l) = x(l)<0 ? -x(l) : x(l); }
223  return s;
224  }
225 
226  /*----------------------------------------------------------------------*/
227 
230  const bool& debug) const
231  {
232  Tseries x=s;
233  if (x.size()>1)
234  {
235  for (Tindex l=x.f()+1; l<=x.l(); ++l)
236  { x(l) += x(l-1); }
237  }
238  return s;
239  }
240 
241  /*----------------------------------------------------------------------*/
242 
245  const bool& debug) const
246  {
247  Tsize n= (Mn<1) ? s.size() : Mn;
248  n= (n < s.size()) ? n : s.size();
249  Tindex f=s.f();
250  Tindex l=s.f()+n-1;
251  s -= aff::func::avg<Tseries>(aff::subarray<Tseries>(s)(f,l));
252  return s;
253  }
254 
255  /*----------------------------------------------------------------------*/
256 
266  const bool& debug) const
267  {
268  double p=double(2.*M_PI/s.size());
269  for (Tindex i=s.f(); i<=s.l(); ++i)
270  { s(i) *= M_SQRT1_2*(1.-cos(p*(i-s.f()))); }
271  return s;
272  }
273 
274  /*----------------------------------------------------------------------*/
275 
278  const bool& debug) const
279  { s *= Mv; return s; }
280 
281  /*----------------------------------------------------------------------*/
282 
285  const bool& debug) const
286  { s += Mv; return s; }
287 
288  /*----------------------------------------------------------------------*/
289 
292  const bool& debug) const
293  {
294  Tindex s1=s.f();
295  int n1= (Mn1 < 1) ? 1 : Mn1;
296  Tindex e1=s1+n1-1;
297  Tindex m1=(s1+e1)/2;
298  int n2= (Mn2 < 1) ? n1 : Mn2;
299  Tindex e2= (Mne < 1) ? s.l() : Mne;
300  Tindex s2= e2-n2+1;
301  Tindex m2=(s2+e2)/2;
302  /* DEBUG
303  std::cerr << "fbl: " << " n1 " << n1 << " n2 " << n2
304  << " s1 " << s1 << " e1 " << e1 << " m1 " << m1
305  << " s2 " << s2 << " e2 " << e2 << " m2 " << m2 << std::endl;
306  */
307  Tvalue avg1=aff::func::avg<Tseries>(aff::subarray<Tseries>(s)(s1,e1));
308  Tvalue avg2=aff::func::avg<Tseries>(aff::subarray<Tseries>(s)(s2,e2));
309  double a=(avg2-avg1)/double(m2-m1);
310  for (Tindex i=s.f(); i<=s.l(); ++i)
311  { s(i) -= (a*double(i-m1)+avg1); }
312  return s;
313  }
314 
315  /*----------------------------------------------------------------------*/
316 
319  const bool& debug) const
320  {
321  // std::cerr << "entering reverse" << std::endl;
322  Tindex k=s.f();
323  Tindex l=s.l();
324  Tindex ek=(k+l)/2+1;
325  Tindex el=(k+l)/2-1;
326  while ((k<ek) && (l>el))
327  {
328  Tvalue vk=s(k);
329  Tvalue vl=s(l);
330  // std::cerr << " # k" << k << " l" << l;
331  // std::cerr << " vk" << vk << " vl" << vl;
332  s(k)=vl;
333  s(l)=vk;
334  ++k;
335  --l;
336  }
337  return s;
338  }
339 
340  /*----------------------------------------------------------------------*/
341 
345  const bool& debug) const
346  {
347  Ttimeseries::Tseries series=s;
348  double a=aff::func::absmax(s);
349  double fac=Mv/a;
350  if (a > 1.e-20)
351  {
352  series *= fac;
353  }
354  else
355  {
356  series=0;
357  }
358  return s;
359  }
360 
361  /*----------------------------------------------------------------------*/
362 
366  const bool& debug) const
367  {
368  Ttimeseries::Theader header=s.header;
369  Ttimeseries::Tseries series=s;
370  Ttimeseries src(series.copyout(), header);
371  double dishift=-(this->Mv)/header.dt;
372  int iashift=int(dishift);
373  int ibshift=iashift;
374  if (dishift < 0) { --iashift; } else { ++ibshift; }
375  double ibfac=dishift-double(iashift);
376  double iafac=double(ibshift)-dishift;
377  /*
378  std::cout << "Mv " << Mv << std::endl;
379  std::cout << "dt " << header.dt << std::endl;
380  std::cout << "dishift " << dishift << std::endl;
381  std::cout << "iashift " << iashift << std::endl;
382  std::cout << "ibshift " << ibshift << std::endl;
383  std::cout << "iafac " << iafac << std::endl;
384  std::cout << "ibfac " << ibfac << std::endl;
385  std::cout << "fac " << ibfac+iafac << std::endl;
386  std::cout.flush();
387  */
388  Ttimeseries::Tvalue s1,s2;
389  s1=src(src.f());
390  s2=s1;
391  for (int i=s.f(); i<=s.l(); ++i)
392  {
393  if (((i+iashift) >= s.f()) && (i+iashift) <= s.l())
394  { s1=src(i+iashift); }
395  if (((i+ibshift) >= s.f()) && (i+ibshift) <= s.l())
396  { s2=src(i+ibshift); }
397  s(i)=s1*iafac+s2*ibfac;
398  }
399  return s;
400  }
401 
402  /*----------------------------------------------------------------------*/
403 
407  const bool& debug) const
408  {
409  Tindex f=s.f();
410  RemoveFirst::Mf=s(f);
411  s -= RemoveFirst::Mf;
412  return s;
413  }
414 
416  double RemoveFirst::Mf=0;
417 
418  /*----------------------------------------------------------------------*/
419 
423  const bool& debug) const
424  {
425  s += RemoveFirst::Mf;
426  RemoveFirst::Mf=0.;
427  return s;
428  }
429 
430  /*----------------------------------------------------------------------*/
431 
434  const bool& debug) const
435  {
436  Ttimeseries::Tseries padded(s.f(),s.l()+this->Mn);
437  padded=0.;
438  Ttimeseries::Tseries subseries=aff::subarray(padded)(s.f(), s.l());
439  subseries.copyin(s);
440  Ttimeseries retval(padded, s.header);
441  return retval; }
442 
443  /*----------------------------------------------------------------------*/
444 
446  Tfilterhandle make_filter(std::string s,
447  const bool& debug)
448  {
449  std::replace(s.begin(),s.end(),',',' ');
450  TSXX_debug(debug, "make_filter", "process " + s );
451  typedef Tfilterhandle Tfh;
452  Tfh fh(new Noop());
453  std::string ID;
454  std::istringstream is(s);
455  is >> ID;
456  TSXX_debug(debug, "make_filter", " filter ID is " + ID );
457  Tvalue v;
458  int n, n2, n3;
459  if (ID=="tre") {
460  is >> n;
461  fh=Tfh(new RemoveTrend(n));
462  } else if (ID=="iset") {
463  is >> n >> n2 >> v;
464  fh=Tfh(new SetByIndex(n,n2,v));
465  } else if (ID=="avg") {
466  is >> n;
467  fh=Tfh(new RemoveAverage(n));
468  } else if (ID=="han") {
469  fh=Tfh(new HanningTaper());
470  } else if (ID=="fac") {
471  is >> v;
472  fh=Tfh(new Scale(v));
473  } else if (ID=="add") {
474  is >> v;
475  TSXX_debug(debug, "make_filter", " filter is: Add(" << v << ")" );
476  fh=Tfh(new Add(v));
477  } else if (ID=="fbl") {
478  is >> n >> n2 >> n3;
479  fh=Tfh(new ForceToBase(n, n2, n3));
480  } else if (ID=="pow") {
481  is >> v;
482  fh=Tfh(new Powerof(v));
483  } else if (ID=="rev") {
484  fh=Tfh(new Reverse());
485  } else if (ID=="sqr") {
486  fh=Tfh(new Square());
487  } else if (ID=="sqt") {
488  fh=Tfh(new SquareRoot());
489  } else if (ID=="rec") {
490  fh=Tfh(new Rectifier());
491  } else if (ID=="cus") {
492  fh=Tfh(new CumSum());
493  } else if (ID=="del") {
494  is >> v;
495  fh=Tfh(new Delay(v));
496  } else if (ID=="noi") {
497  is >> v;
498  fh=Tfh(new GaussianNoise(v));
499  } else if (ID=="nrm") {
500  is >> v;
501  fh=Tfh(new Normalize(v));
502  } else if (ID=="lof") {
503  fh=Tfh(new RemoveFirst());
504  } else if (ID=="rsf") {
505  fh=Tfh(new RestoreFirst());
506  } else if (ID=="pad") {
507  is >> n;
508  fh=Tfh(new Pad(n));
509  } else {
510  TSXX_debug(debug, "make_filter", " filter ID " + ID + " is unknown" );
511  TSXX_UnknownFilterAbort("ts::filter::make_filter", ID.c_str());
512  }
513  return(fh);
514  }
515 
517  void print_help(std::ostream& os)
518  {
519  os << TF_FILTER_CC_VERSION << std::endl;
520  os << filter_usage_text;
521  }
522 
523  } // namespace filter
524 
525 } // namespace ts
526 
527 /* ----- END OF filter.cc ----- */
Tdseries dugauss(const int &n)
return gaussian uniform noise (standard dev=1, zero mean)
Definition: random.cc:72
hanning taper.
Definition: filter.h:150
tfxx::Handle< BasicFilter > Tfilterhandle
handle to pass filters
Definition: filterbase.h:93
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
take each sample to the power of a given exponent
Definition: filter.cc:193
remove average
Definition: filter.h:131
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
Definition: filter.cc:406
char filter_usage_text[]
debug macro (prototypes)
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
square signal
Definition: filter.cc:181
some time series filter classes (prototypes)
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
set values selected by index
Definition: filter.cc:153
remove value of first sample from series
Definition: filter.h:338
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
square root of signal
Definition: filter.cc:169
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
add offset to sample values
Definition: filter.cc:284
force signal to a baseline.The filter removes a linear trend from the time series. After this operation the average in the index ranges [i1,i2] and [i3,i4] will vanish. The index range limits are
Definition: filter.h:205
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
Definition: filter.cc:422
aff::Tsubscript Tindex
Definition: filter.cc:81
Ttimeseries::Tvalue Tvalue
we always work in double precision
Definition: filter.cc:83
error handling for libtsxx (prototypes)
#define TSXX_debug(C, N, M)
produce debug output
Definition: debug.h:51
Ttimeseries::Tseries Tseries
Definition: filterbase.h:77
Add random Gaussian noise.
Definition: filter.h:319
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
remove average
Definition: filter.cc:244
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
Definition: filter.cc:344
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
add Gaussian noise
Definition: filter.cc:205
Tfilterhandle make_filter(std::string s, const bool &debug)
function to generate filter class
Definition: filter.cc:446
Structure to hold the data samples of a series together with header information to form a time series...
Definition: tsxx.h:83
double Mv
Definition: filter.h:181
remove trend
Definition: filter.h:110
static double Mf
definition of static member data is required
Definition: filter.h:345
All stuff in this library will be placed within namespace ts.
Definition: anyfilter.cc:43
Ttimeseries::Tseries Tseries
Definition: filter.cc:84
Theader header
data header fields
Definition: tsxx.h:134
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
hanning taper
Definition: filter.cc:265
#define TSXX_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:127
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
remove trend
Definition: filter.cc:87
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
scale sample values
Definition: filter.cc:277
aff::Tsize Tsize
Definition: filter.cc:82
#define TSXX_UnknownFilterAbort(M, F)
Definition: filterbase.h:153
set sample values selected by index
Definition: filter.h:86
unsigned int Mn
Definition: filter.h:384
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
Definition: filter.cc:365
restore value of first sample to series
Definition: filter.h:358
Tseries::Tvalue Tvalue
Definition: tsxx.h:95
no-operation filter
Definition: filterbase.h:115
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
rectification
Definition: filter.cc:217
create a random series (prototypes)
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
force signal to baseline
Definition: filter.cc:291
double Tvalue
type of sample values
Definition: filterbase.h:74
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
append additional samples
Definition: filter.cc:433
void print_help(std::ostream &os)
print usage information
Definition: filter.cc:517
#define TF_FILTER_CC_VERSION
Definition: filter.cc:61
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
cumulative sum
Definition: filter.cc:229
Ttimeseries operator()(const Ttimeseries &s, const bool &debug=false) const
reverse time series
Definition: filter.cc:318