ARPACK-Eigen
DenseGenComplexShiftSolve.h
1 #ifndef DENSE_GEN_COMPLEX_SHIFT_SOLVE_H
2 #define DENSE_GEN_COMPLEX_SHIFT_SOLVE_H
3 
4 #include <Eigen/Core>
5 #include <Eigen/LU>
6 #include <stdexcept>
7 
16 template <typename Scalar>
18 {
19 private:
20  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Matrix;
21  typedef Eigen::Map<const Matrix> MapMat;
22  typedef Eigen::Map< Eigen::Matrix<Scalar, Eigen::Dynamic, 1> > MapVec;
23 
24  typedef std::complex<Scalar> Complex;
25  typedef Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> ComplexMatrix;
26  typedef Eigen::Matrix<Complex, Eigen::Dynamic, 1> ComplexVector;
27  typedef Eigen::PartialPivLU<ComplexMatrix> ComplexSolver;
28 
29  typedef const Eigen::Ref<const Matrix> ConstGenericMatrix;
30 
31  const MapMat mat;
32  const int dim_n;
33  ComplexSolver solver;
34  ComplexVector x_cache;
35 
36 public:
45  DenseGenComplexShiftSolve(ConstGenericMatrix &mat_) :
46  mat(mat_.data(), mat_.rows(), mat_.cols()),
47  dim_n(mat_.rows())
48  {
49  if(mat_.rows() != mat_.cols())
50  throw std::invalid_argument("DenseGenComplexShiftSolve: matrix must be square");
51  }
52 
56  int rows() { return dim_n; }
60  int cols() { return dim_n; }
61 
68  void set_shift(Scalar sigmar, Scalar sigmai)
69  {
70  ComplexMatrix cmat = mat.template cast<Complex>();
71  cmat.diagonal().array() -= Complex(sigmar, sigmai);
72  solver.compute(cmat);
73  x_cache.resize(dim_n);
74  x_cache.setZero();
75  }
76 
84  // y_out = Re( inv(A - sigma * I) * x_in )
85  void perform_op(Scalar *x_in, Scalar *y_out)
86  {
87  x_cache.real() = MapVec(x_in, dim_n);
88  MapVec y(y_out, dim_n);
89  y.noalias() = solver.solve(x_cache).real();
90  }
91 };
92 
93 
94 #endif // DENSE_GEN_COMPLEX_SHIFT_SOLVE_H
void perform_op(Scalar *x_in, Scalar *y_out)
DenseGenComplexShiftSolve(ConstGenericMatrix &mat_)
void set_shift(Scalar sigmar, Scalar sigmai)