Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

CardinalSplineBasis

Open In Colab

Note: AI was used in the creation of this example.

CardinalSplineBasis provides cubic cardinal-spline weights for interpolating scalar or vector coefficients at a known coordinate. This guide explains the weights and shows how the class fits GTSAM’s basis-function API.

Use CumulativeSplineTrajectory<T> instead when the controls are poses, rotations, or other Lie-group values.

Primary contributor: Brett Downing.

import gtsam
import numpy as np

When to use it

Use CardinalSplineBasis when:

  • the coefficients are scalars or vectors;

  • the sample coordinate is an ordinary numeric value; and

  • you need cubic interpolation weights or a Basis evaluation functor.

Do not apply these weights directly to poses or rotations: scalar multiplication and addition are not the correct operations for Lie-group values. For those controls, use CumulativeSplineTrajectory<T>.

Basis weights

For coefficients p0,,pN1p_0, \ldots, p_{N-1}, the interpolated value is the weighted sum

f(t)=i=0N1Bi(t)pi.f(t)=\sum_{i=0}^{N-1} B_i(t)p_i.

CalculateWeights returns the dense vector B(t)B(t). Only a small neighborhood has nonzero interior weights, while the first and last entries absorb the constant tails. The weights sum to one, so a constant set of coefficients remains constant.

Python usage

Python exposes the class as gtsam.CardinalSplineBasis. CalculateWeights(N, x) returns the interpolation weights for N coefficients at the unit-spaced coordinate x; DerivativeWeights(N, x) returns the first-derivative weights. Both methods also accept a and b to map a bounded coordinate interval over the full spline support.

coefficients = np.array([1.0, 2.0, 0.5, 3.0])
weights = gtsam.CardinalSplineBasis.CalculateWeights(len(coefficients), 3.5)
derivative_weights = gtsam.CardinalSplineBasis.DerivativeWeights(
    len(coefficients), 3.5
)
value = weights @ coefficients
derivative = derivative_weights @ coefficients
np.testing.assert_allclose(weights.sum(), 1.0)
weights, value, derivative
(array([0.02083333, 0.47916667, 0.47916667, 0.02083333]), 1.2812499999999996, -0.6875000000000002)

Taking the dot product of the returned weights with scalar coefficients evaluates the curve or its derivative. For vector coefficients, arrange the values as columns and apply the same weights along the coefficient axis.

C++ usage

The class can provide a functor to GTSAM’s generic basis evaluation machinery:

Vector coefficients{1.0, 2.0, 0.5, 3.0};
CardinalSplineBasis::EvaluationFunctor evaluate(coefficients.size(), 3.5);
double value = evaluate(coefficients);

EvaluationFunctor stores the weights for the chosen coordinate. DerivativeFunctor does the same for a derivative order. These functors can also be used with the generic evaluation factors declared in Basis.h.

Relationship to cumulative kernels

The implementation obtains the dense weights from shifted cumulative-kernel activations ci(t)c_i(t). For NN coefficients,

B0=1c1,Bi=cici+1,BN1=cN1.B_0=1-c_1, \qquad B_i=c_i-c_{i+1}, \qquad B_{N-1}=c_{N-1}.

This difference-of-cumulative-steps form explains why the weights are local and sum to one. For scalar or vector coefficients, it is algebraically equivalent to starting at p0p_0 and cumulatively adding weighted differences pipi1p_i-p_{i-1}.

That equivalence does not make the two GTSAM classes interchangeable. CardinalSplineBasis forms an ordinary linear combination of coefficients. CumulativeSplineTrajectory<T> maps relative pose or rotation changes through the Lie-group logarithm and exponential, and it supports expression-valued time and bounded windows.