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.

EquivariantFilter User Guide

The EquivariantFilter estimates a physical state ξM\xi\in M by maintaining a group element XGX\in G and a fixed reference ξ0\xi_0. The state estimate is ξ^=ϕX(ξ0)\hat\xi=\phi_X(\xi_0), where ϕX\phi_X is the state action. The class inherits from ManifoldEKF, but stores its covariance in error coordinates at the reference.

This user guide explains the state and error coordinates, the lift contract, prediction and correction conventions, and the additional requirements for automatic error linearization. API snippets describe the C++ template; the Python setup below follows the documentation notebook convention.

Open In Colab
import gtsam

Initialization and accessors

Instantiate EquivariantFilter<M, Symmetry> with a physical manifold type and a state-action functor. Symmetry derives from GroupAction<Symmetry, G, M> and declares its ActionType. Its orbit derivative with respect to the group supplies the innovation lift; the state derivative supplies covariance transport. The action must span the physical tangent space at the reference for arbitrary local corrections to be representable.

EquivariantFilter<M, Symmetry> filter(reference, P, initialGroup);

The initial group defaults to the identity. P is the covariance of error coordinates at reference, even when initialGroup is non-identity. state() returns the reconstructed physical estimate, groupEstimate() returns its group representative, errorCovariance() returns the reference covariance, and covariance() returns its pushforward to the current estimate. The filter keeps the reference fixed during ordinary prediction and correction.

State actions and lifts

An action specifies how group elements move physical states. In the equations below, ϕX(ξ)\phi_X(\xi) denotes either action type; the C++ functor takes (group, state) for ActionType::Left and (state, group) for ActionType::Right.

Action typeComposition ruleExample on rotations
LeftϕA(ϕB(ξ))=ϕAB(ξ)\phi_A(\phi_B(\xi))=\phi_{AB}(\xi)ϕA(R)=AR\phi_A(R)=AR
RightϕA(ϕB(ξ))=ϕBA(ξ)\phi_A(\phi_B(\xi))=\phi_{BA}(\xi)ϕA(R)=RA\phi_A(R)=RA

A lift Λ(ξ,u)\Lambda(\xi,u) converts the current input into a group velocity that generates the physical dynamics through that action. Every prediction API requires the lift condition

ddtt=0ϕExp(tΛ(ξ,u))(ξ)=fu(ξ).\left.\frac{d}{dt}\right|_{t=0} \phi_{\operatorname{Exp}(t\Lambda(\xi,u))}(\xi)=f_u(\xi).

This condition states that the lifted motion has the correct physical velocity. It does not, by itself, imply equivariance; automatic error linearization has an additional requirement described below.

Prediction at the current estimate

All prediction paths evaluate the supplied lift at the current estimate, λ=Λ(ξ^,u)\lambda=\Lambda(\hat\xi,u). The composition side places that increment at ξ^\hat\xi:

