mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
Fix regression in a previous commit: some diagonal entry might not be treated by the 2x2 real preconditioner.
This commit is contained in:
parent
20f7ef2f89
commit
5ea0864c81
@ -694,16 +694,6 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
|||||||
/*** step 2. The main Jacobi SVD iteration. ***/
|
/*** step 2. The main Jacobi SVD iteration. ***/
|
||||||
RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
|
RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
|
||||||
|
|
||||||
// For a 1x1 complex matrix this boils down in cancelling the imaginary part
|
|
||||||
// This needs to be done explicitly because the "svd_precondition_2x2_block_to_be_real"
|
|
||||||
// wont't be applied as there is no 2x2 blocks!
|
|
||||||
if(NumTraits<Scalar>::IsComplex && m_diagSize==1 && abs(numext::imag(m_workMatrix.coeff(0,0)))>considerAsZero)
|
|
||||||
{
|
|
||||||
RealScalar z = abs(m_workMatrix.coeff(0,0));
|
|
||||||
if(computeU()) m_matrixU.col(0) *= m_workMatrix.coeff(0,0)/z;
|
|
||||||
m_workMatrix.coeffRef(0,0) = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
while(!finished)
|
while(!finished)
|
||||||
{
|
{
|
||||||
@ -748,11 +738,23 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
|||||||
|
|
||||||
for(Index i = 0; i < m_diagSize; ++i)
|
for(Index i = 0; i < m_diagSize; ++i)
|
||||||
{
|
{
|
||||||
// At this stage, m_workMatrix.coeff(i,i) is supposed to be real.
|
// For a complex matrix, some diagonal coefficients might note have been
|
||||||
|
// treated by svd_precondition_2x2_block_to_be_real, and the imaginary part
|
||||||
|
// of some diagonal entry might not be null.
|
||||||
|
if(NumTraits<Scalar>::IsComplex && abs(numext::imag(m_workMatrix.coeff(i,i)))>considerAsZero)
|
||||||
|
{
|
||||||
|
RealScalar a = abs(m_workMatrix.coeff(i,i));
|
||||||
|
m_singularValues.coeffRef(i) = abs(a);
|
||||||
|
if(computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// m_workMatrix.coeff(i,i) is already real, no difficulty:
|
||||||
RealScalar a = numext::real(m_workMatrix.coeff(i,i));
|
RealScalar a = numext::real(m_workMatrix.coeff(i,i));
|
||||||
m_singularValues.coeffRef(i) = abs(a);
|
m_singularValues.coeffRef(i) = abs(a);
|
||||||
if(computeU() && (a<RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
|
if(computeU() && (a<RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_singularValues *= scale;
|
m_singularValues *= scale;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user