InsightSoftwareConsortium / InsightSoftwareConsortium/ITK
ENH: Tier the itk::Math convenience numerics outside the core API contract (Eigen-unsupported model)
- Dominant language
- C++
- Stars
- 1.7k
- Forks
- 748
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 64
Description
The VNL → Eigen migration (#6403) has been adding Eigen-backed numerics as `itk::Math::*` / `itk::*` APIs (`itk::Math::SVD`, `itk::QRDecomposition`, `itk::*EigenDecomposition`, `itk::Math::SolveSymmetric`, …). @blowekamp raised a concern that this repeats VNL's original mistake: by exposing general-purpose math algorithms through ITK's public API, ITK became their de-facto maintainer and compatibility guarantor for decades. This issue proposes segregating these APIs into a clearly-labeled namespace that marks them as useful conveniences, **not** part of the core ITK API contract — analogous to Eigen's `unsupported/` modules.
The concern
VNL was vendored as an implementation detail, but its symbols leaked into ITK's public surface (`GetVnlVector`, `vnl_matrix` in signatures, direct downstream use of `vnl_svd`, `vnl_lbfgsb`, …). Result: ITK could not change, upgrade, or remove its numerics backend without breaking downstream projects, and the toolkit inherited a support obligation for general linear algebra that is not its mission.
The replacement campaign is at risk of recreating that coupling one level up. Each new `itk::Math::*` wrapper is currently indistinguishable — in namespace, header location, and implied support level — from core ITK contract API like `itk::Image` or `itk::ImageFileReader`. Downstream projects (ANTs, BRAINSTools, Slicer, elastix) will adopt them as freely as they adopted `vnl_svd`, and in 20 years ITK would again be unable to swap the backend (today Eigen, tomorrow something else) without a deprecation campaign of this same scale.
Proposal sketch
Place the math-convenience layer in a namespace (and matching header path) that signals its support tier, e.g.:
- `itk::unsupported::Math::*` — mirrors Eigen's precedent exactly: `unsupported/Eigen/*` modules are robust, widely used, and maintained, but explicitly outside the core Eigen API-stability contract.
- Alternatives to bikeshed: `itk::convenience::`, `itk::numerics::`, `itk::detail::` (too strong — implies "do not use"), or a documented support-tier annotation without a namespace change.
What the tier would mean, concretely:
1. **Usable and tested** — shipped, wrapped where appropriate, covered by GTests, not second-class in quality.
2. **No backend-stability promise** — the numerical backend (currently Eigen) may change between minor releases; results are guaranteed only to documented tolerances, not bit-exactly.
3. **Shorter deprecation window** — signatures may evolve without the multi-release three-state ceremony required for core API.
4. **Not the recommended long-term home** — projects needing hard numerical guarantees should depend on a numerics library directly.
Timing matters: the `itk::Math::*` surface is young (#6454, #6473, #6475, #6487, #6565 merged; #6564/#6568 in review) and downstream adoption is only starting (gated `#ifdef ITK_MATH_HAS_SOLVE_SYMMETRIC` adoptions in ANTs/BRAINSTools). Renaming/re-tiering now costs little; after one or two releases it becomes another VNL.
Open questions
- Namespace name and header layout (`itk/unsupported/…`? `Modules/Core/CommonMath`?).
- Does the tier apply only to the new Eigen-backed wrappers, or also to long-standing math utilities (`itk::Math::abs`, `itkMath.h` constants) that are effectively core contract already?
- Python wrapping policy for the tier.
- How the tier interacts with #6230 (no transitive Eigen exposure) — the namespace does not weaken that rule; Eigen types stay out of all public signatures regardless of tier.
- Whether already-merged `itk::Math::SVD` etc. get aliased-and-deprecated into the new namespace or moved outright while adoption is still minimal.
Related: #6403 (umbrella migration), #6230 (no transitive Eigen exposure).
Contributor guide
Assessment
This issue has not been assessed yet.