mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
simplifications in the ei_solve_impl system, factor out some boilerplate code
This commit is contained in:
@@ -324,54 +324,52 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename Rhs, typename Dest>
|
||||
struct ei_solve_impl<ColPivHouseholderQR<MatrixType>, Rhs, Dest>
|
||||
: ei_solve_return_value<ColPivHouseholderQR<MatrixType>, Rhs>
|
||||
template<typename _MatrixType, typename Rhs>
|
||||
struct ei_solve_impl<ColPivHouseholderQR<_MatrixType>, Rhs>
|
||||
: ei_solve_return_value<ColPivHouseholderQR<_MatrixType>, Rhs>
|
||||
{
|
||||
void evalTo(Dest& dst) const
|
||||
EIGEN_MAKE_SOLVE_HELPERS(ColPivHouseholderQR<_MatrixType>,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
const ColPivHouseholderQR<MatrixType>& dec = this->m_dec;
|
||||
const Rhs& rhs = this->m_rhs;
|
||||
const int rows = dec.rows(), cols = dec.cols();
|
||||
dst.resize(cols, rhs.cols());
|
||||
ei_assert(rhs.rows() == rows);
|
||||
const int rows = dec().rows(), cols = dec().cols();
|
||||
dst.resize(cols, rhs().cols());
|
||||
ei_assert(rhs().rows() == rows);
|
||||
|
||||
// FIXME introduce nonzeroPivots() and use it here. and more generally,
|
||||
// make the same improvements in this dec as in FullPivLU.
|
||||
if(dec.rank()==0)
|
||||
if(dec().rank()==0)
|
||||
{
|
||||
dst.setZero();
|
||||
return;
|
||||
}
|
||||
|
||||
typename Rhs::PlainMatrixType c(rhs);
|
||||
typename Rhs::PlainMatrixType c(rhs());
|
||||
|
||||
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
|
||||
c.applyOnTheLeft(makeHouseholderSequence(
|
||||
dec.matrixQR().corner(TopLeft,rows,dec.rank()),
|
||||
dec.hCoeffs().start(dec.rank())).transpose()
|
||||
dec().matrixQR().corner(TopLeft,rows,dec().rank()),
|
||||
dec().hCoeffs().start(dec().rank())).transpose()
|
||||
);
|
||||
|
||||
if(!dec.isSurjective())
|
||||
if(!dec().isSurjective())
|
||||
{
|
||||
// is c is in the image of R ?
|
||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec.rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec.rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
// FIXME brain dead
|
||||
const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols);
|
||||
if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision*4))
|
||||
return;
|
||||
}
|
||||
|
||||
dec.matrixQR()
|
||||
.corner(TopLeft, dec.rank(), dec.rank())
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, dec().rank(), dec().rank())
|
||||
.template triangularView<UpperTriangular>()
|
||||
.solveInPlace(c.corner(TopLeft, dec.rank(), c.cols()));
|
||||
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
||||
|
||||
for(int i = 0; i < dec.rank(); ++i) dst.row(dec.colsPermutation().coeff(i)) = c.row(i);
|
||||
for(int i = dec.rank(); i < cols; ++i) dst.row(dec.colsPermutation().coeff(i)).setZero();
|
||||
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
|
||||
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -332,57 +332,55 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename Rhs, typename Dest>
|
||||
struct ei_solve_impl<FullPivHouseholderQR<MatrixType>, Rhs, Dest>
|
||||
: ei_solve_return_value<FullPivHouseholderQR<MatrixType>, Rhs>
|
||||
template<typename _MatrixType, typename Rhs>
|
||||
struct ei_solve_impl<FullPivHouseholderQR<_MatrixType>, Rhs>
|
||||
: ei_solve_return_value<FullPivHouseholderQR<_MatrixType>, Rhs>
|
||||
{
|
||||
void evalTo(Dest& dst) const
|
||||
EIGEN_MAKE_SOLVE_HELPERS(FullPivHouseholderQR<_MatrixType>,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
const FullPivHouseholderQR<MatrixType>& dec = this->m_dec;
|
||||
const Rhs& rhs = this->m_rhs;
|
||||
const int rows = dec.rows(), cols = dec.cols();
|
||||
dst.resize(cols, rhs.cols());
|
||||
ei_assert(rhs.rows() == rows);
|
||||
const int rows = dec().rows(), cols = dec().cols();
|
||||
dst.resize(cols, rhs().cols());
|
||||
ei_assert(rhs().rows() == rows);
|
||||
|
||||
// FIXME introduce nonzeroPivots() and use it here. and more generally,
|
||||
// make the same improvements in this dec as in FullPivLU.
|
||||
if(dec.rank()==0)
|
||||
if(dec().rank()==0)
|
||||
{
|
||||
dst.setZero();
|
||||
return;
|
||||
}
|
||||
|
||||
typename Rhs::PlainMatrixType c(rhs);
|
||||
typename Rhs::PlainMatrixType c(rhs());
|
||||
|
||||
Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs.cols());
|
||||
for (int k = 0; k < dec.rank(); ++k)
|
||||
Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs().cols());
|
||||
for (int k = 0; k < dec().rank(); ++k)
|
||||
{
|
||||
int remainingSize = rows-k;
|
||||
c.row(k).swap(c.row(dec.rowsTranspositions().coeff(k)));
|
||||
c.corner(BottomRight, remainingSize, rhs.cols())
|
||||
.applyHouseholderOnTheLeft(dec.matrixQR().col(k).end(remainingSize-1),
|
||||
dec.hCoeffs().coeff(k), &temp.coeffRef(0));
|
||||
c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k)));
|
||||
c.corner(BottomRight, remainingSize, rhs().cols())
|
||||
.applyHouseholderOnTheLeft(dec().matrixQR().col(k).end(remainingSize-1),
|
||||
dec().hCoeffs().coeff(k), &temp.coeffRef(0));
|
||||
}
|
||||
|
||||
if(!dec.isSurjective())
|
||||
if(!dec().isSurjective())
|
||||
{
|
||||
// is c is in the image of R ?
|
||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec.rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec.rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwise().abs().maxCoeff();
|
||||
// FIXME brain dead
|
||||
const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols);
|
||||
if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
|
||||
return;
|
||||
}
|
||||
dec.matrixQR()
|
||||
.corner(TopLeft, dec.rank(), dec.rank())
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, dec().rank(), dec().rank())
|
||||
.template triangularView<UpperTriangular>()
|
||||
.solveInPlace(c.corner(TopLeft, dec.rank(), c.cols()));
|
||||
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
||||
|
||||
for(int i = 0; i < dec.rank(); ++i) dst.row(dec.colsPermutation().coeff(i)) = c.row(i);
|
||||
for(int i = dec.rank(); i < cols; ++i) dst.row(dec.colsPermutation().coeff(i)).setZero();
|
||||
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
|
||||
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -209,28 +209,28 @@ HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType&
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename Rhs, typename Dest>
|
||||
struct ei_solve_impl<HouseholderQR<MatrixType>, Rhs, Dest>
|
||||
: ei_solve_return_value<HouseholderQR<MatrixType>, Rhs>
|
||||
template<typename _MatrixType, typename Rhs>
|
||||
struct ei_solve_impl<HouseholderQR<_MatrixType>, Rhs>
|
||||
: ei_solve_return_value<HouseholderQR<_MatrixType>, Rhs>
|
||||
{
|
||||
void evalTo(Dest& dst) const
|
||||
{
|
||||
const HouseholderQR<MatrixType>& dec = this->m_dec;
|
||||
const Rhs& rhs = this->m_rhs;
|
||||
const int rows = dec.rows(), cols = dec.cols();
|
||||
dst.resize(cols, rhs.cols());
|
||||
const int rank = std::min(rows, cols);
|
||||
ei_assert(rhs.rows() == rows);
|
||||
EIGEN_MAKE_SOLVE_HELPERS(HouseholderQR<_MatrixType>,Rhs)
|
||||
|
||||
typename Rhs::PlainMatrixType c(rhs);
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
const int rows = dec().rows(), cols = dec().cols();
|
||||
dst.resize(cols, rhs().cols());
|
||||
const int rank = std::min(rows, cols);
|
||||
ei_assert(rhs().rows() == rows);
|
||||
|
||||
typename Rhs::PlainMatrixType c(rhs());
|
||||
|
||||
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
|
||||
c.applyOnTheLeft(makeHouseholderSequence(
|
||||
dec.matrixQR().corner(TopLeft,rows,rank),
|
||||
dec.hCoeffs().start(rank)).transpose()
|
||||
dec().matrixQR().corner(TopLeft,rows,rank),
|
||||
dec().hCoeffs().start(rank)).transpose()
|
||||
);
|
||||
|
||||
dec.matrixQR()
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, rank, rank)
|
||||
.template triangularView<UpperTriangular>()
|
||||
.solveInPlace(c.corner(TopLeft, rank, c.cols()));
|
||||
|
||||
Reference in New Issue
Block a user