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