21 #ifndef RFFGEN_LINEAR_ALGEBRA_DETERMINANT_HH 
   22 #define RFFGEN_LINEAR_ALGEBRA_DETERMINANT_HH 
   24 #include <type_traits> 
   27 #include "dimension.hh" 
   28 #include "rowsAndCols.hh" 
   29 #include "../Util/at.hh" 
   30 #include "../Util/base.hh" 
   31 #include "../Util/chainer.hh" 
   32 #include "../Util/exceptions.hh" 
   39   namespace Concepts {  
template <
class> 
struct SymmetricMatrixConceptCheck; }
 
   44   namespace LinearAlgebra
 
   51       template < 
class Matrix >
 
   52       inline auto composeResult(Matrix 
const& A, Matrix 
const& B)
 
   54         return at(A,0,0) * at(B,1,1) + at(A,1,1) * at(B,0,0) - ( at(A,0,1) * at(B,1,0) + at(A,1,0) * at(B,0,1) );
 
   57       template < 
class Matrix >
 
   58       inline auto composeResult(Matrix 
const& dA, Matrix 
const& dB, Matrix 
const& dC)
 
   60         return at(dB,1,1) * ( at(dA,0,0) * at(dC,2,2) - at(dA,2,0) * at(dC,0,2) ) +
 
   61             at(dB,1,2) * ( at(dA,0,1) * at(dC,2,0) - at(dA,2,1) * at(dC,0,0) ) +
 
   62             at(dB,1,0) * ( at(dA,0,2) * at(dC,2,1) - at(dA,2,2) * at(dC,0,1) );
 
   65       template < 
class Matrix >
 
   66       inline auto composeSemiSymmetricResult(Matrix 
const& dA, Matrix 
const& dB, Matrix 
const& dC)
 
   68         return at(dB,1,1) * ( at(dA,0,0) * at(dC,2,2) + at(dA,2,2) * at(dC,0,0) - at(dA,2,0) * at(dC,0,2) - at(dA,0,2) * at(dC,2,0) ) +
 
   69             at(dB,1,2) * ( at(dA,0,1) * at(dC,2,0) + at(dA,2,0) * at(dC,0,1) - at(dA,2,1) * at(dC,0,0) - at(dA,0,0) * at(dC,2,1) ) +
 
   70             at(dB,1,0) * ( at(dA,0,2) * at(dC,2,1) + at(dA,2,1) * at(dC,0,2) - at(dA,2,2) * at(dC,0,1) - at(dA,0,1) * at(dC,2,2) );
 
   73       template <
class Matrix, 
int dim, 
class = Concepts::SymmetricMatrixConceptCheck<Matrix> >
 
   74       class DeterminantImpl;
 
   76       template<
class Matrix>
 
   77       class DeterminantImpl< Matrix , 2 , Concepts::SymmetricMatrixConceptCheck<Matrix> >
 
   78           : 
public Base , 
public Chainer< DeterminantImpl<Matrix,2,Concepts::SymmetricMatrixConceptCheck<Matrix> > >
 
   81         DeterminantImpl() = 
default;
 
   83         explicit DeterminantImpl(Matrix 
const& A_) { update(A_); }
 
   85         void update(Matrix 
const& A_)
 
   88           resultOfD0 = at(A,0,0) * at(A,1,1) - at(A,0,1) * at(A,1,0);
 
   97         auto d1(Matrix 
const& dA1)
 const 
   99           return composeResult(A, dA1);
 
  103         auto d2(Matrix 
const& dA1, Matrix 
const& dA2)
 const 
  105           return composeResult(dA2,dA1);
 
  110         std::decay_t< at_t<Matrix> > resultOfD0 = 0.;
 
  113       template <
class Matrix>
 
  114       class DeterminantImpl<Matrix,3,Concepts::SymmetricMatrixConceptCheck<Matrix> >
 
  115           : 
public Base , 
public Chainer< DeterminantImpl<Matrix,3,Concepts::SymmetricMatrixConceptCheck<Matrix> > >
 
  118         DeterminantImpl() = 
