1 #ifndef hermite_interpolator_hpp
2 #define hermite_interpolator_hpp
4 #include "../common/common.hpp"
5 #include "scalar_traits.hpp"
14 template <
typename ValueType>
23 CoordinateType rangeStart() {
return m_start; }
24 CoordinateType rangeEnd() {
return m_end; }
26 void initialize(CoordinateType start, CoordinateType end,
27 const std::vector<ValueType>& values,
28 const std::vector<ValueType>& derivatives) {
29 if (values.size() != derivatives.size())
30 throw std::invalid_argument(
"HermiteInterpolator::setData(): "
31 "'values' and 'derivatives' must "
32 "have the same length");
33 if (values.size() < 2)
34 throw std::invalid_argument(
"HermiteInterpolator::setData(): "
35 "at least two points are required");
37 throw std::invalid_argument(
"HermiteInterpolator::setData(): "
38 "'start' must be smaller than 'end'");
42 m_interval = (end - start) / (m_n - 1);
44 m_derivatives = derivatives;
47 ValueType evaluate(CoordinateType x)
const {
48 assert(x >= m_start && x <= m_end);
50 const CoordinateType t = std::modf((x - m_start) / m_interval, &fpn);
51 const int n = int(fpn);
52 assert(n >= 0 && n < m_n);
53 assert(t >= 0 && t <= 1);
55 const ValueType f_1 = m_values[n];
56 const ValueType f_2 = m_values[n+1];
57 const ValueType d_1 = m_derivatives[n] * m_interval;
58 const ValueType d_2 = m_derivatives[n+1] * m_interval;
59 const ValueType Delta = f_2 - f_1;
60 const ValueType Delta_1 = d_1 - Delta;
61 const ValueType Delta_2 = d_2 - Delta;
62 const ValueType c_2 = -(Delta_1 + Delta_1 + Delta_2);
63 const ValueType c_3 = Delta_1 + Delta_2;
64 return f_1 + t * (d_1 + t * (c_2 + t * c_3));
69 CoordinateType m_start, m_end;
71 CoordinateType m_interval;
72 std::vector<ValueType> m_values;
73 std::vector<ValueType> m_derivatives;
Traits of scalar types.
Definition: scalar_traits.hpp:40
Definition: hermite_interpolator.hpp:15