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