NiHu  2.0
nd_cheb.hpp
Go to the documentation of this file.
1 
6 #ifndef NIHU_ND_CHEB_HPP_INCLUDED
7 #define NIHU_ND_CHEB_HPP_INCLUDED
8 
9 #include "bounding_box.hpp"
10 
11 #include "util/math_functions.hpp"
12 #include "util/misc.hpp"
13 
14 #include <boost/math/special_functions/chebyshev.hpp>
15 #include <Eigen/Dense>
16 
17 #include <cstddef>
18 
19 namespace NiHu
20 {
21 namespace fmm
22 {
23 
31 template <size_t Dim, class T = double>
32 Eigen::Matrix<T, Dim, Eigen::Dynamic> lintrans(
33  Eigen::Matrix<T, Dim, Eigen::Dynamic> const &x,
34  bounding_box<Dim> const &bbTo,
35  bounding_box<Dim> const &bbFrom)
36 {
37  Eigen::Matrix<T, Dim, Eigen::Dynamic> y = x;
38  for (size_t d = 0; d < Dim; ++d)
39  {
40  y.row(d).array() -= bbFrom.get_center()(d);
41  y.row(d).array() *= bbTo.get_diameter() / bbFrom.get_diameter();
42  y.row(d).array() += bbTo.get_center()(d);
43  }
44  return y;
45 }
46 
54 template <size_t Dim, class T = double>
55 Eigen::Matrix<T, Dim, Eigen::Dynamic> chebnodes(size_t n,
57 {
58  // get Chebyshev roots in [-1 +1]
59  Eigen::Matrix<T, 1, Eigen::Dynamic> x0(1, n);
60  for (size_t i = 0; i < n; ++i)
61  x0(i) = chebroot(n, i);
62 
63  // nd Chebyshev nodes in [-1 +1]^D
64  Eigen::Matrix<T, Dim, Eigen::Dynamic> x(Dim, Ipow(n, Dim));
65  for (size_t i = 0; i < Ipow(n, Dim); ++i)
66  {
67  size_t j = i;
68  for (size_t d = 0; d < Dim; ++d)
69  {
70  x(d, i) = x0(j % n);
71  j /= n;
72  }
73  }
74 
75  // transform to bb
76  x = lintrans<Dim, T>(x, bb, bounding_box<Dim>());
77  return x;
78 }
79 
87 template <class T>
88 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
89 chebanterp0(size_t N, Eigen::Matrix<T, Eigen::Dynamic, 1> const &x,
90  Eigen::Matrix<T, Eigen::Dynamic, 1> const &y)
91 {
92  using boost::math::chebyshev_t;
93  size_t n = x.rows(), m = y.rows();
94  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> S(n, m);
95  Eigen::Matrix<T, Eigen::Dynamic, 1> Sx(n, 1), Sy(m, 1);
96  S.setConstant(1.);
97  for (unsigned l = 1; l < N; ++l)
98  {
99  for (size_t i = 0; i < n; ++i)
100  Sx(i) = chebyshev_t(l, x(i));
101  for (size_t j = 0; j < m; ++j)
102  Sy(j) = chebyshev_t(l, y(j));
103  S += 2. * (Sx * Sy.transpose());
104  }
105  return S / N;
106 }
107 
115 template <class T>
116 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
117 chebanterp0_dy(size_t N, Eigen::Matrix<T, Eigen::Dynamic, 1> const &x,
118  Eigen::Matrix<T, Eigen::Dynamic, 1> const &y)
119 {
120  using boost::math::chebyshev_t;
121  using boost::math::chebyshev_t_prime;
122  size_t n = x.rows(), m = y.rows();
123  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> S(n, m);
124  Eigen::Matrix<T, Eigen::Dynamic, 1> Sx(n, 1), Sy(m, 1);
125  S.setZero();
126  for (unsigned l = 1; l < N; ++l)
127  {
128  for (size_t i = 0; i < n; ++i)
129  Sx(i) = chebyshev_t(l, x(i));
130  for (size_t j = 0; j < m; ++j)
131  Sy(j) = chebyshev_t_prime(l, y(j));
132  S += 2. * (Sx * Sy.transpose());
133  }
134  return S / N;
135 }
136 
137 
146 template <class T, size_t Dim>
147 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
148 chebanterp(size_t N, bounding_box<Dim> const &bb,
149  Eigen::Matrix<T, Dim, Eigen::Dynamic> const &y0)
150 {
151  auto x = chebnodes<Dim, T >(N);
152  auto y = lintrans<Dim, T>(y0, bounding_box<Dim>(), bb);
153  size_t n = x.cols(), m = y.cols();
154  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> S(n, m);
155  S.setConstant(1.);
156  for (size_t d = 0; d < Dim; ++d)
157  S.array() *= chebanterp0<T>(N, x.row(d).transpose(), y.row(d).transpose()).array();
158  return S;
159 }
160 
170 template <class T, size_t Dim>
171 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
172 chebanterp_dny(size_t N,
173  bounding_box<Dim> const &bb,
174  Eigen::Matrix<T, Dim, Eigen::Dynamic> const &y0,
175  Eigen::Matrix<T, Dim, Eigen::Dynamic> const &ny0
176 )
177 {
178  auto x = chebnodes<Dim, T >(N);
179  auto y = lintrans<Dim, T>(y0, bounding_box<Dim>(), bb);
180  size_t n = x.cols(), m = y.cols();
181  double scale = bb.get_diameter() / bounding_box<Dim>().get_diameter();
182 
183  Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic> dS(n, m);
184  dS.setZero();
185 
186  for (size_t q = 0; q < Dim; ++q)
187  {
188  Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic> S(n, m);
189  S.setConstant(1.);
190  for (size_t d = 0; d < Dim; ++d)
191  {
192  if (d == q)
193  S *= chebanterp0_dy<T>(N, x.row(d).transpose(), y.row(d).transpose()).array();
194  else
195  S *= chebanterp0<T>(N, x.row(d).transpose(), y.row(d).transpose()).array();
196  }
197  dS += S.rowwise() * ny0.row(q).array();
198  }
199  return dS / scale;
200 }
201 
202 } // end of namespace fmm
203 } // namespace NiHu
204 
205 #endif /* NIHU_ND_CHEB_HPP_INCLUDED */
NiHu::fmm::chebanterp
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > chebanterp(size_t N, bounding_box< Dim > const &bb, Eigen::Matrix< T, Dim, Eigen::Dynamic > const &y0)
ND Chebyshev anterpolation matrix from points to Chebyshev nodes.
Definition: nd_cheb.hpp:148
NiHu::fmm::chebanterp0_dy
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > chebanterp0_dy(size_t N, Eigen::Matrix< T, Eigen::Dynamic, 1 > const &x, Eigen::Matrix< T, Eigen::Dynamic, 1 > const &y)
y-derivative 1D Chebyshev anterpolation matrix
Definition: nd_cheb.hpp:117
bounding_box.hpp
Implementation of class NiHu::fmm::bounding_box.
NiHu::Ipow
I Ipow(I base, I exp)
compute integer power
Definition: math_functions.hpp:409
NiHu::fmm::lintrans
Eigen::Matrix< T, Dim, Eigen::Dynamic > lintrans(Eigen::Matrix< T, Dim, Eigen::Dynamic > const &x, bounding_box< Dim > const &bbTo, bounding_box< Dim > const &bbFrom)
linear transform of points from a bounding box to an other
Definition: nd_cheb.hpp:32
math_functions.hpp
general mathematical functions
NiHu::fmm::bounding_box::get_center
const location_t & get_center(void) const
return center
Definition: bounding_box.hpp:75
NiHu::fmm::bounding_box
multidimensional square bounding box
Definition: bounding_box.hpp:30
NiHu::fmm::chebanterp0
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > chebanterp0(size_t N, Eigen::Matrix< T, Eigen::Dynamic, 1 > const &x, Eigen::Matrix< T, Eigen::Dynamic, 1 > const &y)
1D Chebyshev anterpolation matrix
Definition: nd_cheb.hpp:89
NiHu::fmm::chebnodes
Eigen::Matrix< T, Dim, Eigen::Dynamic > chebnodes(size_t n, bounding_box< Dim > const &bb=bounding_box< Dim >())
return Chebyshev nodes in a multidimensional bounding box
Definition: nd_cheb.hpp:55
NiHu::fmm::bounding_box::get_diameter
scalar_t get_diameter(void) const
return diameter
Definition: bounding_box.hpp:91
NiHu::chebroot
T chebroot(size_t n, size_t i)
roots of Chebyshev polynomials
Definition: math_functions.hpp:395
NiHu::fmm::chebanterp_dny
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > chebanterp_dny(size_t N, bounding_box< Dim > const &bb, Eigen::Matrix< T, Dim, Eigen::Dynamic > const &y0, Eigen::Matrix< T, Dim, Eigen::Dynamic > const &ny0)
normal derivative of Chebyshev anterpolation matrix
Definition: nd_cheb.hpp:172
misc.hpp
miscellaneous functions and metafunctions