mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Update RealQZ to reduce 2x2 diagonal block of T corresponding to non reduced diagonal block of S to positive diagonal form.
This step involve a real 2x2 SVD problem. The respective routine is thus in src/misc/ to be shared by both EVD and AVD modules.
This commit is contained in:
@@ -552,7 +552,6 @@ namespace Eigen {
|
||||
m_T.coeffRef(l,l-1) = Scalar(0.0);
|
||||
}
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
RealQZ<MatrixType>& RealQZ<MatrixType>::compute(const MatrixType& A_in, const MatrixType& B_in, bool computeQZ)
|
||||
{
|
||||
@@ -616,6 +615,37 @@ namespace Eigen {
|
||||
}
|
||||
// check if we converged before reaching iterations limit
|
||||
m_info = (local_iter<m_maxIters) ? Success : NoConvergence;
|
||||
|
||||
// For each non triangular 2x2 diagonal block of S,
|
||||
// reduce the respective 2x2 diagonal block of T to positive diagonal form using 2x2 SVD.
|
||||
// This step is not mandatory for QZ, but it does help further extraction of eigenvalues/eigenvectors,
|
||||
// and is in par with Lapack/Matlab QZ.
|
||||
if(m_info==Success)
|
||||
{
|
||||
for(Index i=0; i<dim-1; ++i)
|
||||
{
|
||||
if(m_S.coeff(i+1, i) != Scalar(0))
|
||||
{
|
||||
JacobiRotation<Scalar> j_left, j_right;
|
||||
internal::real_2x2_jacobi_svd(m_T, i, i+1, &j_left, &j_right);
|
||||
|
||||
// Apply resulting Jacobi rotations
|
||||
m_T.applyOnTheLeft(i,i+1,j_left);
|
||||
m_T.applyOnTheRight(i,i+1,j_right);
|
||||
m_S.applyOnTheLeft(i,i+1,j_left);
|
||||
m_S.applyOnTheRight(i,i+1,j_right);
|
||||
m_T(i,i+1) = Scalar(0);
|
||||
|
||||
if(m_computeQZ) {
|
||||
m_Q.applyOnTheRight(i,i+1,j_left.transpose());
|
||||
m_Z.applyOnTheLeft(i,i+1,j_right.transpose());
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
} // end compute
|
||||
|
||||
|
||||
Reference in New Issue
Block a user