21 #ifndef RFFGEN_LINEAR_ALGEBRA_TRACE_HH
22 #define RFFGEN_LINEAR_ALGEBRA_TRACE_HH
24 #include <type_traits>
27 #include "dimension.hh"
28 #include "rowsAndCols.hh"
29 #include "../Util/base.hh"
30 #include "../Util/at.hh"
31 #include "../Util/exceptions.hh"
38 template <
class>
struct Chainer;
39 namespace Concepts {
template <
class>
struct SymmetricMatrixConceptCheck; }
44 namespace LinearAlgebra
57 template <
class Matrix>
58 static auto apply(
const Matrix& A)
61 for(
int i = 1; i < rows<Matrix>(); ++i) val += at(A,i,i);
68 struct ComputeTrace<2>
70 template <
class Matrix>
71 static auto apply(
const Matrix& A)
73 return at(A,0,0) + at(A,1,1) ;
79 struct ComputeTrace<3>
81 template <
class Matrix>
82 static auto apply(
const Matrix& A)
84 return at(A,0,0) + at(A,1,1) + at(A,2,2);
94 template <
class Matrix,
class = Concepts::SymmetricMatrixConceptCheck<Matrix> >
95 struct ConstantSizeTrace : Base , Chainer< ConstantSizeTrace< Matrix , Concepts::SymmetricMatrixConceptCheck<Matrix> > >
97 using Chainer< ConstantSizeTrace< Matrix , Concepts::SymmetricMatrixConceptCheck<Matrix> > >::operator ();
99 ConstantSizeTrace() =
default;
105 explicit ConstantSizeTrace(
const Matrix& A) { update(A); }
108 void update(
const Matrix& A)
110 trace = Detail::ComputeTrace<dimension<Matrix>()>::apply(A);
114 const auto& operator()() const noexcept
120 const auto& operator()(
const Matrix& A)
const
127 const auto& d0() const noexcept
134 auto d1(
const Matrix& dA)
const
136 return Detail::ComputeTrace<dimension<Matrix>()>::apply(dA);
140 std::decay_t< at_t<Matrix> >
trace = 0.;
147 template <
class Matrix>
148 struct DynamicSizeTrace : Base , Chainer< DynamicSizeTrace<Matrix> >
150 using Chainer< DynamicSizeTrace<Matrix> >::operator ();
152 DynamicSizeTrace() =
default;
158 explicit DynamicSizeTrace(
const Matrix& A) { update(A); }
161 void update(
const Matrix& A)
163 #ifdef RFFGEN_ENABLE_EXCEPTIONS
164 if( rows(A) != cols(A) )
throw NonSymmetricMatrixException(
"DynamicSizeTrace",rows(A),cols(A),__FILE__,__LINE__);
167 using Index = decltype(rows(std::declval<Matrix>()));
169 for(Index i = 0; i < rows(A); ++i)
trace += at(A,i,i);
173 const auto& operator()() const noexcept
179 const auto& operator()(
const Matrix& A)
const
186 const auto& d0() const noexcept
193 auto d1(
const Matrix& dA)
const
195 using Index = decltype(rows(std::declval<Matrix>()));
196 auto result = decltype(at(dA,0,0))(0.);
197 for(Index i = 0; i < rows(dA); ++i) result += at(dA,i,i);
202 std::decay_t< at_t<Matrix> >
trace = 0.;
212 template<
class Matrix >
213 using Trace = std::conditional_t< Checks::isConstantSizeMatrix<Matrix>() , ConstantSizeTrace<Matrix> , DynamicSizeTrace<Matrix> >;
223 template <
class Matrix>
224 static auto apply(
const Matrix& A)
231 struct TraceImpl<true>
233 template <
class Function>
234 static auto apply(
const Function& f)
236 return Trace< std::decay_t<decltype(f.d0())> >( f.d0() )( f );
252 return Detail::TraceImpl<std::is_base_of<Base,Arg>::value>::apply(arg);
257 #endif // RFFGEN_LINEAR_ALGEBRA_TRACE_HH
auto trace(const Arg &arg)
Convenient generation of Trace<Matrix>.
Definition: trace.hh:250
std::conditional_t< Checks::isConstantSizeMatrix< Matrix >(), ConstantSizeTrace< Matrix >, DynamicSizeTrace< Matrix > > Trace
Trace of a matrix (sum of diagonal elements).
Definition: trace.hh:213