RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
cofactor.hh
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the C++-library RFFGen. */
4 /* Copyright 2015 Lars Lubkoll */
5 /* */
6 /* RFFGen is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* RFFGen is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with RFFGen. If not, see <http://www.gnu.org/licenses/>. */
18 /* */
19 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20 
21 #ifndef RFFGEN_LINEAR_ALGEBRA_COFACTOR_HH
22 #define RFFGEN_LINEAR_ALGEBRA_COFACTOR_HH
23 
24 #include <cassert>
25 #include "dimension.hh"
26 #include "../Util/at.hh"
27 #include "../conceptCheck.hh"
28 #include "../Util/staticChecks.hh"
29 
30 namespace RFFGen
31 {
32  namespace LinearAlgebra
33  {
37  namespace Detail
38  {
39  constexpr int getFirst(int row)
40  {
41  return (row==0) ? 1 : 0;
42  }
43 
44  constexpr int getLast(int row)
45  {
46  return (row==2) ? 1 : 2;
47  }
48 
49  template <int row, int col>
50  struct CofactorIndices
51  {
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);
56  };
57 
58  constexpr int sign(int row, int col)
59  {
60  return (((row+col)%2==0) ? 1 : -1 );
61  }
62 
63  template <int row, int col, class Matrix>
64  auto computeCofactorImpl(Matrix const&, Matrix const& A, std::integral_constant<int,2>)
65  {
66  using Id = Detail::CofactorIndices<row,col>;
67  return sign(row,col) * at(A,Id::firstRow,Id::firstCol);
68  }
69 
70  template <int row, int col, class Matrix>
71  auto computeCofactorImpl(Matrix const& A, Matrix const& B, std::integral_constant<int,3>)
72  {
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));
75  }
76  }
89  template < int row , int col , class Matrix ,
90  class = std::enable_if_t<Checks::isConstantSizeMatrix<Matrix>()> ,
91  class = Concepts::MatrixConceptCheck<Matrix> >
92  auto computeCofactor(Matrix const& A)
93  {
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>()>());
97  }
98 
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>()> ,
109  class = Concepts::MatrixConceptCheck<Matrix> >
110  auto computeCofactor(Matrix const& A)
111  {
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  /*if( rows(A) == 3 )*/ return Detail::computeCofactorImpl<row,col>(A, A, std::integral_constant<int,3>());
115  }
116 
126  template < int row , int col , class Matrix ,
127  class = std::enable_if_t<Checks::isConstantSizeMatrix<Matrix>()> ,
129  auto computeCofactorDirectionalDerivative(Matrix const& A, Matrix const& B)
130  {
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>()>());
134  }
135 
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>()> ,
148  class = Concepts::MatrixConceptCheck<Matrix> >
149  auto computeCofactorDirectionalDerivative(Matrix const& A, Matrix const& B)
150  {
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  /*if ( rows(A)==3 )*/ return Detail::computeCofactorImpl<row,col>(A, B, std::integral_constant<int,3>());
154  }
155  }
156 }
157 
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