1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// ~/cartan/cartan-core/src/geodesic.rs
//! The `GeodesicInterpolation` trait: sampling points along geodesics.
//!
//! Geodesic interpolation provides a way to move continuously between
//! two points on a manifold along the shortest path (minimizing geodesic).
//! This is the manifold analogue of linear interpolation in Euclidean space.
//!
//! ## Definition
//!
//! Given points p, q in M and parameter t in [0, 1], the geodesic
//! interpolation gamma(p, q, t) is defined as:
//!
//! gamma(p, q, t) = Exp_p(t * Log_p(q))
//!
//! Properties:
//! gamma(p, q, 0) = p
//! gamma(p, q, 1) = q
//! d/dt gamma(p, q, t)|_{t=0} = Log_p(q) (initial velocity)
//!
//! ## Applications
//!
//! - Frechet mean computation (iterative: barycenter in T_pM)
//! - Geodesic grid generation for visualization
//! - Midpoint computation (t = 0.5) for Riemannian bisection
//! - Slerp generalization (spherical: reduces to standard slerp)
//!
//! ## Failure modes
//!
//! Like Log_p(q), geodesic interpolation fails at the cut locus. The
//! method returns an error rather than panicking, allowing callers to
//! detect and handle this case (e.g., by using a retraction-based fallback).
//!
//! ## References
//!
//! - do Carmo. "Riemannian Geometry." Chapter 3 (geodesics).
//! - Pennec, Fillard, Ayache. "A Riemannian Framework for Tensor Computing."
//! IJCV, 2006. Section 3.2 (geodesic interpolation for SPD matrices).
use crate::;
/// A manifold with geodesic interpolation between points.
///
/// The geodesic interpolation gamma(p, q, t) = Exp_p(t * Log_p(q))
/// parameterizes the unique minimizing geodesic from p to q (when it exists).
///
/// # Supertraiting Manifold
///
/// GeodesicInterpolation requires Self: Manifold because it is defined
/// via exp and log. A default implementation could be provided here using
/// self.exp(p, self.log(p, q)? * t), but we leave it as an abstract method
/// to allow manifolds to provide more numerically stable implementations
/// (e.g., direct formula on the sphere using sin/cos).