Make FullPivHouseholderQR::solve returns the least-square solution instead of aborting if no exact solution exist

(grafted from 150c9fe5363d96c248b1ad3b19316c2d3ad5824d
)
This commit is contained in:
Gael Guennebaud 2013-08-20 11:52:48 +02:00
parent 2b50ade6ca
commit 0c5f4fd8da

View File

@ -126,11 +126,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
} }
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
* *this is the QR decomposition, if any exists. * \c *this is the QR decomposition.
* *
* \param b the right-hand-side of the equation to solve. * \param b the right-hand-side of the equation to solve.
* *
* \returns a solution. * \returns the exact or least-square solution if the rank is greater or equal to the number of columns of A,
* and an arbitrary solution otherwise.
* *
* \note The case where b is a matrix is not yet implemented. Also, this * \note The case where b is a matrix is not yet implemented. Also, this
* code is space inefficient. * code is space inefficient.
@ -516,17 +517,6 @@ struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
dec().hCoeffs().coeff(k), &temp.coeffRef(0)); dec().hCoeffs().coeff(k), &temp.coeffRef(0));
} }
if(!dec().isSurjective())
{
// is c is in the image of R ?
RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff();
RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff();
// FIXME brain dead
const RealScalar m_precision = NumTraits<Scalar>::epsilon() * (std::min)(rows,cols);
// this internal:: prefix is needed by at least gcc 3.4 and ICC
if(!internal::isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
return;
}
dec().matrixQR() dec().matrixQR()
.topLeftCorner(dec().rank(), dec().rank()) .topLeftCorner(dec().rank(), dec().rank())
.template triangularView<Upper>() .template triangularView<Upper>()