MUQ  0.4.3
LyapunovSolver.h
Go to the documentation of this file.
1 #ifndef LYAPUNOVSOLVER_H
2 #define LYAPUNOVSOLVER_H
3 
4 #include <Eigen/Core>
5 #include <Eigen/Eigenvalues>
6 
7 namespace muq
8 {
9 namespace Modeling
10 {
11 
31  template<class ScalarType, int FixedRows=Eigen::Dynamic, int FixedCols=Eigen::Dynamic>
33  {
34  public:
35 
36  typedef Eigen::Matrix<ScalarType, FixedRows, FixedCols> MatrixType;
37  typedef Eigen::Matrix<std::complex<ScalarType>, FixedRows, FixedCols> ComplexMatrixType;
38 
40  {
41  const int dim = A.rows();
42  assert(A.rows()==A.cols());
43  assert(C.rows()==C.cols());
44  assert(A.rows()==C.rows());
45 
46  Eigen::ComplexSchur<MatrixType> schur;
47  schur.compute(A);
48 
49  auto& Q = schur.matrixU();
50  ComplexMatrixType S = schur.matrixT();
51 
52  ComplexMatrixType ctilde = Q.adjoint() * C.template cast<std::complex< ScalarType >>() * Q;
53 
54  X.resize(dim,dim);
55  ComputeFromSchur(S, ctilde, X);
56 
57  X = (Q*X*Q.adjoint()).eval();
58 
59  return *this;
60  };
61 
62  ComplexMatrixType const& matrixX() const{return X;};
63 
64  private:
65 
66  void ComputeFromSchur(Eigen::Ref<const ComplexMatrixType> const& S,
67  Eigen::Ref<ComplexMatrixType> ctilde,
68  Eigen::Ref<ComplexMatrixType> X)
69  {
70  const int size = X.rows();
71 
72  X(0,0) = -ctilde(0,0)/(S(0,0)+ std::conj(S(0,0)));
73 
74  if(size==1)
75  return;
76 
77  ComplexMatrixType tempX = -ctilde.block(1,0,size-1,1) - X(0,0)*S.block(0,1,1,size-1).adjoint();
78  (S.block(1,1,size-1,size-1).adjoint() + S(0,0)*ComplexMatrixType::Identity(size-1,size-1)).template triangularView<Eigen::Lower>().solveInPlace(tempX);
79 
80  X.block(1,0,size-1,1) = tempX;
81  X.block(0,1,1,size-1) = X.block(1,0,size-1,1).adjoint();
82 
83  // Recursively call this function on the next block
84  ctilde.block(1,1,size-1,size-1) += S.block(0,1,1,size-1).adjoint()*X.block(0,1,1,size-1) + X.block(1,0,size-1,1)*S.block(0,1,1,size-1);
85 
86  ComputeFromSchur(S.block(1,1,size-1,size-1), ctilde.block(1,1,size-1,size-1) , X.block(1,1,size-1,size-1));
87 
88  }
89 
91 
92  };
93 }
94 }
95 
96 
97 #endif
void ComputeFromSchur(Eigen::Ref< const ComplexMatrixType > const &S, Eigen::Ref< ComplexMatrixType > ctilde, Eigen::Ref< ComplexMatrixType > X)
Eigen::Matrix< std::complex< ScalarType >, FixedRows, FixedCols > ComplexMatrixType
ComplexMatrixType const & matrixX() const
Eigen::Matrix< ScalarType, FixedRows, FixedCols > MatrixType
LyapunovSolver & compute(MatrixType const &A, MatrixType const &C)