X+={Exp(hλ)X,left action,XExp(hλ),right action.ξ^+=ϕX+(ξ0).X^+=\begin{cases} \operatorname{Exp}(h\lambda)X,&\text{left action},\\ X\operatorname{Exp}(h\lambda),&\text{right action}. \end{cases} \qquad \hat\xi^+=\phi_{X^+}(\xi_0).

For example, the left-action composition rule gives ϕExp(hλ)X(ξ0)=ϕExp(hλ)(ξ^)\phi_{\operatorname{Exp}(h\lambda)X}(\xi_0)=\phi_{\operatorname{Exp}(h\lambda)}(\hat\xi). The right-action rule gives the same physical interpretation with the opposite multiplication side. The exponential step integrates a frozen lift; a general state-dependent lift may require smaller steps for accurate integration.

For a left action on rotations, the same physical motion can be expressed with a body or spatial velocity. If R˙=R[u]×\dot R=R[u]_\times, the lift is Λ(R,u)=Ru=AdRu\Lambda(R,u)=Ru=\operatorname{Ad}_R u, since a left action generates [Λ]×R[\Lambda]_\times R. Thus

Exp(h[Ru]×)R=RExp(h[u]×).\operatorname{Exp}(h[Ru]_\times)R=R\operatorname{Exp}(h[u]_\times).

If instead the input ω\omega is already a spatial angular velocity, R˙=[ω]×R\dot R=[\omega]_\times R, the correct lift is constant: Λ(R,ω)=ω\Lambda(R,\omega)=\omega. It still requires left composition. State independence does not determine the frame of an increment.

Migration for left-action callers: predictWithJacobian() formerly right-multiplied for both action types. A caller that supplied a body-coordinate velocity for a left-regular action must now supply the lift that generates motion through that action: Λ(R,u)=AdRu\Lambda(R,u)=\operatorname{Ad}_R u. Supplying an explicit covariance model does not convert the mean increment’s frame. Right-action callers retain their composition convention.

Error coordinates and automatic linearization

The filter error is e=ϕX1(ξ)e=\phi_{X^{-1}}(\xi), with local coordinates ϵ=Local(ξ0,e)\epsilon=\operatorname{Local}(\xi_0,e). The covariance PP, continuous error matrix AA, and process noise all refer to these coordinates. errorCovariance() returns PP; covariance() pushes it to the tangent space at the current estimate using the state-action differential.

Automatic prediction additionally needs an input action ψX\psi_X and an equivariant lift. The input action must be compatible with the physical dynamics, and the lift must satisfy

Λ(ϕX(ξ),ψX(u))={AdXΛ(ξ,u),left action,AdX1Λ(ξ,u),right action.\Lambda(\phi_X(\xi),\psi_X(u))= \begin{cases} \operatorname{Ad}_X\Lambda(\xi,u),&\text{left action},\\ \operatorname{Ad}_{X^{-1}}\Lambda(\xi,u),&\text{right action}. \end{cases}

Here AdX\operatorname{Ad}_X transports a group velocity by conjugation: for matrix groups, [AdXv]=X[v]X1[\operatorname{Ad}_X v]^\wedge=X[v]^\wedge X^{-1}. Lift equivariance is a separate condition from reproducing the dynamics. In particular, for a non-free action, adding a stabilizer velocity can preserve the physical dynamics while violating equivariance.

The input orbit psi_u holds the current input fixed and evaluates its action, psi_u(X) = psi_X(u). Mapping it to the reference gives u0=ψX1(u)u_0=\psi_{X^{-1}}(u). Define

Dϕ0=vv=0Local(ξ0,ϕExp(v)(ξ0)),DΛ=ϵϵ=0Λ(Retract(ξ0,ϵ),u0).D\phi_0=\left.\frac{\partial}{\partial v}\right|_{v=0} \operatorname{Local}(\xi_0,\phi_{\operatorname{Exp}(v)}(\xi_0)), \qquad D\Lambda=\left.\frac{\partial}{\partial\epsilon}\right|_{\epsilon=0} \Lambda(\operatorname{Retract}(\xi_0,\epsilon),u_0).

For an equivariant lift, the error velocity can be written as the infinitesimal action of Λ(e,u0)Λ(ξ0,u0)\Lambda(e,u_0)-\Lambda(\xi_0,u_0) at ee. This difference vanishes at the reference, so its linearization is

ϵ˙=Aϵ,A=Dϕ0DΛ.\dot\epsilon=A\epsilon,\qquad A=D\phi_0 D\Lambda.

The matrices have shapes dim(M)×dim(G)\dim(M)\times\dim(G) and dim(G)×dim(M)\dim(G)\times\dim(M) respectively, so the formula also covers non-free actions such as rotations acting on a direction. It removes explicit dependence on XX except through u0u_0; the transformed input can still vary over time.

For the left-regular body-velocity rotation example, the input action is trivial and Λ(R,u)=Ru\Lambda(R,u)=Ru. At R0=IR_0=I, Exp([ϵ]×)uu[u]×ϵ\operatorname{Exp}([\epsilon]_\times)u\approx u-[u]_\times\epsilon, so A=[u]×A=-[u]_\times. For the constant spatial lift, the compatible input action is ψX(ω)=Xω\psi_X(\omega)=X\omega and A=0A=0. These two examples explain why checking only whether a lift is constant cannot establish its dynamics or equivariance.

Choosing a prediction API

The three APIs share the same lift-at-the-estimate mean update. Only automatic prediction needs an input orbit and lift equivariance:

filter.predict(lift_u, psi_u, Qc, dt);          // Computes A automatically.
filter.predictWithJacobian(lift_u, A, Qc, dt);  // Caller supplies continuous A.
filter.predictWithTransition(lift_u, Phi, Qd, dt);  // Caller supplies discrete Phi/Qd.

The explicit paths need a callable lift_u(state) and an error model derived in reference error coordinates. They require neither an input-orbit constructor nor a lift Jacobian. The automatic path also constructs Lift(psi_u(X.inverse())) and evaluates its Jacobian at the reference. The supplied lift and input orbit must describe the same current input and model.

predict() and predictWithJacobian() use Φ=I+Adt\Phi=I+A\,dt by default, or the transitionMatrix<K>() exponential approximation for higher K, and Qd=QcdtQ_d=Q_c\,dt. They propagate P+=ΦPΦT+QdP^+=\Phi P\Phi^T+Q_d. predictWithTransition() uses the supplied discrete matrices directly and uses dt only for the mean. Do not pass a discrete transition as A, since it would be discretized again.

Measurement correction at the reference

A measurement correction is expressed at the reference, so it composes on the opposite side from prediction. With the implementation’s residual convention r=Local(z,z^)r=\operatorname{Local}(z,\hat z), the correction is

δξ=Kr,δx=(Dϕ0)+δξ,X+={XExp(δx),left action,Exp(δx)X,right action.\delta\xi=-Kr,\qquad \delta x=(D\phi_0)^+\delta\xi, \qquad X^+=\begin{cases} X\operatorname{Exp}(\delta x),&\text{left action},\\ \operatorname{Exp}(\delta x)X,&\text{right action}. \end{cases}

Both cases reconstruct ξ^+=ϕX(ϕExp(δx)(ξ0))\hat\xi^+=\phi_X(\phi_{\operatorname{Exp}(\delta x)}(\xi_0)) using the pre-update XX. The pseudo-inverse innovation lift accommodates different group and manifold dimensions. The measurement Jacobian supplied to the update must differentiate the predicted measurement with respect to ϵ\epsilon at the reference; a Jacobian in the tangent space at the current estimate must first be multiplied by actionDifferential(). The covariance update uses Joseph form in the reference coordinates.

OperationWhere its increment is definedLeft actionRight action
PredictionCurrent estimateExp(hλ)X\operatorname{Exp}(h\lambda)XXExp(hλ)X\operatorname{Exp}(h\lambda)
CorrectionReferenceXExp(δx)X\operatorname{Exp}(\delta x)Exp(δx)X\operatorname{Exp}(\delta x)X

The rotation and sphere fixtures in testEquivariantFilter.cpp exercise these conventions with non-identity estimates and reference states.