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.

Pseudo-Spectral Chebyshev Trajectory Fitting

This notebook fits a smooth planar trajectory to regularly spaced 2D samples with a factor graph. The unknown is a 2×N2 \times N matrix whose columns are trajectory positions at second-kind Chebyshev (Chebyshev--Lobatto) points. VectorEvaluationFactorChebyshev2 interpolates those unknown node values at every sample parameter.

The trajectory comes from the VERTEX2 records in GTSAM’s examples/Data/example.graph dataset. We load those records through GTSAM’s dataset.h machinery rather than parsing the file in Python.

Open In Colab

Load the regularly spaced 2D trajectory

findExampleDataFile locates the packaged dataset, and load2D invokes GTSAM’s dataset.h loader. The returned Values contains a Pose2 at each untagged key from a VERTEX2 record, as well as tagged landmark values that we exclude. We retain each pose’s translation and use vertex order as a regularly spaced trajectory parameter on [0,1][0,1]. The edge factors in the file are not needed for this curve-fitting example.

Loaded 95 VERTEX2 samples from /Users/dellaert/.local/lib/python3.12/site-packages/gtsam/Data/example.graph
First point: [-0.138  0.342]
Last point:  [53.529  8.305]
Loading...

Build the factor graph

Let P∈R2×NP \in \mathbb{R}^{2 \times N} contain the unknown 2D positions at the NN Chebyshev points. For sample parameter tit_i, Chebyshev2 computes barycentric weights w(ti)w(t_i) and predicts

p^i=P w(ti).\hat p_i = P\,w(t_i).

Every VectorEvaluationFactorChebyshev2 adds the residual p^i−pi\hat p_i-p_i to the same matrix variable. Thus the graph solves the least-squares problem over all regular samples. N is the number of pseudo-spectral nodes, so the interpolating polynomial has degree at most N−1N-1.

Graph: 95 sample factors, one 2x16 variable

Optimize the Chebyshev node values

For a useful initial visualization, we linearly interpolate the regular samples at the fixed Chebyshev parameters. The factor model is linear in PP, so the initial value does not affect the least-squares optimum and Gauss--Newton reaches it in one linear step.

Initial graph error: 4.788934
Final graph error:   2.309378
Optimized node matrix shape: (2, 16)

Interpolate the fitted trajectory

The optimized columns of node_matrix are values at the red Chebyshev points, not polynomial coefficients. A dense WeightMatrix interpolates those values to produce the continuous trajectory.

Loading...

What the factor graph buys us

The graph representation makes it straightforward for the same Chebyshev node matrix to participate in additional factors, such as endpoint observations, derivative constraints, component-specific measurements, or joint estimation with other variables.

Optimize the same parameters with gradient descent

We can also optimize the 2×N2 \times N Chebyshev node matrix directly, using gradient descent. We’ll leave it there whether this is a good idea or not, :-).

Let W∈RM×NW \in \mathbb{R}^{M \times N} contain the barycentric interpolation weights at the MM sample parameters, let P∈R2×NP \in \mathbb{R}^{2 \times N} contain the Chebyshev node positions, and let Y∈RM×2Y \in \mathbb{R}^{M \times 2} contain the data. We define the mean loss per 2D sample as

L(P)=12M∥WPT−Y∥F2,\mathcal{L}(P) = \frac{1}{2M}\left\|W P^T - Y\right\|_F^2,

with gradient

∇PL(P)=1M(WPT−Y)TW.\nabla_P \mathcal{L}(P) = \frac{1}{M}\left(WP^T-Y\right)^T W.

The node positions are the only parameters; the regular trajectory samples are fixed data.

Starting from zero node positions, each gradient-descent step applies P←P−η ∇PLP \leftarrow P - \eta\,\nabla_P\mathcal{L}. We choose a conservative fixed learning rate from the Frobenius norm of WW, avoiding any matrix factorization.

Learning rate: 0.903
Initial loss: 740.829278
Final loss:   0.024309
Loading...