echidna_optim/lib.rs
1//! Optimization solvers with automatic differentiation support, plus implicit
2//! differentiation tools for differentiating through fixed-point equations.
3//!
4//! This crate depends on [`echidna`] with the `bytecode` feature enabled,
5//! giving it access to bytecode tapes, forward-over-reverse Hessians, and
6//! sparse derivative machinery.
7//!
8//! # Solvers
9//!
10//! Three unconstrained optimizers, all operating on a bytecode-tape
11//! [`Objective`]:
12//!
13//! - **L-BFGS** ([`lbfgs`]) — two-loop recursion limited-memory quasi-Newton.
14//! Low per-iteration cost; the default choice for smooth, large-scale problems.
15//! - **Newton** ([`newton`]) — exact Hessian with Cholesky factorization.
16//! Quadratic convergence near the solution; practical when `n` is moderate.
17//! - **Trust-region** ([`trust_region`]) — Steihaug-Toint conjugate-gradient
18//! subproblem. Robust on indefinite or ill-conditioned Hessians.
19//!
20//! # Line search
21//!
22//! All solvers use **Armijo backtracking** ([`ArmijoParams`]) to enforce
23//! sufficient decrease along the search direction.
24//!
25//! # Implicit differentiation
26//!
27//! Differentiate through solutions of `F(z, x) = 0` via the Implicit Function
28//! Theorem without unrolling the solver:
29//!
30//! - [`implicit_tangent`] — tangent (forward) mode: `dz/dx · v`
31//! - [`implicit_adjoint`] — adjoint (reverse) mode: `(dz/dx)^T · w`
32//! - [`implicit_jacobian`] — full Jacobian `dz/dx`
33//! - [`implicit_hvp`] — Hessian-vector product of a loss composed with the
34//! implicit solution
35//! - [`implicit_hessian`] — full Hessian of a loss composed with the implicit
36//! solution
37//!
38//! # Piggyback differentiation
39//!
40//! Differentiate through fixed-point iterations `z = G(z, x)` by
41//! interleaving derivative accumulation with the primal iteration:
42//!
43//! - [`piggyback_tangent_solve`] — tangent mode (forward)
44//! - [`piggyback_adjoint_solve`] — adjoint mode (reverse)
45//! - [`piggyback_forward_adjoint_solve`] — interleaved forward-adjoint for
46//! second-order derivatives
47//! - [`piggyback_tangent_step`] / [`piggyback_tangent_step_with_buf`] —
48//! single-step building blocks for custom loops
49//!
50//! # Sparse implicit differentiation
51//!
52//! With the **`sparse-implicit`** feature, [`sparse_implicit`] exploits
53//! structural sparsity in `F_z` for efficient implicit differentiation via
54//! `faer` sparse LU factorization. See [`SparseImplicitContext`],
55//! [`implicit_tangent_sparse`], [`implicit_adjoint_sparse`], and
56//! [`implicit_jacobian_sparse`].
57
58pub mod convergence;
59pub mod implicit;
60pub mod linalg;
61pub mod line_search;
62pub mod objective;
63pub mod piggyback;
64pub mod result;
65pub mod solvers;
66
67#[cfg(feature = "sparse-implicit")]
68pub mod sparse_implicit;
69
70pub use convergence::ConvergenceParams;
71pub use implicit::{
72 implicit_adjoint, implicit_hessian, implicit_hvp, implicit_jacobian, implicit_tangent,
73};
74
75pub use line_search::ArmijoParams;
76pub use objective::{Objective, TapeObjective};
77pub use piggyback::{
78 piggyback_adjoint_solve, piggyback_forward_adjoint_solve, piggyback_tangent_solve,
79 piggyback_tangent_step, piggyback_tangent_step_with_buf,
80};
81pub use result::{OptimResult, TerminationReason};
82pub use solvers::lbfgs::{lbfgs, LbfgsConfig};
83pub use solvers::newton::{newton, NewtonConfig};
84pub use solvers::trust_region::{trust_region, TrustRegionConfig};
85#[cfg(feature = "sparse-implicit")]
86pub use sparse_implicit::{
87 implicit_adjoint_sparse, implicit_jacobian_sparse, implicit_tangent_sparse,
88 SparseImplicitContext,
89};