vector_barycentric_rational.hpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. #ifndef BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP
  12. #define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP
  13. #include <memory>
  14. #include <boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp>
  15. namespace boost{ namespace math{
  16. template<class TimeContainer, class SpaceContainer>
  17. class vector_barycentric_rational
  18. {
  19. public:
  20. using Real = typename TimeContainer::value_type;
  21. using Point = typename SpaceContainer::value_type;
  22. vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order = 3);
  23. void operator()(Point& x, Real t) const;
  24. // I have validated using google benchmark that returning a value is no more expensive populating it,
  25. // at least for Eigen vectors with known size at compile-time.
  26. // This is kinda a weird thing to discover since it goes against the advice of basically every high-performance computing book.
  27. Point operator()(Real t) const {
  28. Point p;
  29. this->operator()(p, t);
  30. return p;
  31. }
  32. void prime(Point& dxdt, Real t) const {
  33. Point x;
  34. m_imp->eval_with_prime(x, dxdt, t);
  35. }
  36. Point prime(Real t) const {
  37. Point p;
  38. this->prime(p, t);
  39. return p;
  40. }
  41. void eval_with_prime(Point& x, Point& dxdt, Real t) const {
  42. m_imp->eval_with_prime(x, dxdt, t);
  43. return;
  44. }
  45. std::pair<Point, Point> eval_with_prime(Real t) const {
  46. Point x;
  47. Point dxdt;
  48. m_imp->eval_with_prime(x, dxdt, t);
  49. return {x, dxdt};
  50. }
  51. private:
  52. std::shared_ptr<detail::vector_barycentric_rational_imp<TimeContainer, SpaceContainer>> m_imp;
  53. };
  54. template <class TimeContainer, class SpaceContainer>
  55. vector_barycentric_rational<TimeContainer, SpaceContainer>::vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order):
  56. m_imp(std::make_shared<detail::vector_barycentric_rational_imp<TimeContainer, SpaceContainer>>(std::move(times), std::move(points), approximation_order))
  57. {
  58. return;
  59. }
  60. template <class TimeContainer, class SpaceContainer>
  61. void vector_barycentric_rational<TimeContainer, SpaceContainer>::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const
  62. {
  63. m_imp->operator()(p, t);
  64. return;
  65. }
  66. }}
  67. #endif