Parallel Transport & Vector Transport
Moving tangent vectors between different points on a manifold requires a notion
of transport. cartan provides two levels: exact parallel transport (via a
connection) and the cheaper VectorTransport approximation used in optimizers.
Parallel Transport
Given a smooth curve $\gamma : [0,1] \to M$ with $\gamma(0) = p$, the parallel transport of $v \in T_pM$ along $\gamma$ is the unique vector field satisfying:
Here $D/dt$ denotes the covariant derivative along $\gamma$. The result $V(1) \in T_qM$ preserves the inner product: $g_q(V(1), W(1)) = g_p(v, w)$.
The ParallelTransport Trait
pub trait ParallelTransport: Connection {
/// Transport v ∈ T_pM to T_qM along the geodesic from p to q.
fn parallel_transport(
&self,
p: &Self::Point,
q: &Self::Point,
v: &Self::Tangent,
) -> Option<Self::Tangent>;
}Sphere<N>, Euclidean<N>, SO<N>, SE<N>Returns None when p and q are antipodal (the geodesic is undefined).
The transport is always along the geodesic segment, not an arbitrary path.
Blanket impl: ParallelTransport → VectorTransport
Any type implementing ParallelTransport automatically gets VectorTransport:
impl<M: ParallelTransport> VectorTransport for M {
fn vector_transport(&self, p, q, v) -> Option<Self::Tangent> {
self.parallel_transport(p, q, v) // exact, but cheap to call
}
}The dashed edge in the trait diagram visualises this blanket impl.
Holonomy
On a curved manifold, transporting a vector around a closed loop does not return the original vector. The holonomy of the loop measures the rotation:
On $S^2$, transporting a vector around a spherical triangle with angles $\alpha, \beta, \gamma$ produces a rotation by $\delta = \alpha + \beta + \gamma - \pi$ (the spherical excess). This is the same quantity as the enclosed area via Gauss–Bonnet.
Transport a north-pointing tangent at the north pole, east to $(1,0,0)$, south to the equator at $(0,1,0)$, then back to the north pole. The vector rotates by $\pi/2$, equal to the area of the spherical octant.
VectorTransport
pub trait VectorTransport: Manifold {
fn vector_transport(
&self,
p: &Self::Point,
q: &Self::Point,
v: &Self::Tangent,
) -> Option<Self::Tangent>;
}Sphere<N>, Euclidean<N>, SO<N>, SE<N>, SPD<N>, Grassmann<N,K>For Riemannian optimizers (conjugate gradient, Riemannian Adam) the exact
isometry property of ParallelTransport is not required; any map that moves
a tangent vector from $T_pM$ to $T_qM$ compatibly with the retraction suffices.
Sphere Formula
On , parallel transport of $v \in T_pM$ to $T_qM$ along the geodesic is:
This is exact (not an approximation) and costs a small fixed number of dot products.
Practical Usage
use cartan::prelude::*;
use cartan::manifolds::Sphere;
let s2 = Sphere::<3>;
let mut rng = rand::rng();
let p = s2.random_point(&mut rng);
let q = s2.random_point(&mut rng);
let v = s2.random_tangent(&p, &mut rng);
// Exact parallel transport (isometry).
let w_exact = s2.parallel_transport(&p, &q, &v).unwrap();
// Approximate (any VectorTransport impl; here identical).
let w_approx = s2.vector_transport(&p, &q, &v).unwrap();
// Inner product is preserved:
assert!((s2.inner(&p, &v, &v) - s2.inner(&q, &w_exact, &w_exact)).abs() < 1e-10);