MUQ  0.4.3
EigenMatrixAlgebra.h
Go to the documentation of this file.
1 #ifndef EIGENMATRIXALGEBRA_H_
2 #define EIGENMATRIXALGEBRA_H_
3 
4 #include <iostream>
5 
6 #include <Eigen/Core>
7 #include <Eigen/Dense>
8 #include <unsupported/Eigen/MatrixFunctions>
9 
10 #include <boost/none.hpp>
11 #include <boost/any.hpp>
12 
13 namespace muq {
14  namespace Modeling {
16  class EigenMatrixAlgebra {
17  public:
18 
19  EigenMatrixAlgebra();
20 
21  ~EigenMatrixAlgebra();
22 
24 
28  static bool IsEigenMatrix(std::type_info const& obj_type);
29 
31 
35  static bool IsZero(boost::any const& obj);
36 
38 
42  static double Norm(boost::any const& mat);
43 
45 
50  static unsigned int Size(boost::any const& mat, int const dim);
51 
53 
60  static boost::any AccessElement(boost::any const& mat, unsigned int const i, unsigned int const j);
61 
63 
69  static boost::any Identity(std::type_info const& type, unsigned int const rows, unsigned int const cols);
70 
72 
77  static boost::any Add(boost::any const& in0, boost::any const& in1);
78 
80 
85  static boost::any Subtract(boost::any const& in0, boost::any const& in1);
86 
88 
93  static boost::any Multiply(boost::any const& in0, boost::any const& in1);
94 
96 
101  static boost::any ScalarMultiply(boost::any const& in0, boost::any const& in1);
102 
104 
109  static boost::any Zero(std::type_info const& type, unsigned int const rows, unsigned int const cols);
110 
112 
117  static boost::any ApplyInverse(boost::any const& A, boost::any const& x);
118 
120 
125  static boost::any Apply(boost::any const& A, boost::any const& x);
126 
128 
132  static boost::any SquareRoot(boost::any const& obj);
133 
135 
139  static double LogDeterminate(boost::any const& obj);
140 
141  private:
142 
144 
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());
155 
156  return (type0)(x0+x1);
157  }
158 
160 
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());
171 
172  //Eigen::VectorXd& diag = mat.diagonal();
173  mat.diagonal() += vec;
174 
175  return mat;
176 
177  //Eigen:: result = mat+vec.asDiagonal();
178  //return result;
179  }
180 
182 
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);
190  switch( dim ) {
191  case 0:
192  return eig.rows();
193  case 1:
194  return eig.cols();
195  default:
196  return eig.size();
197  }
198  }
199 
201 
205  template<typename EigenType>
206  static inline bool IsZero(boost::any const& obj) {
207  const EigenType& v = boost::any_cast<EigenType const&>(obj);
208 
209  return (v.array()==EigenType::Zero(v.rows(), v.cols()).array()).all();
210  }
211 
213 
220  template<typename mattype>
221  static inline boost::any AccessElement(boost::any const& mat, unsigned int const i, unsigned int const j) {
222  // get a constant reference to the matrix
223  const mattype& matref = boost::any_cast<const mattype&>(mat);
224 
225  // check the size
226  assert(i<matref.rows());
227  assert(j<matref.cols());
228 
229  // return ith element
230  return matref(i,j);
231  }
232 
234 
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());
245 
246  return (type0)(x0-x1);
247  }
248 
250 
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());
260 
261  return (type0)(x0*x1);
262  }
263 
265 
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);
274 
275  return (type1)(x0 * x1);
276  }
277 
279 
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());
290 
291  // solve the system
292  const vectype soln = mat.colPivHouseholderQr().solve(vec);
293 
294  return soln;
295  }
296 
298 
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();
307 
308  const vectype& vec = boost::any_cast<vectype const&>(x);
309  assert(L.rows()==vec.size());
310  assert(L.cols()==vec.size());
311 
312  // solve the system
313  vectype soln = L.template triangularView<Eigen::Lower>().solve(vec);
314  L.template triangularView<Eigen::Lower>().transpose().solveInPlace(soln);
315 
316  return soln;
317  }
318 
320 
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());
330 
331  return (vectype)(mat*vec);
332  }
333 
335 
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());
346 
347  vectype soln = mat.template triangularView<Eigen::Lower>().transpose()*vec;
348  soln = mat.template triangularView<Eigen::Lower>()*soln;
349 
350  return soln;
351  }
352 
354 
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);
361 
362  return (mattype)(mat.matrixL());
363  }
364 
366 
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();
374 
375  return 2.0*mat.diagonal().array().log().sum();
376  }
377  };
378  } // namespace Modeling
379 } // namespace muq
380 
381 #endif
int int diyfp diyfp v
Definition: json.h:15163