Tapkee
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
generalized_eigendecomposition.hpp
Go to the documentation of this file.
1 /* This software is distributed under BSD 3-clause license (see LICENSE file).
2  *
3  * Copyright (c) 2012-2013 Sergey Lisitsyn
4  */
5 
6 #ifndef TAPKEE_GENERALIZED_EIGENDECOMPOSITION_H_
7 #define TAPKEE_GENERALIZED_EIGENDECOMPOSITION_H_
8 
9 /* Tapkee includes */
10 #ifdef TAPKEE_WITH_ARPACK
12 #endif
14 /* End of Tapkee includes */
15 
16 namespace tapkee
17 {
18 namespace tapkee_internal
19 {
20 
21 #ifdef TAPKEE_WITH_ARPACK
22 
23 template <class LMatrixType, class RMatrixType, class MatrixOperationType>
25  const RMatrixType& rhs, IndexType target_dimension, unsigned int skip)
26 {
27  timed_context context("ARPACK DSXUPD generalized eigendecomposition");
28 
30  arpack(lhs,rhs,target_dimension+skip,"SM");
31 
32  if (arpack.info() == Eigen::Success)
33  {
34  std::stringstream ss;
35  ss << "Took " << arpack.getNbrIterations() << " iterations.";
37  DenseMatrix selected_eigenvectors = (arpack.eigenvectors()).rightCols(target_dimension);
38  return EigendecompositionResult(selected_eigenvectors,arpack.eigenvalues().tail(target_dimension));
39  }
40  else
41  {
42  throw eigendecomposition_error("eigendecomposition failed");
43  }
44  return EigendecompositionResult();
45 }
46 #endif
47 
49 template <class LMatrixType, class RMatrixType, class MatrixOperationType>
51  const RMatrixType& rhs, IndexType target_dimension, unsigned int skip)
52 {
53  timed_context context("Eigen dense generalized eigendecomposition");
54 
55  DenseMatrix dense_lhs = lhs;
56  DenseMatrix dense_rhs = rhs;
57  Eigen::GeneralizedSelfAdjointEigenSolver<DenseMatrix> solver(dense_lhs, dense_rhs);
58  if (solver.info() == Eigen::Success)
59  {
60  if (MatrixOperationType::largest)
61  {
62  assert(skip==0);
63  DenseMatrix selected_eigenvectors = solver.eigenvectors().rightCols(target_dimension);
64  return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().tail(target_dimension));
65  }
66  else
67  {
68  DenseMatrix selected_eigenvectors = solver.eigenvectors().leftCols(target_dimension+skip).rightCols(target_dimension);
69  return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().segment(skip,skip+target_dimension));
70  }
71  }
72  else
73  {
74  throw eigendecomposition_error("eigendecomposition failed");
75  }
76 
77  return EigendecompositionResult();
78 }
79 
80 template <class LMatrixType, class RMatrixType, class MatrixOperationType>
82  const RMatrixType& rhs,
83  IndexType target_dimension, unsigned int skip)
84 {
85  LoggingSingleton::instance().message_info("Using the " + get_eigen_method_name(method) + " eigendecomposition method.");
86  switch (method)
87  {
88 #ifdef TAPKEE_WITH_ARPACK
89  case Arpack:
90  return generalized_eigendecomposition_impl_arpack<LMatrixType, RMatrixType, MatrixOperationType>(lhs, rhs, target_dimension, skip);
91 #endif
92  case Dense:
93  return generalized_eigendecomposition_impl_dense<LMatrixType, RMatrixType, MatrixOperationType>(lhs, rhs, target_dimension, skip);
94  case Randomized:
95  throw unsupported_method_error("Randomized method is not supported for generalized eigenproblems");
96  return EigendecompositionResult();
97  default: break;
98  }
99  return EigendecompositionResult();
100 }
101 
102 } // End of namespace tapkee_internal
103 } // End of namespace tapkee
104 
105 #endif