Belle II Software  release-08-01-10
nodes.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 
10 
11 #include <cassert>
12 #include <vector>
13 #include <iostream>
14 #include <cmath>
15 
16 #include <Eigen/Dense>
17 
18 namespace Belle2 {
24  using Eigen::VectorXd;
25  using Eigen::MatrixXd;
26 
27 
28  // to integrate function between 0 and 1 (more in nodes.h)
29  VectorXd getWeights(int Size)
30  {
31  const int N = Size - 1;
32  assert(N % 2 == 0);
33 
34  std::vector<std::vector<double>> coef(Size);
35  for (auto& el : coef) el.resize(Size);
36 
37 
38  for (int k = 0; k <= N / 2; ++k) {
39  coef[2 * k][N] = 1. / N;
40  coef[2 * k][0] = 1. / N ;
41 
42  coef[2 * k][N / 2] = 2. / N * (2 * ((k + 1) % 2) - 1);
43 
44  for (int n = 1; n <= N / 2 - 1; ++n)
45  coef[2 * k][n] = coef[2 * k][N - n] = 2. / N * cos(n * k * M_PI * 2 / N);
46  }
47 
48  VectorXd wgt = VectorXd::Zero(Size);
49 
50 
51  for (int i = 0; i < Size; ++i) {
52  wgt[i] += coef[0][i];
53  wgt[i] += coef[N][i] / (1. - N * N);
54  for (int k = 1; k <= N / 2 - 1; ++k) {
55  double w = 2. / (1 - 4 * k * k);
56  wgt[i] += w * coef[2 * k][i];
57  }
58 
59  wgt[i] *= 0.5; //for interval (0,1)
60  }
61  return wgt;
62  }
63 
64  // vector of nodes to integrate function between 0 and 1 (more in nodes.h)
65  VectorXd getNodes(int Size)
66  {
67  assert((Size - 1) % 2 == 0);
68  VectorXd xi = VectorXd::Zero(Size);
69  for (int i = 0; i < Size; ++i) {
70  double Cos = cos(i / (Size - 1.) * M_PI);
71  xi[i] = (1 - Cos) / 2;
72  }
73  return xi;
74  }
75 
76 // Evaluate Cheb pols up to Size at point x, x is between 0 and 1 (more in nodes.h)
77  VectorXd getPols(int Size, double x)
78  {
79  VectorXd pol(Size);
80  double C = 2 * (2 * x - 1);
81 
82  if (Size >= 1) pol[0] = 1;
83  if (Size >= 2) pol[1] = C / 2;
84 
85  for (int i = 2; i < Size; ++i)
86  pol[i] = C * pol[i - 1] - pol[i - 2];
87  return pol;
88  }
89 
90 
96  VectorXd getPolsSum(int Size, VectorXd x)
97  {
98  assert(Size > 2);
99 
100  VectorXd polSum(Size);
101 
102  VectorXd pol0 = 0 * x.array() + 1;
103  VectorXd pol1 = 2 * x.array() - 1;
104  VectorXd C = 2 * pol1;
105 
106  VectorXd pol2(x.size());
107  for (int i = 2; i < Size; ++i) {
108  polSum(i - 2) = pol0.sum();
109 
110  pol2 = C.array() * pol1.array() - pol0.array();
111 
112  pol0 = pol1;
113  pol1 = pol2;
114  }
115 
116  polSum(Size - 2) = pol0.sum();
117  polSum(Size - 1) = pol1.sum();
118 
119  return polSum;
120  }
121 
122 
123 
124 
125 
126 // Transformation matrix between Cheb nodes and Cheb. Coefficients (more in nodes.h)
127  MatrixXd getCoefs(int Size, bool isInverse = false)
128  {
129  const int N = Size - 1;
130  assert(N % 2 == 0);
131 
132  MatrixXd coef(Size, Size);
133 
134  double mul = 1;
135  double C = 1. / N;
136  if (isInverse == true) {C = 1. / 2; }
137 
138  for (int k = 0; k <= N; ++k) {
139  if (!isInverse) {
140  coef(k, N) = C;
141  coef(k, 0) = C * (k % 2 == 1 ? -1 : 1);
142  } else {
143  mul = k % 2 == 1 ? -1 : 1;
144  coef(N - k, N) = C * mul;
145  coef(N - k, 0) = C ;
146  }
147 
148  for (int n = 1; n <= N - 1; ++n) {
149  double el = cos(n * k * M_PI / N) * 2.*C * mul;
150  if (!isInverse) coef(k, N - n) = el;
151  else coef(N - k, N - n) = el;
152  }
153  }
154 
155  return coef;
156  }
157 
158 
159 
160 
161 // getCoef with better normalization of the borders (more in nodes.h)
162  MatrixXd getCoefsCheb(int oldSize)
163  {
164  auto coef = getCoefs(oldSize);
165 
166  coef.row(0) *= 0.5;
167  coef.row(coef.rows() - 1) *= 0.5;
168 
169  return coef;
170  }
171 
172 
173 
174 
176  double evalPol(const VectorXd& polCoef, double x)
177  {
178  VectorXd pols = getPols(polCoef.size(), x);
179 
180  double s = pols.dot(polCoef);
181 
182  return s;
183  }
184 
185 
189  VectorXd interpol(const VectorXd& xi, double x)
190  {
191  double Norm = (xi[xi.size() - 1] - xi[0]) / 2;
192  VectorXd coefs(xi.size());
193  for (int i = 0; i < xi.size(); ++i) {
194  double num = 1, den = 1;
195  for (int j = 0; j < xi.size(); ++j)
196  if (j != i) {
197  num *= (x - xi(j)) / Norm;
198  den *= (xi(i) - xi(j)) / Norm;
199  }
200  coefs(i) = num / den;
201  }
202  return coefs;
203  }
204 
205 
210  double interpol(VectorXd xi, VectorXd vals, double x)
211  {
212  VectorXd coefs = interpol(xi, x);
213  return coefs.dot(vals);
214  }
215 
217 }
Eigen::VectorXd interpol(const Eigen::VectorXd &xi, double x)
Get Interpolation vector k_i for point x from the function values at points xi (polynomial interpolat...
Eigen::VectorXd getWeights(int Size)
Get the vector of weights to calculate the integral over the Chebyshev nodes The nodes are by definit...
Definition: nodes.cc:29
Eigen::VectorXd getPols(int Size, double x)
Evaluate Chebyshev polynomials up to Size at point x It returns a vector of the P_i(x) for i=0....
Definition: nodes.cc:77
Eigen::MatrixXd getCoefsCheb(int oldSize)
Transformation matrix between Cheb nodes and Cheb coefficients with better normalization of the borde...
Definition: nodes.cc:162
Eigen::VectorXd getPolsSum(int Size, Eigen::VectorXd x)
Calculate the Chebyshev polynomials of order i=0..Size-1 at points given in vector x_j and sum it ove...
Eigen::MatrixXd getCoefs(int Size, bool isInverse=false)
Transformation matrix between Cheb nodes and coefficients of the Cheb polynomials Notice,...
Definition: nodes.cc:127
Eigen::VectorXd getNodes(int Size)
Get the vector of positions of the Chebyshev nodes The nodes are by definition between 0 and 1,...
Definition: nodes.cc:65
double evalPol(const Eigen::VectorXd &polCoef, double x)
Evaluate Cheb.
Abstract base class for different kinds of events.