Tatooine
interpolation.h
Go to the documentation of this file.
1#ifndef TATOOINE_INTERPOLATION_H
2#define TATOOINE_INTERPOLATION_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/tensor.h>
7
8#include <cassert>
9#include <cmath>
10#include <iostream>
11#include <utility>
12//==============================================================================
14//==============================================================================
15template <typename Real>
16struct linear;
17//==============================================================================
18template <floating_point Real>
19struct linear<Real> {
20 //----------------------------------------------------------------------------
21 // traits
22 //----------------------------------------------------------------------------
23 public:
24 static constexpr std::size_t num_derivatives = 0;
25 using real_type = Real;
27 static constexpr std::size_t num_dimensions() { return 1; }
28
29 //----------------------------------------------------------------------------
30 // members
31 //----------------------------------------------------------------------------
32 public:
34
35 //----------------------------------------------------------------------------
36 // ctors
37 //----------------------------------------------------------------------------
38 constexpr linear() = default;
39 constexpr linear(linear const&) = default;
40 constexpr linear(linear&&) = default;
41 constexpr linear& operator=(linear const&) = default;
42 constexpr linear& operator=(linear&&) = default;
43 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
44 constexpr linear(Real const ft0, Real const ft1)
45 : m_interpolant{ft0, ft1 - ft0} {}
46 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47 constexpr linear(Real const t0, Real const t1, Real const ft0, Real const ft1)
48 : m_interpolant{(ft0 * t1 - ft1 * t0) / (t1 - t0),
49 (ft1 - ft0) / (t1 - t0)} {}
50 //----------------------------------------------------------------------------
51 // methods
52 //----------------------------------------------------------------------------
53 constexpr auto evaluate(arithmetic auto const t) const {
54 return m_interpolant(t);
55 }
56 constexpr auto operator()(arithmetic auto const t) const {
57 return evaluate(t);
58 }
59 //----------------------------------------------------------------------------
60 constexpr auto polynomial() const -> auto const& { return m_interpolant; }
61 constexpr auto polynomial() -> auto& { return m_interpolant; }
62};
63//==============================================================================
64template <typename T>
66// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67template <typename Real, std::size_t... Dims>
68struct interpolation_value_type_impl<tensor<Real, Dims...>> {
69 using type = tensor<Real, Dims...>;
70};
71// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
72template <typename Real, std::size_t N>
75};
76// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
77template <typename Real, std::size_t N>
79 : interpolation_value_type_impl<tensor<Real, N>> {};
80// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81template <typename Real, std::size_t M, std::size_t N>
84};
85// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86template <typename Real, std::size_t M, std::size_t N>
88 : interpolation_value_type_impl<tensor<Real, M, N>> {};
89// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
90template <typename T>
93//==============================================================================
94template <typename Real>
96// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97template <typename Real, std::size_t... Dims>
98struct interpolation_tensor_type_impl<tensor<Real, Dims...>> {
99 using type = tensor<Real, Dims...>;
100};
101// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102template <typename Real, std::size_t N>
105};
106// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
107template <typename Real, std::size_t N>
110};
111// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112template <typename Real, std::size_t M, std::size_t N>
115};
116// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117template <typename T>
120//==============================================================================
121template <floating_point Float>
122linear(Float, Float) -> linear<Float>;
123template <floating_point Float>
124linear(Float, Float, Float, Float) -> linear<Float>;
125//==============================================================================
126template <floating_point Real, std::size_t... Dims>
127struct linear<tensor<Real, Dims...>> {
128 //----------------------------------------------------------------------------
129 // traits
130 //----------------------------------------------------------------------------
131 public:
132 static constexpr std::size_t num_derivatives = 0;
133 using real_type = Real;
139 //----------------------------------------------------------------------------
140 // members
141 //----------------------------------------------------------------------------
142 public:
143 polynomial_array_type m_interpolants = {};
144 //----------------------------------------------------------------------------
145 // ctors
146 //----------------------------------------------------------------------------
147 constexpr linear() = default;
148 constexpr linear(linear const&) = default;
149 constexpr linear(linear&&) = default;
150 constexpr linear& operator=(linear const&) = default;
151 constexpr linear& operator=(linear&&) = default;
152 // - - - - - - - - - - - - - - - - - - -j- - - - - - - - - - - - - - - - - - -
153 constexpr linear(Real const t0, Real const t1,
154 tensor_type const& ft0, tensor_type const& ft1) {
155 auto it = [&](auto const... is) {
156 m_interpolants(is...) =
157 interpolant_type{(ft0(is...) * t1 - ft1(is...) * t0) / (t1 - t0),
158 (ft1(is...) - ft0(is...)) / (t1 - t0)};
159 };
160 for_loop(it, Dims...);
161 }
162 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163 constexpr linear(tensor_type const& ft0, tensor_type const& ft1) {
164 auto it = [&](auto const... is) {
165 m_interpolants(is...) =
166 interpolant_type{ft0(is...), ft1(is...) - ft0(is...)};
167 };
168 for_loop(it, Dims...);
169 }
170
171 //----------------------------------------------------------------------------
172 // methods
173 //----------------------------------------------------------------------------
174 constexpr auto evaluate(arithmetic auto const t) const {
175 auto interpolation = value_type{};
176 auto it = [&](auto const... is) {
177 interpolation(is...) = m_interpolants(is...)(t);
178 };
179 for_loop(it, Dims...);
180 return interpolation;
181 }
182 constexpr auto operator()(arithmetic auto const t) const {
183 return evaluate(t);
184 }
185 //----------------------------------------------------------------------------
186 auto polynomial() const -> auto const& { return m_interpolants; }
187 auto polynomial() -> auto& { return m_interpolants; }
188};
189// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
190template <typename Real, std::size_t N>
191struct linear<vec<Real, N>> : linear<tensor<Real, N>> {
192 using linear<tensor<Real, N>>::linear;
193};
194// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
195template <typename Real, std::size_t M, std::size_t N>
196struct linear<mat<Real, M, N>> : linear<tensor<Real, N>> {
197 using linear<tensor<Real, N>>::linear;
198};
199template <floating_point Float, std::size_t... Dims>
201 -> linear<tensor<Float, Dims...>>;
202template <floating_point Float, std::size_t... Dims>
204 -> linear<tensor<Float, Dims...>>;
205template <floating_point Float, std::size_t N>
207template <floating_point Float, std::size_t N>
209template <floating_point Float, std::size_t M, std::size_t N>
212template <floating_point Float, std::size_t M, std::size_t N>
214//==============================================================================
215template <typename Real>
216struct cubic;
217//==============================================================================
218template <floating_point Real>
219struct cubic<Real> : polynomial<Real, 3> {
220 static constexpr std::size_t num_derivatives = 1;
221 using real_type = Real;
223 static constexpr std::size_t num_dimensions() { return 1; }
224
225 //----------------------------------------------------------------------------
226 // ctors
227 //----------------------------------------------------------------------------
228 public:
229 constexpr cubic() = default;
230 constexpr cubic(cubic const&) = default;
231 constexpr cubic(cubic&&) = default;
232 constexpr cubic& operator=(cubic const&) = default;
233 constexpr cubic& operator=(cubic&&) = default;
234 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
235 constexpr cubic(Real const t0, Real const t1, Real const ft0, Real const ft1,
236 Real const dft0_dt, Real const dft1_dt)
237 : parent_type{0, 0, 0, 0} {
238 constexpr Real zero = 0;
239 constexpr Real one = 1;
240 auto const A = mat<Real, 4, 4>{{one, t0, t0 * t0, t0 * t0 * t0},
241 {one, t1, t1 * t1, t1 * t1 * t1},
242 {zero, one, 2 * t0, 3 * t0 * t0},
243 {zero, one, 2 * t1, 3 * t1 * t1}};
244 auto const b = vec<Real, 4>{ft0, ft1, dft0_dt, dft1_dt};
245 this->set_coefficients(solve(A, b)->data());
246 }
247 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
248 constexpr cubic(Real const ft0, Real const ft1, Real const dft0_dt,
249 Real const dft1_dt)
250 : parent_type{ft0, dft0_dt, 3 * ft1 - 3 * ft0 - dft1_dt - 2 * dft0_dt,
251 -2 * ft1 + 2 * ft0 + dft1_dt + dft0_dt} {}
252};
253//------------------------------------------------------------------------------
254template <floating_point Float>
255cubic(Float, Float, Float, Float) -> cubic<Float>;
256//------------------------------------------------------------------------------
257template <floating_point Float>
258cubic(Float, Float, Float, Float, Float, Float) -> cubic<Float>;
259//------------------------------------------------------------------------------
260template <arithmetic Real, std::size_t N>
261struct cubic<tensor<Real, N>> {
262 //----------------------------------------------------------------------------
263 // traits
264 //----------------------------------------------------------------------------
265 public:
266 static constexpr std::size_t num_derivatives = 1;
267 using real_type = Real;
270 using polynomial_array_type = std::array<interpolant_type, N>;
271 static constexpr std::size_t num_dimensions() { return N; }
272 //----------------------------------------------------------------------------
273 // members
274 //----------------------------------------------------------------------------
275 public:
277 //----------------------------------------------------------------------------
278 // ctors
279 //----------------------------------------------------------------------------
280 constexpr cubic() = default;
281 constexpr cubic(cubic const&) = default;
282 constexpr cubic(cubic&&) = default;
283 constexpr cubic& operator=(cubic const&) = default;
284 constexpr cubic& operator=(cubic&&) = default;
285 //-----------------------------------------------------------------------------
286 private:
287 template <std::size_t... Is>
288 constexpr cubic(vec_type const& ft0, vec_type const& ft1,
289 vec_type const& dft0_dt, vec_type const& dft1_dt,
290 std::index_sequence<Is...> /*seq*/)
291 : m_interpolants{interpolant_type{
292 ft0(Is), dft0_dt(Is),
293 3 * ft1(Is) - 3 * ft0(Is) - dft1_dt(Is) - 2 * dft0_dt(Is),
294 -2 * ft1(Is) + 2 * ft0(Is) + dft1_dt(Is) + dft0_dt(Is)}...} {}
295 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
296 public:
297 constexpr cubic(vec_type const& ft0, vec_type const& ft1,
298 vec_type const& dft0_dt, vec_type const& dft1_dt)
299 : cubic{ft0, ft1, dft0_dt, dft1_dt, std::make_index_sequence<N>{}} {}
300 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
301 constexpr cubic(real_type const t0, real_type const t1, vec_type const& ft0,
302 vec_type const& ft1, vec_type const& dft0_dt,
303 vec_type const& dft1_dt) {
305 B.row(0) = ft0;
306 B.row(1) = ft1;
307 B.row(2) = dft0_dt;
308 B.row(3) = dft1_dt;
309 auto const A = Mat4<Real>{{1.0, t0, t0 * t0, t0 * t0 * t0},
310 {1.0, t1, t1 * t1, t1 * t1 * t1},
311 {0.0, 1.0, 2 * t0, 3 * t0 * t0},
312 {0.0, 1.0, 2 * t1, 3 * t1 * t1}};
313 auto const C = *solve(A, B);
314 for (std::size_t i = 0; i < N; ++i) {
315 m_interpolants[i].set_coefficients(C(0, i), C(1, i), C(2, i), C(3, i));
316 }
317 }
318 //----------------------------------------------------------------------------
319 // methods
320 //----------------------------------------------------------------------------
321 template <std::size_t... Is>
322 constexpr auto evaluate(arithmetic auto const t,
323 std::index_sequence<Is...> /*seq*/) const {
324 return vec{m_interpolants[Is](t)...};
325 }
326 constexpr auto evaluate(arithmetic auto const t) const {
327 return evaluate(t, std::make_index_sequence<N>{});
328 }
329 constexpr auto operator()(arithmetic auto const t) const {
330 return evaluate(t, std::make_index_sequence<N>{});
331 }
332 //----------------------------------------------------------------------------
333 auto polynomial() const -> auto const& { return m_interpolants; }
334 auto polynomial() -> auto& { return m_interpolants; }
335};
336//==============================================================================
337template <typename Real, std::size_t N>
338struct cubic<vec<Real, N>> : cubic<tensor<Real, N>> {
339 using cubic<tensor<Real, N>>::cubic;
340};
341template <floating_point Float, std::size_t N>
344//------------------------------------------------------------------------------
345template <floating_point Float, std::size_t N>
348//------------------------------------------------------------------------------
349template <floating_point Float, std::size_t N>
352//------------------------------------------------------------------------------
353template <floating_point Float, std::size_t N>
356//==============================================================================
357template <typename Real>
358struct quintic;
359//==============================================================================
360template <floating_point Real>
361struct quintic<Real> {
362 static constexpr std::size_t num_derivatives = 2;
363 using real_type = Real;
365 static constexpr std::size_t num_dimensions() { return 1; }
366 static_assert(std::is_arithmetic<Real>::value);
367
368 //----------------------------------------------------------------------------
369 // members
370 //----------------------------------------------------------------------------
371 private:
373
374 //----------------------------------------------------------------------------
375 // ctors
376 //----------------------------------------------------------------------------
377 public:
378 constexpr quintic() = default;
379 constexpr quintic(quintic const&) = default;
380 constexpr quintic(quintic&&) = default;
381 constexpr quintic& operator=(quintic const&) = default;
382 constexpr quintic& operator=(quintic&&) = default;
383 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
384 constexpr quintic(Real const t0, Real const t1, Real const ft0,
385 Real const ft1, Real const dft0_dt, Real const dft1_dt,
386 Real const ddft0_dtt, Real const ddft1_dtt)
387 : m_interpolant{0, 0, 0, 0, 0, 0} {
388 auto const A =
389 Mat4<Real>{{1.0, t0, t0 * t0, t0 * t0 * t0, t0 * t0 * t0 * t0,
390 t0 * t0 * t0 * t0 * t0},
391 {1.0, t1, t1 * t1, t1 * t1 * t1, t1 * t1 * t1 * t1,
392 t1 * t1 * t1 * t1 * t1},
393 {0.0, 1.0, 2 * t0, 3 * t0 * t0, 4 * t0 * t0 * t0,
394 5 * t0 * t0 * t0 * t0},
395 {0.0, 1.0, 2 * t1, 3 * t1 * t1, 4 * t1 * t1 * t1,
396 5 * t1 * t1 * t1 * t1},
397 {0.0, 0.0, 2.0, 6 * t0, 12 * t0 * t0, 20 * t0 * t0 * t0},
398 {0.0, 0.0, 2.0, 6 * t1, 12 * t1 * t1, 20 * t1 * t1 * t1}};
399 vec<Real, 6> b{ft0, ft1, dft0_dt, dft1_dt, ddft0_dtt, ddft1_dtt};
400 m_interpolant.set_coefficients(solve(A, b)->data());
401 }
402 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
403 constexpr quintic(Real const ft0, Real const ft1, Real const dft0_dt,
404 Real const dft1_dt, Real const ddft0_dtt,
405 Real const ddft1_dtt)
406 : m_interpolant{ft0,
407 dft0_dt,
408 ddft0_dtt / 2,
409 (20 * ft1 - 20 * ft0 - 8 * dft1_dt - 12 * dft0_dt +
410 ddft1_dtt - 3 * ddft0_dtt) /
411 2,
412 -(30 * ft1 - 30 * ft0 - 14 * dft1_dt - 16 * dft0_dt +
413 2 * ddft1_dtt - 3 * ddft0_dtt) /
414 2,
415 (12 * ft1 - 12 * ft0 - 6 * dft1_dt - 6 * dft0_dt +
416 ddft1_dtt - ddft0_dtt) /
417 2} {}
418
419 //----------------------------------------------------------------------------
420 // methods
421 //----------------------------------------------------------------------------
422 constexpr auto evaluate(arithmetic auto const t) const {
423 return m_interpolant(t);
424 }
425 //----------------------------------------------------------------------------
426 constexpr auto operator()(arithmetic auto const t) const {
427 return evaluate(t);
428 }
429 //----------------------------------------------------------------------------
430 constexpr auto polynomial() const -> auto const& { return m_interpolant; }
431 constexpr auto polynomial() -> auto& { return m_interpolant; }
432};
433//------------------------------------------------------------------------------
434template <floating_point Float>
435quintic(Float, Float, Float, Float, Float, Float) -> quintic<Float>;
436//==============================================================================
437} // namespace tatooine::interpolation
438//==============================================================================
439#endif
Definition: concepts.h:33
Definition: concepts.h:30
Definition: interpolation.h:13
typename interpolation_value_type_impl< T >::type interpolation_value_type
Definition: interpolation.h:92
typename interpolation_tensor_type_impl< T >::type interpolation_tensor_type
Definition: interpolation.h:119
auto solve(polynomial< Real, 1 > const &p) -> std::vector< Real >
solve a + b*x
Definition: polynomial.h:187
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
T type
Definition: common_type.h:13
constexpr cubic & operator=(cubic const &)=default
static constexpr std::size_t num_dimensions()
Definition: interpolation.h:223
Real real_type
Definition: interpolation.h:221
constexpr cubic & operator=(cubic &&)=default
constexpr cubic(Real const t0, Real const t1, Real const ft0, Real const ft1, Real const dft0_dt, Real const dft1_dt)
Definition: interpolation.h:235
constexpr cubic(Real const ft0, Real const ft1, Real const dft0_dt, Real const dft1_dt)
Definition: interpolation.h:248
constexpr cubic(cubic &&)=default
constexpr cubic(cubic const &)=default
constexpr cubic(real_type const t0, real_type const t1, vec_type const &ft0, vec_type const &ft1, vec_type const &dft0_dt, vec_type const &dft1_dt)
Definition: interpolation.h:301
constexpr cubic(vec_type const &ft0, vec_type const &ft1, vec_type const &dft0_dt, vec_type const &dft1_dt)
Definition: interpolation.h:297
static constexpr std::size_t num_dimensions()
Definition: interpolation.h:271
Real real_type
Definition: interpolation.h:267
constexpr cubic(vec_type const &ft0, vec_type const &ft1, vec_type const &dft0_dt, vec_type const &dft1_dt, std::index_sequence< Is... >)
Definition: interpolation.h:288
constexpr auto operator()(arithmetic auto const t) const
Definition: interpolation.h:329
constexpr cubic & operator=(cubic const &)=default
std::array< interpolant_type, N > polynomial_array_type
Definition: interpolation.h:270
constexpr auto evaluate(arithmetic auto const t, std::index_sequence< Is... >) const
Definition: interpolation.h:322
auto polynomial() -> auto &
Definition: interpolation.h:334
auto polynomial() const -> auto const &
Definition: interpolation.h:333
constexpr auto evaluate(arithmetic auto const t) const
Definition: interpolation.h:326
polynomial_array_type m_interpolants
Definition: interpolation.h:276
constexpr cubic & operator=(cubic &&)=default
Definition: interpolation.h:216
constexpr linear(Real const t0, Real const t1, Real const ft0, Real const ft1)
Definition: interpolation.h:47
constexpr linear & operator=(linear &&)=default
constexpr linear(Real const ft0, Real const ft1)
Definition: interpolation.h:44
interpolant_type m_interpolant
Definition: interpolation.h:33
constexpr auto polynomial() const -> auto const &
Definition: interpolation.h:60
constexpr linear & operator=(linear const &)=default
constexpr linear(linear const &)=default
constexpr auto polynomial() -> auto &
Definition: interpolation.h:61
constexpr auto operator()(arithmetic auto const t) const
Definition: interpolation.h:56
Real real_type
Definition: interpolation.h:25
constexpr linear(linear &&)=default
static constexpr std::size_t num_dimensions()
Definition: interpolation.h:27
constexpr auto evaluate(arithmetic auto const t) const
Definition: interpolation.h:53
constexpr linear(Real const t0, Real const t1, tensor_type const &ft0, tensor_type const &ft1)
Definition: interpolation.h:153
interpolation_value_type< tensor< Real, Dims... > > value_type
Definition: interpolation.h:134
constexpr auto operator()(arithmetic auto const t) const
Definition: interpolation.h:182
auto polynomial() -> auto &
Definition: interpolation.h:187
auto polynomial() const -> auto const &
Definition: interpolation.h:186
constexpr linear(tensor_type const &ft0, tensor_type const &ft1)
Definition: interpolation.h:163
constexpr linear & operator=(linear const &)=default
interpolation_tensor_type< tensor< Real, Dims... > > tensor_type
Definition: interpolation.h:135
constexpr auto evaluate(arithmetic auto const t) const
Definition: interpolation.h:174
constexpr linear & operator=(linear &&)=default
Definition: interpolation.h:16
constexpr quintic(Real const ft0, Real const ft1, Real const dft0_dt, Real const dft1_dt, Real const ddft0_dtt, Real const ddft1_dtt)
Definition: interpolation.h:403
static constexpr std::size_t num_dimensions()
Definition: interpolation.h:365
Real real_type
Definition: interpolation.h:363
constexpr auto polynomial() const -> auto const &
Definition: interpolation.h:430
constexpr quintic(quintic &&)=default
constexpr auto polynomial() -> auto &
Definition: interpolation.h:431
constexpr quintic & operator=(quintic const &)=default
constexpr auto evaluate(arithmetic auto const t) const
Definition: interpolation.h:422
constexpr quintic(quintic const &)=default
constexpr auto operator()(arithmetic auto const t) const
Definition: interpolation.h:426
interpolant_type m_interpolant
Definition: interpolation.h:372
constexpr quintic & operator=(quintic &&)=default
constexpr quintic(Real const t0, Real const t1, Real const ft0, Real const ft1, Real const dft0_dt, Real const dft1_dt, Real const ddft0_dtt, Real const ddft1_dtt)
Definition: interpolation.h:384
Definition: interpolation.h:358
Definition: mat.h:14
auto constexpr row(std::size_t i)
Definition: mat.h:172
constexpr auto set_coefficients(std::array< Real, Degree+1 > const &coeffs) -> void
Definition: polynomial.h:104
Definition: tags.h:112
Definition: tensor.h:17
Definition: index_order.h:17