ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkBridgeMathDeterminant.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkBridgeMathDeterminant_h
19#define itkBridgeMathDeterminant_h
20
21#include "itkMacro.h"
22#include "vnl/vnl_matrix.h"
23#include "vnl/vnl_matrix_fixed.h"
24
25#include "itk_eigen.h"
26#include ITK_EIGEN(Dense)
27
28namespace itk
29{
30// Forward declaration lets the Matrix overload parse under the circular include
31// with itkMatrix.h; its body instantiates only where itk::Matrix is complete.
32template <typename T, unsigned int VRows, unsigned int VColumns>
33class Matrix;
34} // namespace itk
35
36namespace itk::bridge
37{
38namespace Math
39{
40namespace detail
41{
42// Eigen chooses direct cofactor formulas for VDim <= 4 and PartialPivLU beyond;
43// the determinant is transpose-invariant, so the row-major map matches ITK
44// storage without affecting the value.
45template <unsigned int VDim, typename TReal>
46TReal
47DeterminantEigen(const TReal * inData)
48{
49 using RowMajor = Eigen::Matrix<TReal, VDim, VDim, Eigen::RowMajor>;
50 return Eigen::Map<const RowMajor>(inData).determinant();
51}
52
53template <typename TReal>
54TReal
55DynamicDeterminantEigen(const TReal * inData, unsigned int n)
56{
57 // Eigen's Dynamic-sized determinant always uses LU; dispatch small sizes to
58 // the compile-time direct formulas so runtime small matrices stay fast.
59 switch (n)
60 {
61 case 1:
62 return inData[0];
63 case 2:
64 return DeterminantEigen<2, TReal>(inData);
65 case 3:
66 return DeterminantEigen<3, TReal>(inData);
67 case 4:
68 return DeterminantEigen<4, TReal>(inData);
69 default:
70 {
71 using RowMajor = Eigen::Matrix<TReal, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
72 return Eigen::Map<const RowMajor>(inData, n, n).determinant();
73 }
74 }
75}
76} // namespace detail
77
87template <typename TReal, unsigned int VDim>
88TReal
89Determinant(const vnl_matrix_fixed<TReal, VDim, VDim> & A)
90{
91 return detail::DeterminantEigen<VDim, TReal>(A.data_block());
92}
93
95template <typename TReal, unsigned int VDim>
96TReal
101
103template <typename TReal>
104TReal
105Determinant(const vnl_matrix<TReal> & A)
106{
107 const unsigned int rows = A.rows();
108 if (rows != A.cols())
109 {
110 itkGenericExceptionMacro("itk::bridge::Math::Determinant requires a square matrix.");
111 }
112 return detail::DynamicDeterminantEigen<TReal>(A.data_block(), rows);
113}
114
119template <typename TReal, unsigned int VRows, unsigned int VColumns>
120TReal
121Determinant(const vnl_matrix_fixed<TReal, VRows, VColumns> & A)
122{
123 return Determinant(A.as_ref());
124}
125
126} // namespace Math
127} // namespace itk::bridge
128
129#endif // itkBridgeMathDeterminant_h
A templated class holding a M x N size Matrix.
Definition itkMatrix.h:71
InternalMatrixType & GetVnlMatrix()
Definition itkMatrix.h:232
TReal Determinant(const vnl_matrix_fixed< TReal, VDim, VDim > &A)
Determinant of a square matrix, backed by Eigen.
Cholesky-based linear algebra for symmetric matrices, backed by Eigen.
TReal DeterminantEigen(const TReal *inData)
TReal DynamicDeterminantEigen(const TReal *inData, unsigned int n)
Convenience wrappers over third-party numerical backends, provided as a migration aid rather than as ...
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....