Belle II Software development
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
18namespace 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 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 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::MatrixXd getCoefs(int Size, bool isInverse=false)
Transformation matrix between Cheb nodes and coefficients of the Cheb polynomials Notice,...
Definition: nodes.cc:127
double evalPol(const Eigen::VectorXd &polCoef, double x)
Evaluate Cheb.
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::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
Abstract base class for different kinds of events.