ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkMathDeterminant.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 itkMathDeterminant_h
19#define itkMathDeterminant_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
35namespace Math
36{
37namespace detail
38{
39// Eigen chooses direct cofactor formulas for VDim <= 4 and PartialPivLU beyond;
40// the determinant is transpose-invariant, so the row-major map matches ITK
41// storage without affecting the value.
42template <unsigned int VDim, typename TReal>
43TReal
44DeterminantEigen(const TReal * inData)
45{
46 using RowMajor = Eigen::Matrix<TReal, VDim, VDim, Eigen::RowMajor>;
47 return Eigen::Map<const RowMajor>(inData).determinant();
48}
49
50template <typename TReal>
51TReal
52DynamicDeterminantEigen(const TReal * inData, unsigned int n)
53{
54 // Eigen's Dynamic-sized determinant always uses LU; dispatch small sizes to
55 // the compile-time direct formulas so runtime small matrices stay fast.
56 switch (n)
57 {
58 case 1:
59 return inData[0];
60 case 2:
61 return DeterminantEigen<2, TReal>(inData);
62 case 3:
63 return DeterminantEigen<3, TReal>(inData);
64 case 4:
65 return DeterminantEigen<4, TReal>(inData);
66 default:
67 {
68 using RowMajor = Eigen::Matrix<TReal, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
69 return Eigen::Map<const RowMajor>(inData, n, n).determinant();
70 }
71 }
72}
73} // namespace detail
74
84template <typename TReal, unsigned int VDim>
85TReal
86Determinant(const vnl_matrix_fixed<TReal, VDim, VDim> & A)
87{
88 return detail::DeterminantEigen<VDim, TReal>(A.data_block());
89}
90
92template <typename TReal, unsigned int VDim>
93TReal
98
100template <typename TReal>
101TReal
102Determinant(const vnl_matrix<TReal> & A)
103{
104 const unsigned int rows = A.rows();
105 if (rows != A.cols())
106 {
107 itkGenericExceptionMacro("itk::Math::Determinant requires a square matrix.");
108 }
109 return detail::DynamicDeterminantEigen<TReal>(A.data_block(), rows);
110}
111
116template <typename TReal, unsigned int VRows, unsigned int VColumns>
117TReal
118Determinant(const vnl_matrix_fixed<TReal, VRows, VColumns> & A)
119{
120 return Determinant(A.as_ref());
121}
122
123} // namespace Math
124} // namespace itk
125
126#endif // itkMathDeterminant_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 DynamicDeterminantEigen(const TReal *inData, unsigned int n)
TReal DeterminantEigen(const TReal *inData)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....