21 #ifndef RFFGEN_LINEAR_ALGEBRA_COFACTOR_HH
22 #define RFFGEN_LINEAR_ALGEBRA_COFACTOR_HH
25 #include "dimension.hh"
26 #include "../Util/at.hh"
27 #include "../conceptCheck.hh"
28 #include "../Util/staticChecks.hh"
32 namespace LinearAlgebra
39 constexpr
int getFirst(
int row)
41 return (row==0) ? 1 : 0;
44 constexpr
int getLast(
int row)
46 return (row==2) ? 1 : 2;
49 template <
int row,
int col>
50 struct CofactorIndices
52 static constexpr
int firstRow = getFirst(row);
53 static constexpr
int lastRow = getLast(row);
54 static constexpr
int firstCol = getFirst(col);
55 static constexpr
int lastCol = getLast(col);
58 constexpr
int sign(
int row,
int col)
60 return (((row+col)%2==0) ? 1 : -1 );
63 template <
int row,
int col,
class Matrix>
64 auto computeCofactorImpl(Matrix
const&, Matrix
const& A, std::integral_constant<int,2>)
66 using Id = Detail::CofactorIndices<row,col>;
67 return sign(row,col) * at(A,Id::firstRow,Id::firstCol);
70 template <
int row,
int col,
class Matrix>
71 auto computeCofactorImpl(Matrix
const& A, Matrix
const& B, std::integral_constant<int,3>)
73 using Id = Detail::CofactorIndices<row,col>;
74 return sign(row,col) * (at(A,Id::firstRow,Id::firstCol)*at(B,Id::lastRow,Id::lastCol) - at(A,Id::firstRow,Id::lastCol)*at(B,Id::lastRow,Id::firstCol));
89 template <
int row ,
int col ,
class Matrix ,
90 class = std::enable_if_t<Checks::isConstantSizeMatrix<Matrix>()> ,
91 class = Concepts::MatrixConceptCheck<Matrix> >
94 static_assert( dimension<Matrix>() == 2 || dimension<Matrix>() == 3 ,
95 "Cofactors are currently only implemented for 2x2 and 3x3 matrices. Efficient general implementations are non-trivial and may or may not be implemented in the future." );
96 return Detail::computeCofactorImpl<row,col>(A, A, std::integral_constant<int,dimension<Matrix>()>());
106 template <
int row ,
int col ,
class Matrix ,
107 class = std::enable_if_t<!Checks::isConstantSizeMatrix<Matrix>()> ,
108 class = std::enable_if_t<Checks::isDynamicMatrix<Matrix>()> ,
112 assert( ( rows(A)==2 && cols(A)==2 ) || ( rows(A)==3 && cols(A)==3) );
113 if( rows(A) == 2 )
return Detail::computeCofactorImpl<row,col>(A, A, std::integral_constant<int,2>());
114 return Detail::computeCofactorImpl<row,col>(A, A, std::integral_constant<int,3>());
126 template <
int row ,
int col ,
class Matrix ,
127 class = std::enable_if_t<Checks::isConstantSizeMatrix<Matrix>()> ,
131 static_assert( dimension<Matrix>() == 2 || dimension<Matrix>() == 3 ,
132 "Cofactors are currently only implemented for 2x2 and 3x3 matrices. Efficient general implementations are non-trivial and may or may not be implemented in the future." );
133 return Detail::computeCofactorImpl<row,col>(A, B, std::integral_constant<int,dimension<Matrix>()>());
145 template <
int row ,
int col ,
class Matrix ,
146 class = std::enable_if_t<!Checks::isConstantSizeMatrix<Matrix>()> ,
147 class = std::enable_if_t<Checks::isDynamicMatrix<Matrix>()> ,
151 assert( ( rows(A)==2 && cols(A)==2 ) || ( rows(A)==3 && cols(A)==3) );
152 if ( rows(A)==2 )
return Detail::computeCofactorImpl<row,col>(A, B, std::integral_constant<int,2>());
153 return Detail::computeCofactorImpl<row,col>(A, B, std::integral_constant<int,3>());
158 #endif // RFFGEN_LINEAR_ALGEBRA_COFACTOR_HH
auto computeCofactor(Matrix const &A)
Compute the -cofactor of . Implemented for with .
Definition: cofactor.hh:110
Static check if the requirements of MatrixConcept are satisfied.
Definition: conceptCheck.hh:107
auto computeCofactorDirectionalDerivative(Matrix const &A, Matrix const &B)
Compute the first directional derivative in direction of the -cofactor of . Implemented for with ...
Definition: cofactor.hh:149