1 #ifndef LYAPUNOVSOLVER_H
2 #define LYAPUNOVSOLVER_H
5 #include <Eigen/Eigenvalues>
31 template<
class ScalarType,
int FixedRows=Eigen::Dynamic,
int FixedCols=Eigen::Dynamic>
36 typedef Eigen::Matrix<ScalarType, FixedRows, FixedCols>
MatrixType;
41 const int dim = A.rows();
42 assert(A.rows()==A.cols());
43 assert(C.rows()==C.cols());
44 assert(A.rows()==C.rows());
46 Eigen::ComplexSchur<MatrixType> schur;
49 auto& Q = schur.matrixU();
52 ComplexMatrixType ctilde = Q.adjoint() * C.template cast<std::complex< ScalarType >>() * Q;
57 X = (Q*
X*Q.adjoint()).eval();
67 Eigen::Ref<ComplexMatrixType> ctilde,
68 Eigen::Ref<ComplexMatrixType>
X)
70 const int size =
X.rows();
72 X(0,0) = -ctilde(0,0)/(S(0,0)+ std::conj(S(0,0)));
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);
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();
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);
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));
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)