Skip to content

ENH: Deprecate the vnl_svd family for the Eigen-backed itk::Math::SVD#6564

Open
hjmjohnson wants to merge 4 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:enh-deprecate-vnl-svd-family
Open

ENH: Deprecate the vnl_svd family for the Eigen-backed itk::Math::SVD#6564
hjmjohnson wants to merge 4 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:enh-deprecate-vnl-svd-family

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Jul 8, 2026

Copy link
Copy Markdown
Member

Deprecates the vnl_svd family (vnl_svd, vnl_svd_fixed, vnl_svd_economy, vnl_matrix_inverse) in favor of the Eigen-backed itk::Math::SVD, migrates every in-tree consumer, and build-gates the LINPACK svdc engine out of ITK_FUTURE_LEGACY_REMOVE. The itk::Math::SolveSymmetric/InverseSymmetric (LDLT) work that previously lived here is split out to #6565 so the two review independently.

Commit structure (4 thematic commits)
  1. Extend itk::Math::SVD — pseudo-inverse, solve, rank, recompose, null-vector, WellCondition, DeterminantMagnitude; eigenvector sign routed through itkEigenDecompositionSignConvention for backend-stable results.
  2. Test the extended surface against vnl_svd on well- and ill-conditioned inputs.
  3. Migrate consumers (transforms, DTI reconstruction, image moments, label-map, membership functions, Mahalanobis metrics, Quasi-Newton optimizer, NIfTI/MINC IO, classifier estimators, itk::Matrix::GetInverse). Widely-included headers keep the transitive vnl_svd* include reachable under #if !defined(ITK_LEGACY_REMOVE) && !defined(ITK_FUTURE_LEGACY_REMOVE) so downstream code that relied on it still compiles during the deprecation window.
  4. Deprecate the vnl_svd family with the three-state guard (silent default / #warning under ITK_LEGACY_REMOVE / #error under ITK_FUTURE_LEGACY_REMOVE) and build-gate the LINPACK svdc sources.
Downstream validation (forest)

Built against this branch's tip in the ITK downstream forest: ITK, ANTs, BRAINSTools, c3d, SimpleITK all compile clean. The one real regression found — ANTs antsAffineInitializer relying on a transitive vnl_svd_fixed.h via itkTransform.hxx — is fixed by the guarded transitive includes in commit 3. No consumer hit any vnl_svd/vnl_matrix_inverse/itk::Math::SVD compile error. (c3d and SimpleITK additionally needed their own upstream ITK6-migration PRs, unrelated to this change.)

@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Core Issues affecting the Core module area:Filtering Issues affecting the Filtering module area:IO Issues affecting the IO module area:Registration Issues affecting the Registration module area:Segmentation Issues affecting the Segmentation module area:ThirdParty Issues affecting the ThirdParty module area:Numerics Issues affecting the Numerics module labels Jul 8, 2026
@hjmjohnson hjmjohnson changed the title ENH: Deprecate the vnl_svd SVD family in favour of itk::Math::SVD ENH: Deprecate the vnl_svd SVD family, and add itk::Math::SolveSymmetric (Eigen LDLT) Jul 8, 2026
@hjmjohnson

hjmjohnson commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

Scope update (superseded): the itk::Math::SolveSymmetric / InverseSymmetric (Eigen LDLT) work has been split out to #6565. This PR is now the vnl_svd-family deprecation only (vnl_svd, vnl_svd_fixed, vnl_svd_economy, vnl_matrix_inverseitk::Math::SVD).

@hjmjohnson hjmjohnson force-pushed the enh-deprecate-vnl-svd-family branch 2 times, most recently from 6707e4c to 76036f9 Compare July 8, 2026 12:32
@hjmjohnson hjmjohnson force-pushed the enh-deprecate-vnl-svd-family branch from 76036f9 to 619512b Compare July 8, 2026 17:22
@hjmjohnson hjmjohnson changed the title ENH: Deprecate the vnl_svd SVD family, and add itk::Math::SolveSymmetric (Eigen LDLT) ENH: Deprecate the vnl_svd family for the Eigen-backed itk::Math::SVD Jul 8, 2026
@hjmjohnson hjmjohnson force-pushed the enh-deprecate-vnl-svd-family branch from 619512b to 520c2f2 Compare July 8, 2026 23:57
@hjmjohnson hjmjohnson marked this pull request as ready for review July 9, 2026 00:54
@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces in-tree VNL SVD and matrix-inverse usage with the Eigen-backed itk::Math::SVD. The main changes are:

  • New itk::Math::SVD helpers for pseudo-inverse, solve, rank, recomposition, null vectors, condition values, and determinant magnitude.
  • Fixed-size rectangular SVD support and explicit SVD template instantiations in ITKCommon.
  • Migrated transform, IO, statistics, optimizer, diffusion tensor, registration, and classifier code paths to itk::Math::SVD.
  • Deprecated vnl_svd, vnl_svd_fixed, vnl_svd_economy, vnl_matrix_inverse, and related LINPACK-backed build inputs behind legacy guards.

Confidence Score: 4/5

These issues need to be fixed before merging for future-legacy build support.

The main SVD migration is broad and mostly consistent. Eigen includes follow the ITK_EIGEN macro rule. Confidence is limited by two changed files that still include deprecated vnl_svd directly and fail under ITK_FUTURE_LEGACY_REMOVE.

Modules/Filtering/DiffusionTensorImage/include/itkDiffusionTensor3DReconstructionImageFilter.hxx; Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex ran the requested verification, but local artifact references were not uploaded.
  • T-Rex reproduced the stale deprecated SVD include in the ImageRegistration9 test and built a narrow future-legacy compile harness that failed with a VNL SVD deprecation error.
  • T-Rex verified the build produced the ITK test drivers and that all tests in the svd-validation run passed, including 23 MathSVD tests, Numerics, and itkSymmetricEigenAnalysisTest, while noting that a broader test scope caused exit code 8 unrelated to the SVD code.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
Modules/Core/Common/include/itkMathSVD.h Extends Eigen-backed SVD result helpers, fixed rectangular overloads, and explicit instantiation declarations.
Modules/Core/Common/src/itkMathSVD.cxx Adds explicit SVD template instantiation definitions to reduce consumer compile cost.
Modules/Core/Common/include/itkMatrix.h Migrates GetInverse to Math::SVD while keeping guarded transitional VNL includes.
Modules/Core/Transform/include/itkTransform.hxx Migrates inverse Jacobian pseudo-inverse computation to Math::SVD with square and rectangular handling.
Modules/Filtering/DiffusionTensorImage/include/itkDiffusionTensor3DReconstructionImageFilter.hxx Migrates pseudo-inverse to Math::SVD but leaves an unguarded deprecated vnl_svd include that breaks ITK_FUTURE_LEGACY_REMOVE builds.
Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx Migrates SVD usage but leaves a stale unguarded vnl_svd include that breaks future legacy removal builds.
Modules/ThirdParty/VNL/src/vxl/core/vnl/algo/CMakeLists.txt Build-gates deprecated VNL SVD and matrix-inverse sources and filters template instantiations under ITK_FUTURE_LEGACY_REMOVE.
Modules/ThirdParty/VNL/src/vxl/v3p/netlib/CMakeLists.txt Gates LINPACK svdc sources out of future-legacy builds after deprecating their remaining consumers.
Modules/IO/NIFTI/src/itkNiftiImageIO.cxx Migrates affine-condition and inverse calculations from VNL inverse to Math::SVD.
Modules/Numerics/Statistics/include/itkGaussianMembershipFunction.hxx Uses Math::SVD for covariance pseudo-inverse while preserving signed determinant validation.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Consumers needing SVD or inverse] --> B[itk::Math::SVD]
  B --> C{Matrix shape}
  C -->|fixed square| D[SquareSVDEigen / JacobiSVD]
  C -->|runtime square| E[DynamicSquareSVDEigen]
  C -->|rectangular| F[RectangularSVDEigen / thin U,V]
  D --> G[PseudoInverse / Solve / Rank / Recompose]
  E --> G
  F --> G
  H[vnl_svd family headers] --> I{ITK_FUTURE_LEGACY_REMOVE}
  I -->|true| J[#error / sources gated out]
  I -->|false| K[deprecated transitional availability]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
  A[Consumers needing SVD or inverse] --> B[itk::Math::SVD]
  B --> C{Matrix shape}
  C -->|fixed square| D[SquareSVDEigen / JacobiSVD]
  C -->|runtime square| E[DynamicSquareSVDEigen]
  C -->|rectangular| F[RectangularSVDEigen / thin U,V]
  D --> G[PseudoInverse / Solve / Rank / Recompose]
  E --> G
  F --> G
  H[vnl_svd family headers] --> I{ITK_FUTURE_LEGACY_REMOVE}
  I -->|true| J[#error / sources gated out]
  I -->|false| K[deprecated transitional availability]
Loading

Reviews (1): Last reviewed commit: "ENH: Deprecate the vnl_svd family and bu..." | Re-trigger Greptile

Comment thread Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx Outdated
Extend the Eigen-backed itk::Math::SVD helpers so every vnl_svd /
vnl_matrix_inverse call site in ITK has a direct replacement: pseudo-inverse,
solve, rank, recompose, null vector, and the WellCondition and
DeterminantMagnitude predicates. Route the eigenvector sign convention through
itkEigenDecompositionSignConvention so results are backend-stable.
Exercise the extended itk::Math::SVD surface (pseudo-inverse, solve, rank,
WellCondition, DeterminantMagnitude) and cross-check it against the vnl_svd
result on well- and ill-conditioned inputs.
…h::SVD

Replace direct vnl_svd, vnl_svd_fixed and vnl_matrix_inverse use across the
transforms, diffusion-tensor reconstruction, image moments, label-map filters,
membership functions, Mahalanobis metrics, the Quasi-Newton optimizer, NIfTI
and MINC IO and the classifier estimators with the Eigen-backed itk::Math::SVD
API, including itk::Matrix::GetInverse.

Where a widely included header (itkTransform, itkMatrix, the affine transforms)
previously pulled a vnl_svd* header transitively, keep that include reachable
under
  #if !defined(ITK_LEGACY_REMOVE) && !defined(ITK_FUTURE_LEGACY_REMOVE)
so downstream code that relied on the transitive include still compiles during
the deprecation window.
Add the three-state deprecation guard to vnl_svd, vnl_svd_fixed,
vnl_svd_economy, vnl_matrix_inverse and vnl_solve_qp, pointing callers at the
Eigen-backed itk::Math::SVD: silent by default, a #warning under
ITK_LEGACY_REMOVE and a hard #error under ITK_FUTURE_LEGACY_REMOVE.

Build-gate the vnl_svd family and the LINPACK svdc netlib sources out of the
ITK_FUTURE_LEGACY_REMOVE build so the dead engine no longer compiles once the
APIs are gone, and move the vnl algo tests off the deprecated spellings.
@hjmjohnson hjmjohnson force-pushed the enh-deprecate-vnl-svd-family branch from 520c2f2 to 7c01e6f Compare July 9, 2026 02:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Core Issues affecting the Core module area:Filtering Issues affecting the Filtering module area:IO Issues affecting the IO module area:Numerics Issues affecting the Numerics module area:Registration Issues affecting the Registration module area:Segmentation Issues affecting the Segmentation module area:ThirdParty Issues affecting the ThirdParty module type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant