cartan

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

Definition null (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>;
}
Implemented by: 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: ParallelTransportVectorTransport

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:

Remark null.

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.

Example ?: Holonomy on S²; 90° triangle

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>;
}
Implemented by: 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);