1 #ifndef EIGENMATRIXALGEBRA_H_
2 #define EIGENMATRIXALGEBRA_H_
8 #include <unsupported/Eigen/MatrixFunctions>
10 #include <boost/none.hpp>
11 #include <boost/any.hpp>
16 class EigenMatrixAlgebra {
21 ~EigenMatrixAlgebra();
28 static bool IsEigenMatrix(std::type_info
const& obj_type);
35 static bool IsZero(boost::any
const& obj);
42 static double Norm(boost::any
const& mat);
50 static unsigned int Size(boost::any
const& mat,
int const dim);
60 static boost::any AccessElement(boost::any
const& mat,
unsigned int const i,
unsigned int const j);
69 static boost::any Identity(std::type_info
const& type,
unsigned int const rows,
unsigned int const cols);
77 static boost::any Add(boost::any
const& in0, boost::any
const& in1);
85 static boost::any Subtract(boost::any
const& in0, boost::any
const& in1);
93 static boost::any Multiply(boost::any
const& in0, boost::any
const& in1);
101 static boost::any ScalarMultiply(boost::any
const& in0, boost::any
const& in1);
109 static boost::any Zero(std::type_info
const& type,
unsigned int const rows,
unsigned int const cols);
117 static boost::any ApplyInverse(boost::any
const& A, boost::any
const& x);
125 static boost::any Apply(boost::any
const& A, boost::any
const& x);
132 static boost::any SquareRoot(boost::any
const& obj);
139 static double LogDeterminate(boost::any
const& obj);
149 template<
typename type0,
typename type1>
150 static inline boost::any Add(boost::any
const& in0, boost::any
const& in1) {
151 const type0& x0 = boost::any_cast<type0 const&>(in0);
152 const type1& x1 = boost::any_cast<type1 const&>(in1);
153 assert(x0.rows()==x1.rows());
154 assert(x0.cols()==x1.cols());
156 return (type0)(x0+x1);
165 template<
typename mattype,
typename vectype>
166 static inline boost::any AddVector(boost::any
const& in0, boost::any
const& in1) {
167 mattype mat = boost::any_cast<mattype>(in0);
168 const vectype& vec = boost::any_cast<vectype const&>(in1);
169 assert(mat.rows()==vec.size());
170 assert(mat.cols()==vec.size());
173 mat.diagonal() += vec;
187 template<
typename type>
188 static inline unsigned int Size(boost::any
const& mat,
int const dim) {
189 const type& eig = boost::any_cast<type const&>(mat);
205 template<
typename EigenType>
206 static inline bool IsZero(boost::any
const& obj) {
207 const EigenType&
v = boost::any_cast<EigenType const&>(obj);
209 return (
v.array()==EigenType::Zero(
v.rows(),
v.cols()).array()).all();
220 template<
typename mattype>
221 static inline boost::any AccessElement(boost::any
const& mat,
unsigned int const i,
unsigned int const j) {
223 const mattype& matref = boost::any_cast<const mattype&>(mat);
226 assert(i<matref.rows());
227 assert(j<matref.cols());
239 template<
typename type0,
typename type1>
240 static inline boost::any Subtract(boost::any
const& in0, boost::any
const& in1) {
241 const type0& x0 = boost::any_cast<type0 const&>(in0);
242 const type1& x1 = boost::any_cast<type1 const&>(in1);
243 assert(x0.rows()==x1.rows());
244 assert(x0.cols()==x1.cols());
246 return (type0)(x0-x1);
255 template<
typename type0,
typename type1>
256 static inline boost::any Multiply(boost::any
const& in0, boost::any
const& in1) {
257 const type0& x0 = boost::any_cast<type0 const&>(in0);
258 const type1& x1 = boost::any_cast<type1 const&>(in1);
259 assert(x0.cols()==x1.rows());
261 return (type0)(x0*x1);
270 template<
typename type0,
typename type1>
271 static inline boost::any ScalarMultiply(boost::any
const& in0, boost::any
const& in1) {
272 const type0& x0 = boost::any_cast<type0 const&>(in0);
273 const type1& x1 = boost::any_cast<type1 const&>(in1);
275 return (type1)(x0 * x1);
284 template<
typename mattype,
typename vectype>
285 inline static boost::any ApplyInverse(boost::any
const& A, boost::any
const& x) {
286 const mattype& mat = boost::any_cast<mattype const&>(A);
287 const vectype& vec = boost::any_cast<vectype const&>(x);
288 assert(mat.rows()==vec.size());
289 assert(mat.cols()==vec.size());
292 const vectype soln = mat.colPivHouseholderQr().solve(vec);
303 template<
typename mattype,
typename vectype>
304 inline static boost::any ApplyCholeskyInverse(boost::any
const& A, boost::any
const& x) {
305 const Eigen::LLT<mattype>& chol = boost::any_cast<Eigen::LLT<mattype>
const&>(A);
306 const mattype& L = chol.matrixL();
308 const vectype& vec = boost::any_cast<vectype const&>(x);
309 assert(L.rows()==vec.size());
310 assert(L.cols()==vec.size());
313 vectype soln = L.template triangularView<Eigen::Lower>().solve(vec);
314 L.template triangularView<Eigen::Lower>().transpose().solveInPlace(soln);
325 template<
typename mattype,
typename vectype>
326 inline static boost::any Apply(boost::any
const& A, boost::any
const& x) {
327 const mattype& mat = boost::any_cast<mattype const&>(A);
328 const vectype& vec = boost::any_cast<vectype const&>(x);
329 assert(mat.cols()==vec.size());
331 return (vectype)(mat*vec);
340 template<
typename mattype,
typename vectype>
341 inline static boost::any ApplyCholesky(boost::any
const& A, boost::any
const& x) {
342 const Eigen::LLT<mattype>& chol = boost::any_cast<Eigen::LLT<mattype>
const&>(A);
343 const mattype& mat = chol.matrixL();
344 const vectype& vec = boost::any_cast<vectype const&>(x);
345 assert(mat.cols()==vec.size());
347 vectype soln = mat.template triangularView<Eigen::Lower>().transpose()*vec;
348 soln = mat.template triangularView<Eigen::Lower>()*soln;
358 template<
typename mattype>
359 inline static boost::any SquareRoot(boost::any
const& obj) {
360 const Eigen::LLT<mattype>& mat = boost::any_cast<Eigen::LLT<mattype>
const&>(obj);
362 return (mattype)(mat.matrixL());
370 template<
typename mattype>
371 inline static double LogDeterminate(boost::any
const& obj) {
372 const Eigen::LLT<mattype>& chol = boost::any_cast<Eigen::LLT<mattype>
const&>(obj);
373 const mattype& mat = chol.matrixL();
375 return 2.0*mat.diagonal().array().log().sum();