default;
 
  120         DeterminantImpl(Matrix 
const& A_) { update(A_); }
 
  122         void update(Matrix 
const& A_)
 
  125           resultOfD0 = composeResult(A,A,A);
 
  128         auto d0()
 const { 
return resultOfD0; }
 
  131         auto d1(Matrix 
const& dA1)
 const 
  133           return composeResult(dA1,A,A) + composeResult(A,dA1,A) + composeResult(A,A,dA1);
 
  137         auto d2(Matrix 
const& dA1, Matrix 
const& dA2)
 const 
  139           return composeSemiSymmetricResult(A,dA2,dA1) + composeSemiSymmetricResult(dA1,A,dA2) + composeSemiSymmetricResult(A,dA1,dA2);
 
  142         template <
int,
int,
int>
 
  143         auto d3(Matrix 
const& dA1, Matrix 
const& dA2, Matrix 
const& dA3)
 const 
  145           return composeSemiSymmetricResult(dA1,dA2,dA3) + composeSemiSymmetricResult(dA1,dA3,dA2) + composeSemiSymmetricResult(dA2,dA1,dA3);
 
  150         std::decay_t< at_t<Matrix> > resultOfD0 = 0.;
 
  161     template <
class Matrix>
 
  168     template <
class Matrix>
 
  170         public Base , 
public Chainer< DynamicSizeDeterminant<Matrix> >
 
  184 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
  188         if( dim == 2 ) det2D.update(A);
 
  189         if( dim == 3 ) det3D.update(A);
 
  193       auto d0()
 const { 
return ( dim==2 ) ? det2D.d0() : det3D.d0(); }
 
  197       auto d1(Matrix 
const& dA1)
 const 
  199         return ( dim==2 ) ? det2D.template d1<id>(dA1) : det3D.template d1<id>(dA1) ;
 
  203       template < 
int idx , 
int idy >
 
  204       auto d2(Matrix 
const& dA1, Matrix 
const& dA2)
 const 
  206         return ( dim==2 ) ? det2D.template d2<idx,idy>(dA1,dA2) : det3D.template d2<idx,idy>(dA1,dA2);
 
  210       template < 
int idx , 
int idy , 
int idz >
 
  211       auto d3(Matrix 
const& dA1, Matrix 
const& dA2, Matrix 
const& dA3)
 const 
  213         return ( dim==2 ) ? 0 : det3D.template d3<idx,idy,idz>(dA1,dA2,dA3);
 
  218       Detail::DeterminantImpl<Matrix,2> det2D;
 
  219       Detail::DeterminantImpl<Matrix,3> det3D;
 
  229     template < 
class Matrix >
 
  236     template<
class Matrix>
 
  246     template<
class Matrix>
 
  254 #endif // RFFGEN_LINEAR_ALGEBRA_DETERMINANT_HH 
auto det(Matrix const &A)
Convenient generation of Determinant<Matrix>(A). 
Definition: determinant.hh:237
auto d2(Matrix const &dA1, Matrix const &dA2) const 
Second (directional) derivative. 
Definition: determinant.hh:204
Exception for non-symmetric matrices if symmetric matrices are required. 
Definition: exceptions.hh:62
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
Determinant of dynamic size matrix with first three derivatives. 
Definition: determinant.hh:169
void update(Matrix const &A)
Reset point of evaluation. 
Definition: determinant.hh:182
auto d3(Matrix const &dA1, Matrix const &dA2, Matrix const &dA3) const 
Third (directional) derivative. 
Definition: determinant.hh:211
auto determinant(Matrix const &A)
Convenient computation of . 
Definition: determinant.hh:247
Detail::DeterminantImpl< Matrix, dimension< Matrix >()> ConstantSizeDeterminant
Determinant of constant size matrix with first three derivatives. 
Definition: determinant.hh:162
auto d1(Matrix const &dA1) const 
First (directional) derivative. 
Definition: determinant.hh:197
DynamicSizeDeterminant(Matrix const &A)
Constructor. 
Definition: determinant.hh:176
std::conditional_t< Checks::isConstantSizeMatrix< Matrix >(), ConstantSizeDeterminant< Matrix >, DynamicSizeDeterminant< Matrix > > Determinant
Determinant with first three derivatives. 
Definition: determinant.hh:230
auto d0() const 
Function value. 
Definition: determinant.hh:193