File: digitalFilterIntegral.h

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (104 lines) | stat: -rw-r--r-- 3,043 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/***********************************************/
/**
* @file digitalFilterIntegral.h
*
* @brief Numerical integration using polynomial approximation.
*
* @author Andreas Kvas
* @date 2016-06-21
*
*/
/***********************************************/

#ifndef __GROOPS_DIGITALFILTERINTEGRAL__
#define __GROOPS_DIGITALFILTERINTEGRAL__

// Latex documentation
#ifdef DOCSTRING_DigitalFilter
static const char *docstringDigitalFilterIntegral = R"(
\subsection{Integral}
Numerical integration using polynomial approximation.
The input time series is approximated by a moving polynomial of degree \config{polynomialDegree}
by solving
\begin{equation}
  \begin{bmatrix} x(t_k+\tau_0) \\ \vdots \\ x(t_k+\tau_M) \end{bmatrix}
  =
  \begin{bmatrix}
  1      & \tau_0 & \tau_0^2 & \cdots & \tau_0^M \\
  \vdots & \vdots & \vdots   &        & \vdots   \\
  1      & \tau_M & \tau_M^2 & \cdots & \tau_M^M \\
  \end{bmatrix}%^{-1}
  \begin{bmatrix}
  a_0 \\ \vdots \\ a_M
  \end{bmatrix}
  \qquad\text{with}\quad
  \tau_j =  (j-M/2)\cdot \Delta t,
\end{equation}
for each time step $t_k$ ($\Delta t$ is the \config{sampling} of the time series).
The numerical integral for each time step $t_k$ is approximated by the center interval of the estimated polynomial.

\fig{!hb}{0.7}{DigitalFilter_integral}{fig:DigitalFilterIntegral}{Numerical integration by polynomial approximation.}

\config{polynomialDegree} should be even to avoid a phase shift.
)";
#endif

/***********************************************/

#include "classes/digitalFilter/digitalFilter.h"

/***** CLASS ***********************************/

/** @brief Numerical integration using polynomial approximation.
* @ingroup digitalFilterGroup
* @see DigitalFilter */
class DigitalFilterIntegral : public DigitalFilterARMA
{
public:
  DigitalFilterIntegral(Config &config);
};

/***********************************************/
/***** Inlines *********************************/
/***********************************************/

inline DigitalFilterIntegral::DigitalFilterIntegral(Config &config)
{
  try
  {
    UInt   degree;
    Double dt;

    readConfig(config, "polynomialDegree", degree,  Config::MUSTSET,  "7",   "degree of approximation polynomial");
    readConfig(config, "sampling",         dt,      Config::DEFAULT,  "1.0", "assumed time step between points");
    readConfig(config, "padType",          padType, Config::MUSTSET,  "",    "");
    if(isCreateSchema(config)) return;

    Matrix F(degree+1, degree+1);
    Matrix D(degree+1, degree+1);
    Vector v(degree+1);
    for(UInt j=0; j<F.rows(); j++)
    {
      D(j, j) = 1.0/std::pow(dt, j);
      v(j) = dt/(j+1.);
      F(j,0) = 1.;
      for(UInt n=1; n<F.columns(); n++)
        F(j,n) = std::pow(0.5*degree-j, n);
    }
    inverse(F);

    bnStartIndex = bn.rows()/2;
    bn = Vector(degree+1);
    matMult(1.0, v.trans(), D*F, bn.trans());
    an = Vector(2);
    an(0) = 1.0; an(1) = -1.0;
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/

#endif