1 /*
2 * Copyright Nick Thompson, 2019
3 * Use, modification and distribution are subject to the
4 * Boost Software License, Version 1.0. (See accompanying file
5 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 *
7 * Exactly the same as barycentric_rational.hpp, but delivers values in $\mathbb{R}^n$.
8 * In some sense this is trivial, since each component of the vector is computed in exactly the same
9 * as would be computed by barycentric_rational.hpp. But this is a bit more efficient and convenient.
10 */
11
12 #ifndef BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP
13 #define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP
14
15 #include <memory>
16 #include <boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp>
17
18 namespace boost{ namespace math{
19
20 template<class TimeContainer, class SpaceContainer>
21 class vector_barycentric_rational
22 {
23 public:
24 using Real = typename TimeContainer::value_type;
25 using Point = typename SpaceContainer::value_type;
26 vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order = 3);
27
28 void operator()(Point& x, Real t) const;
29
30 // I have validated using google benchmark that returning a value is no more expensive populating it,
31 // at least for Eigen vectors with known size at compile-time.
32 // This is kinda a weird thing to discover since it goes against the advice of basically every high-performance computing book.
operator ()(Real t) const33 Point operator()(Real t) const {
34 Point p;
35 this->operator()(p, t);
36 return p;
37 }
38
prime(Point & dxdt,Real t) const39 void prime(Point& dxdt, Real t) const {
40 Point x;
41 m_imp->eval_with_prime(x, dxdt, t);
42 }
43
prime(Real t) const44 Point prime(Real t) const {
45 Point p;
46 this->prime(p, t);
47 return p;
48 }
49
eval_with_prime(Point & x,Point & dxdt,Real t) const50 void eval_with_prime(Point& x, Point& dxdt, Real t) const {
51 m_imp->eval_with_prime(x, dxdt, t);
52 return;
53 }
54
eval_with_prime(Real t) const55 std::pair<Point, Point> eval_with_prime(Real t) const {
56 Point x;
57 Point dxdt;
58 m_imp->eval_with_prime(x, dxdt, t);
59 return {x, dxdt};
60 }
61
62 private:
63 std::shared_ptr<detail::vector_barycentric_rational_imp<TimeContainer, SpaceContainer>> m_imp;
64 };
65
66
67 template <class TimeContainer, class SpaceContainer>
vector_barycentric_rational(TimeContainer && times,SpaceContainer && points,size_t approximation_order)68 vector_barycentric_rational<TimeContainer, SpaceContainer>::vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order):
69 m_imp(std::make_shared<detail::vector_barycentric_rational_imp<TimeContainer, SpaceContainer>>(std::move(times), std::move(points), approximation_order))
70 {
71 return;
72 }
73
74 template <class TimeContainer, class SpaceContainer>
operator ()(typename SpaceContainer::value_type & p,typename TimeContainer::value_type t) const75 void vector_barycentric_rational<TimeContainer, SpaceContainer>::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const
76 {
77 m_imp->operator()(p, t);
78 return;
79 }
80
81 }}
82 #endif
83