18 #ifndef _MATRIXALGORITHMS_IMPL_IPP
19 #define _MATRIXALGORITHMS_IMPL_IPP
21 #include "../include/MatrixAlgorithms.hpp"
27 template <
typename MatrixT>
31 throw (std::invalid_argument(
"Input to exp_by_squaring is not a square matrix"));
35 throw (std::invalid_argument(
"exp_by_squaring: 0 is not a valid argument for exponent"));
43 return exp_by_squaring<MatrixT>(prod(M,M), n/2);
46 return prod(M,exp_by_squaring<MatrixT>(prod(M,M),(n-1)/2));
52 template <
typename MatrixT>
53 typename MatrixT::value_type
trace(
const MatrixT& M,
size_t n)
56 throw (std::invalid_argument(
"Input to exp_by_squaring is not a square matrix"));
58 std::unique_ptr<MatrixT> pB;
59 std::unique_ptr<MatrixT> pA;
63 pB = std::make_unique<MatrixT>(
exp(M,n/2));
64 pA = std::make_unique<MatrixT>(trans(*pB));
72 pB = std::make_unique<MatrixT>(
exp(M,(n-1)/2));
73 pA = std::make_unique<MatrixT>(trans(prod(*pB,M)));
75 MatrixT R = element_prod(*pA,*pB);
76 typename MatrixT::value_type tr=0;
78 for(
typename MatrixT::iterator1 it1 = R.begin1(); it1 != R.end1(); ++it1) {
79 for(
typename MatrixT::iterator2 it2 = it1.begin(); it2 != it1.end(); ++it2){
90 template <
typename MatrixT>
91 MatrixT
exp(
const MatrixT& M,
size_t n)
99 template <
typename MatrixT>
100 typename MatrixT::value_type
det(
const MatrixT& M)
103 throw (std::invalid_argument(
"Input to det is not a square matrix"));
106 using valueT =
typename MatrixT::value_type;
107 std::vector<valueT> invariants;
108 std::vector<valueT> traces;
109 size_t size = M.size1();
110 invariants.reserve(size);
111 traces.reserve(size);
112 valueT temp =
trace(M);
113 invariants.push_back(temp);
114 traces.push_back(temp);
115 for(
size_t k = 2; k <= size ; ++k) {
117 valueT outer_multiplier = (k%2==0) ? (-1/
double(k)) : (1/
double(k));
119 traces.push_back(
trace(M,k));
122 for(
size_t i =1 ;i<k;++i) {
123 sum += (i%2==0) ? invariants[i-1]*traces[k-i-1] : invariants[i-1]*traces[k-i-1]*(valueT(-1));
125 invariants.push_back((traces[k-1] + sum)*(outer_multiplier));
128 return (valueT(invariants[size-1]));
135 #endif // _MATRIXALGORITHMS_H
MatrixT::value_type trace(const MatrixT &M, size_t n)
MatrixT exp_by_squaring(const MatrixT &M, size_t n)
MatrixT exp(const MatrixT &M, size_t n)
Finds the M^n for a square matrix M.
MatrixT::value_type det(const MatrixT &M)
Finds the determinant of a square matrix.
bool isSquare(const MatrixT &M)
Convinience function to check if a matrix is square or not.