45#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_SPLINE_LINEAR_INL
46#define LASS_GUARDIAN_OF_INCLUSION_NUM_SPLINE_LINEAR_INL
59template <
typename S,
typename D,
typename T>
60SplineLinear<S, D, T>::SplineLinear()
84template <
typename S,
typename D,
typename T>
85template <
typename PairInputIterator>
86SplineLinear<S, D, T>::SplineLinear(PairInputIterator iFirst,
87 PairInputIterator iLast)
89 while (iFirst != iLast)
92 node.x = iFirst->first;
93 node.y = iFirst->second;
94 nodes_.push_back(node);
119template <
typename S,
typename D,
typename T>
120template <
typename ScalarInputIterator,
typename DataInputIterator>
121SplineLinear<S, D, T>::SplineLinear(ScalarInputIterator iFirstControl,
122 ScalarInputIterator iLastControl,
123 DataInputIterator iFirstData)
125 while (iFirstControl != iLastControl)
128 node.x = *iFirstControl++;
129 node.y = *iFirstData++;
130 nodes_.push_back(node);
147template <
typename S,
typename D,
typename T>
148const typename SplineLinear<S, D, T>::TData
153 const typename TNodes::const_iterator n = findNode(iX);
154 const TScalar dx = iX - n->x;
157 TDataTraits::multiplyAccumulate(result, n->dy, dx);
177template <
typename S,
typename D,
typename T>
178const typename SplineLinear<S, D, T>::TData
183 return findNode(iX)->dy;
201template <
typename S,
typename D,
typename T>
202const typename SplineLinear<S, D, T>::TData
203SplineLinear<S, D, T>::derivative2(TScalar )
const
205 LASS_ASSERT(!isEmpty());
208 TDataTraits::zero(result, dataDimension_);
225template <
typename S,
typename D,
typename T>
226const typename SplineLinear<S, D, T>::TData
231 TNodeConstIterator first = findNode(iBegin);
232 TNodeConstIterator last = findNode(iEnd);
235 TData result(first->y);
236 TDataTraits::scale(result, iEnd - iBegin);
237 TDataTraits::multiplyAccumulate(result, first->dy,
243 TScalar multiplier = 1;
246 std::swap(iBegin, iEnd);
247 std::swap(first, last);
251 TNodeConstIterator next = stde::next(first);
253 TData result(first->y);
254 TDataTraits::scale(result, next->x - iBegin);
255 TDataTraits::multiplyAccumulate(result, first->dy,
259 while (first != last)
261 const TScalar dx = next->x - first->x;
262 TDataTraits::multiplyAccumulate(result, first->y, dx);
263 TDataTraits::multiplyAccumulate(result, first->dy,
num::sqr(dx) / 2);
267 const TScalar dx = iEnd - first->x;
268 TDataTraits::multiplyAccumulate(result, first->y, dx);
269 TDataTraits::multiplyAccumulate(result, first->dy,
num::sqr(dx) / 2);
271 TDataTraits::scale(result, multiplier);
282template <
typename S,
typename D,
typename T>
285 return nodes_.empty();
294template <
typename S,
typename D,
typename T>
295const typename SplineLinear<S, D, T>::TControlRange
298 typedef typename SplineLinear<S, D, T>::TControlRange TRange;
299 return TRange(nodes_.front().x, nodes_.back().x);
306template <
typename S,
typename D,
typename T>
307void SplineLinear<S, D, T>::init()
311 const typename TNodes::size_type size = nodes_.size();
314 LASS_THROW(
"A linear interpolator needs at least two nodes! This one only has '"
315 <<
static_cast<unsigned>(nodes_.size()) <<
"'.");
318 typename TNodes::iterator prev = nodes_.begin();
319 dataDimension_ = TDataTraits::dimension(prev->y);
320 const typename TNodes::iterator end = nodes_.end();
321 for (
typename TNodes::iterator i = stde::next(nodes_.begin()); i != end; prev = i++)
327 LASS_THROW(
"Nodes in linear interpolator must have absolutely increasing control "
333 if (TDataTraits::dimension(i->y) != dataDimension_)
335 LASS_THROW(
"All data in linear interpolator must be of same dimension.");
341 TDataTraits::multiplyAccumulate(prev->dy, prev->y, -1);
342 TDataTraits::scale(prev->dy,
num::inv(i->x - prev->x));
346 stde::prev(end)->dy = stde::prev(end, 2)->dy;
360template <
typename S,
typename D,
typename T>
361const typename SplineLinear<S, D, T>::TNodeConstIterator
362SplineLinear<S, D, T>::findNode(TScalar iX)
const
364 LASS_ASSERT(nodes_.size() >= 2);
368 if (iX < nodes_.front().x)
370 return nodes_.begin();
372 if (iX >= nodes_.back().x)
374 return stde::prev(nodes_.end());
379 TNodeConstIterator first = nodes_.begin();
380 TNodeConstIterator last = nodes_.end();
381 while (stde::next(first) != last)
383 TNodeConstIterator middle = stde::next(first, std::distance(first, last) / 2);
384 LASS_ASSERT(middle != first && middle != last);
394 LASS_ASSERT(first != last);
397 LASS_ASSERT(first->x <= iX && last->x > iX);
const TControlRange controlRange() const override
return the range of control values for which the spline can interpolate.
bool isEmpty() const override
return true if the spline contains any nodes at all.
const TData derivative(TScalar iX) const override
Get the first derivative of data value that corresponds with constrol value iX.
const TData integral(TScalar iA, TScalar iB) const override
Get the integrated data value between control points iA and iB.
const TData operator()(TScalar iX) const override
Get the linear interpolated data value that corresponds with constrol value iX.
T sqr(const T &x)
return x * x
T inv(const T &x)
return x ^ -1
numeric types and traits.
Library for Assembled Shared Sources.