ENH: Deprecate vnl_determinant/vnl_det for Eigen-backed itk::Math::Determinant#6568
Open
hjmjohnson wants to merge 4 commits into
Open
ENH: Deprecate vnl_determinant/vnl_det for Eigen-backed itk::Math::Determinant#6568hjmjohnson wants to merge 4 commits into
hjmjohnson wants to merge 4 commits into
Conversation
Contributor
|
| Filename | Overview |
|---|---|
| Modules/Core/Common/include/itkMathDeterminant.h | Adds Eigen-backed determinant overloads for itk::Matrix, fixed VNL, and dynamic VNL matrices; Eigen includes follow ITK macro policy. |
| Modules/Core/Common/include/itkMatrix.h | Switches inverse singular checks to the new determinant helper while preserving legacy transitive VNL include during the deprecation window. |
| Modules/Core/Common/test/itkMathDeterminantGTest.cxx | Adds determinant coverage for overload consistency, singular/non-square behavior, scaling, and VNL parity. |
| Modules/Filtering/DisplacementField/include/itkDisplacementFieldJacobianDeterminantFilter.hxx | Migrates physical Jacobian determinant computation to itk::Math::Determinant. |
| Modules/ThirdParty/VNL/src/vxl/core/vnl/algo/vnl_determinant.h | Adds ITK deprecation guards for vnl_determinant while preserving upstream VXL use when itkConfigure.h is unavailable. |
| Modules/ThirdParty/VNL/src/vxl/core/vnl/vnl_det.h | Adds matching ITK deprecation guards for vnl_det. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller as ITK call site
participant Math as itk::Math::Determinant
participant Dispatch as Fixed/dynamic dispatch
participant Eigen as Eigen determinant engine
participant Legacy as vnl_determinant/vnl_det headers
Caller->>Math: pass itk::Matrix or vnl_matrix(_fixed)
Math->>Dispatch: validate square dynamic inputs
alt "fixed size or n <= 4"
Dispatch->>Eigen: Map row-major data to fixed-size matrix
else "dynamic n > 4"
Dispatch->>Eigen: Map row-major data to dynamic matrix
end
Eigen-->>Caller: determinant value
Caller-->>Legacy: no migrated in-tree calls
Legacy-->>Caller: warn/error only under legacy guard macros
%%{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"}}}%%
sequenceDiagram
participant Caller as ITK call site
participant Math as itk::Math::Determinant
participant Dispatch as Fixed/dynamic dispatch
participant Eigen as Eigen determinant engine
participant Legacy as vnl_determinant/vnl_det headers
Caller->>Math: pass itk::Matrix or vnl_matrix(_fixed)
Math->>Dispatch: validate square dynamic inputs
alt "fixed size or n <= 4"
Dispatch->>Eigen: Map row-major data to fixed-size matrix
else "dynamic n > 4"
Dispatch->>Eigen: Map row-major data to dynamic matrix
end
Eigen-->>Caller: determinant value
Caller-->>Legacy: no migrated in-tree calls
Legacy-->>Caller: warn/error only under legacy guard macros
Reviews (1): Last reviewed commit: "ENH: Deprecate vnl_determinant and vnl_d..." | Re-trigger Greptile
dzenanz
reviewed
Jul 9, 2026
dzenanz
left a comment
Member
There was a problem hiding this comment.
I haven't taken a look at the tests. The rest looks good on a glance.
788161a to
b67f657
Compare
Eigen-backed replacement for vnl_determinant/vnl_det. Overloads accept an itk::Matrix, a vnl_matrix_fixed, or a runtime vnl_matrix over a zero-copy Eigen::Map; no Eigen type appears in the interface. Fixed sizes and runtime sizes <= 4x4 use direct cofactor formulas; larger runtime sizes use PartialPivLU. The runtime engine dispatches small n to the compile-time direct formula so small runtime matrices stay fast (Eigen's Dynamic-sized determinant otherwise always uses LU). A forward declaration of itk::Matrix keeps the header free of a cycle with itkMatrix.h; the Matrix overload instantiates where itk::Matrix is complete. Part of the VNL->Eigen numerics migration (InsightSoftwareConsortium#6403, InsightSoftwareConsortium#6230).
Scavenges the vnl test_determinant coverage into a GoogleTest exercising the itk::Math::Determinant API: 2x2/3x3 closed-form references, overload consistency, identity/diagonal, singular, large triangular, the c^n scaling law, float, a non-square throw, and equivalence with vnl_det/vnl_determinant on well- and ill-conditioned inputs. Marked ITK_LEGACY_TEST so it keeps compiling once the vnl spellings warn under ITK_LEGACY_REMOVE.
Switches every in-tree determinant call site off vnl_determinant/vnl_det to the Eigen-backed itk::Math::Determinant: transforms, mesh cells, image base/extract/series writer, displacement-field Jacobian, quasi-Newton, membership/Mahalanobis statistics, label geometry, FDF IO, and video stream. Removes now-unused vnl determinant includes. itkMatrix.h and itkImageBase keep the vnl header reachable under a silent-window guard so downstream code that relied on the transitive include still compiles during the deprecation window.
Adds the itkConfigure-gated three-state deprecation guard to both vnl determinant headers, pointing at itk::Math::Determinant: silent by default, a #warning under ITK_LEGACY_REMOVE, and a hard #error under ITK_FUTURE_LEGACY_REMOVE. The guard is inert for the upstream VXL build (fires only for an ITK consumer) and honors ITK_LEGACY_TEST. Part of the VNL->Eigen numerics migration (InsightSoftwareConsortium#6403, InsightSoftwareConsortium#6230).
b67f657 to
7ad449c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deprecates
vnl_determinantandvnl_detin favor of the Eigen-backeditk::Math::Determinant, migrates every in-tree consumer, and gates both vnl spellings behind the standard three-state deprecation guard. Part of the VNL→Eigen numerics migration (#6403, #6230); same shape as thevnl_matrix_exp(#6454) andvnl_fft(#6441) precedents.Only Mac clang was exercised locally; Windows/MSVC (the
#pragma messageguard branch) and the Linux GCC configs rely on CI.Commit structure (4 thematic commits)
itk::Math::Determinant— Eigen-backed, no-copyEigen::Map, overloads foritk::Matrix/vnl_matrix_fixed/vnl_matrix; runtime engine dispatches n≤4 to the compile-time direct formula so small runtime matrices stay fast. A forward declaration ofitk::Matrixbreaks the include cycle withitkMatrix.h.c^nscaling, float, non-square throw, vnl equivalence on well- and ill-conditioned inputs).vnl_determinantandvnl_det(transforms, mesh cells, image base/extract/series-writer, displacement-field Jacobian, quasi-Newton, membership/Mahalanobis, label geometry, FDF IO, video stream).itkMatrix.h/itkImageBasekeep the vnl header reachable under#if !defined(ITK_LEGACY_REMOVE) && !defined(ITK_FUTURE_LEGACY_REMOVE)so downstream code relying on the transitive include still compiles during the deprecation window.vnl_determinant.handvnl_det.hwith the three-state guard (silent default /#warningunderITK_LEGACY_REMOVE/#errorunderITK_FUTURE_LEGACY_REMOVE), inert for the upstream VXL build and honoringITK_LEGACY_TEST.Benchmark gate — accuracy + speed
Eigen ties-or-wins both axes across the meaningful range; the
vnl_*engine is therefore left in place (not auto-routed to Eigen) — consumers get Eigen via the new API, the vnl spellings keep their own engine behind the deprecation guard.itk::Matrix)Key design point: Eigen's
Dynamic-sized.determinant()always uses LU, so a naive runtime path was ~30× slower than vnl for n=3/4; dispatching small n to the compile-time formula (as vnl does internally) keeps the one hot consumer — per-pixel 3×3DisplacementFieldJacobianDeterminantFilter— at parity instead of a 30× regression.macOS arm64, clang
-O3, single-threaded, median of 200 reps, accuracy vs long-double LU reference.