10 #ifndef EIGEN_SPLINE_H 11 #define EIGEN_SPLINE_H 13 #include "SplineFwd.h" 34 template <
typename _Scalar,
int _Dim,
int _Degree>
74 template <
typename OtherVectorType,
typename OtherArrayType>
75 Spline(
const OtherVectorType&
knots,
const OtherArrayType&
ctrls) : m_knots(knots), m_ctrls(ctrls) {}
81 template <
int OtherDegree>
83 m_knots(spline.
knots()), m_ctrls(spline.
ctrls()) {}
88 const KnotVectorType&
knots()
const {
return m_knots; }
93 const ControlPointVectorType&
ctrls()
const {
return m_ctrls; }
128 template <
int DerivativeOrder>
130 derivatives(Scalar u, DenseIndex order = DerivativeOrder)
const;
172 template <
int DerivativeOrder>
179 DenseIndex
degree()
const;
185 DenseIndex
span(Scalar u)
const;
204 static BasisVectorType
BasisFunctions(Scalar u, DenseIndex degree,
const KnotVectorType& knots);
208 KnotVectorType m_knots;
209 ControlPointVectorType m_ctrls;
212 template <
typename _Scalar,
int _Dim,
int _Degree>
220 const Scalar* pos = std::upper_bound(knots.data()+degree-1, knots.data()+knots.size()-degree-1, u);
221 return static_cast<DenseIndex
>( std::distance(knots.data(), pos) - 1 );
224 template <
typename _Scalar,
int _Dim,
int _Degree>
233 const DenseIndex p =
degree;
238 BasisVectorType left(p+1); left(0) =
Scalar(0);
239 BasisVectorType right(p+1); right(0) =
Scalar(0);
244 BasisVectorType N(1,p+1);
246 for (DenseIndex j=1; j<=p; ++j)
249 for (DenseIndex r=0; r<j; r++)
251 const Scalar tmp = N(r)/(right(r+1)+left(j-r));
252 N[r] = saved + right(r+1)*tmp;
253 saved = left(j-r)*tmp;
260 template <
typename _Scalar,
int _Dim,
int _Degree>
264 return m_knots.size() - m_ctrls.cols() - 1;
269 template <
typename _Scalar,
int _Dim,
int _Degree>
275 template <
typename _Scalar,
int _Dim,
int _Degree>
280 const DenseIndex
span = this->
span(u);
281 const DenseIndex p =
degree();
286 return (ctrl_weights * ctrl_pts).rowwise().sum();
291 template <
typename SplineType,
typename DerivativeType>
292 void derivativesImpl(
const SplineType& spline,
typename SplineType::Scalar u, DenseIndex order, DerivativeType& der)
296 enum { DerivativeOrder = DerivativeType::ColsAtCompileTime };
300 typedef typename BasisDerivativeType::ConstRowXpr BasisDerivativeRowXpr;
302 const DenseIndex p = spline.degree();
303 const DenseIndex
span = spline.span(u);
305 const DenseIndex n = (std::min)(p, order);
310 const BasisDerivativeType basis_func_ders = spline.template basisFunctionDerivatives<DerivativeOrder>(u, n+1);
313 for (DenseIndex der_order=0; der_order<n+1; ++der_order)
317 der.col(der_order) = (ctrl_weights * ctrl_pts).rowwise().sum();
321 template <
typename _Scalar,
int _Dim,
int _Degree>
326 derivativesImpl(*
this, u, order, res);
330 template <
typename _Scalar,
int _Dim,
int _Degree>
331 template <
int DerivativeOrder>
336 derivativesImpl(*
this, u, order, res);
340 template <
typename _Scalar,
int _Dim,
int _Degree>
349 template <
typename SplineType,
typename DerivativeType>
350 void basisFunctionDerivativesImpl(
const SplineType& spline,
typename SplineType::Scalar u, DenseIndex order, DerivativeType& N_)
358 const KnotVectorType& U = spline.knots();
360 const DenseIndex p = spline.degree();
361 const DenseIndex
span = spline.span(u);
363 const DenseIndex n = (std::min)(p, order);
367 BasisVectorType left = BasisVectorType::Zero(p+1);
368 BasisVectorType right = BasisVectorType::Zero(p+1);
379 left[j] = u-U[span+1-j];
380 right[j] = U[span+j]-u;
383 for (DenseIndex r=0; r<j; ++r)
386 ndu(j,r) = right[r+1]+left[j-r];
387 temp = ndu(r,j-1)/ndu(j,r);
389 ndu(r,j) =
static_cast<Scalar
>(saved+right[r+1] * temp);
390 saved = left[j-r] * temp;
393 ndu(j,j) =
static_cast<Scalar
>(saved);
396 for (j = p; j>=0; --j)
400 DerivativeType a(n+1,p+1);
409 for (DenseIndex k=1; k<=static_cast<DenseIndex>(n); ++k)
412 DenseIndex rk,pk,j1,j2;
417 a(s2,0) = a(s1,0)/ndu(pk+1,rk);
418 d = a(s2,0)*ndu(rk,pk);
424 if (r-1 <= pk) j2 = k-1;
427 for (j=j1; j<=j2; ++j)
429 a(s2,j) = (a(s1,j)-a(s1,j-1))/ndu(pk+1,rk+j);
430 d += a(s2,j)*ndu(rk+j,pk);
435 a(s2,k) = -a(s1,k-1)/ndu(pk+1,r);
436 d += a(s2,k)*ndu(r,pk);
439 N_(k,r) =
static_cast<Scalar
>(d);
440 j = s1; s1 = s2; s2 = j;
447 for (DenseIndex k=1; k<=static_cast<DenseIndex>(n); ++k)
449 for (DenseIndex j=p; j>=0; --j) N_(k,j) *= r;
454 template <
typename _Scalar,
int _Dim,
int _Degree>
455 typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::BasisDerivativeType
459 basisFunctionDerivativesImpl(*
this, u, order, der);
463 template <
typename _Scalar,
int _Dim,
int _Degree>
464 template <
int DerivativeOrder>
465 typename SplineTraits< Spline<_Scalar, _Dim, _Degree>, DerivativeOrder >::BasisDerivativeType
469 basisFunctionDerivativesImpl(*
this, u, order, der);
474 #endif // EIGEN_SPLINE_H A class representing multi-dimensional spline curves.
Definition: Spline.h:35
static BasisVectorType BasisFunctions(Scalar u, DenseIndex degree, const KnotVectorType &knots)
Returns the spline's non-zero basis functions.
Definition: Spline.h:226
SplineTraits< Spline >::PointType PointType
The point type the spline is representing.
Definition: Spline.h:43
SplineTraits< Spline >::DerivativeType derivatives(Scalar u, DenseIndex order) const
Evaluation of spline derivatives of up-to given order.
Definition: Spline.h:323
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: TestIMU_Common.h:87
SplineTraits< Spline >::BasisDerivativeType basisFunctionDerivatives(Scalar u, DenseIndex order) const
Computes the non-zero spline basis function derivatives up to given order.
Definition: Spline.h:456
const ControlPointVectorType & ctrls() const
Returns the knots of the underlying spline.
Definition: Spline.h:93
Expression of a fixed-size or dynamic-size sub-vector.
Definition: ForwardDeclarations.h:83
PointType operator()(Scalar u) const
Returns the spline value at a given site .
Definition: Spline.h:276
DenseIndex span(Scalar u) const
Returns the span within the knot vector in which u is falling.
Definition: Spline.h:270
DenseIndex degree() const
Returns the spline degree.
Definition: Spline.h:261
Spline()
Creates a (constant) zero spline.
Definition: Spline.h:58
Expression of the multiple replication of a matrix or vector.
Definition: Replicate.h:62
static DenseIndex Span(typename SplineTraits< Spline >::Scalar u, DenseIndex degree, const typename SplineTraits< Spline >::KnotVectorType &knots)
Computes the spang within the provided knot vector in which u is falling.
Definition: Spline.h:213
const KnotVectorType & knots() const
Returns the knots of the underlying spline.
Definition: Spline.h:88
Definition: SplineFwd.h:19
SplineTraits< Spline >::ControlPointVectorType ControlPointVectorType
The data type representing the spline's control points.
Definition: Spline.h:52
Spline(const Spline< Scalar, Dimension, OtherDegree > &spline)
Copy constructor for splines.
Definition: Spline.h:82
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
SplineTraits< Spline >::BasisVectorType basisFunctions(Scalar u) const
Computes the non-zero basis functions at the given site.
Definition: Spline.h:342
Spline(const OtherVectorType &knots, const OtherArrayType &ctrls)
Creates a spline from a knot vector and control points.
Definition: Spline.h:75
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:42
SplineTraits< Spline >::BasisVectorType BasisVectorType
The data type used to store non-zero basis functions.
Definition: Spline.h:49
SplineTraits< Spline >::KnotVectorType KnotVectorType
The data type used to store knot vectors.
Definition: Spline.h:46
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.
Definition: Constants.h:21
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
_Scalar Scalar
Definition: Spline.h:38
double Scalar
Common scalar type.
Definition: FlexibleKalmanBase.h:48