aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Householder/HouseholderSequence.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2010-06-10 16:39:46 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2010-06-10 16:39:46 +0200
commit469382407ca5d730f23788c593e71e91d24e9b89 (patch)
tree7c5423e63a9c4b01a25b0edded15cae4d7efb88c /Eigen/src/Householder/HouseholderSequence.h
parentd2d7465bcfcfc60e2b7350f4e4ae44d809182d39 (diff)
* Make HouseholderSequence::evalTo works in place
* Clean a bit the Triadiagonalization making sure it the inplace function really works inplace ;), and that only the lower triangular part of the matrix is referenced. * Remove the Tridiagonalization member object of SelfAdjointEigenSolver exploiting the in place capability of HouseholdeSequence. * Update unit test to check SelfAdjointEigenSolver only consider the lower triangular part.
Diffstat (limited to 'Eigen/src/Householder/HouseholderSequence.h')
-rw-r--r--Eigen/src/Householder/HouseholderSequence.h47
1 files changed, 37 insertions, 10 deletions
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index 835fe6a1c..b33fe5eeb 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -160,18 +160,45 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
template<typename DestType> void evalTo(DestType& dst) const
{
Index vecs = m_actualVectors;
- dst.setIdentity(rows(), rows());
+ // FIXME find a way to pass this temporary if the user want to
Matrix<Scalar, DestType::RowsAtCompileTime, 1,
- AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> temp(rows());
- for(Index k = vecs-1; k >= 0; --k)
+ AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> temp(rows());
+ if( ei_is_same_type<typename ei_cleantype<VectorsType>::type,DestType>::ret
+ && ei_extract_data(dst) == ei_extract_data(m_vectors))
{
- Index cornerSize = rows() - k - m_shift;
- if(m_trans)
- dst.bottomRightCorner(cornerSize, cornerSize)
- .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
- else
- dst.bottomRightCorner(cornerSize, cornerSize)
- .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
+ // in-place
+ dst.diagonal().setOnes();
+ dst.template triangularView<StrictlyUpper>().setZero();
+ for(Index k = vecs-1; k >= 0; --k)
+ {
+ Index cornerSize = rows() - k - m_shift;
+ if(m_trans)
+ dst.bottomRightCorner(cornerSize, cornerSize)
+ .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
+ else
+ dst.bottomRightCorner(cornerSize, cornerSize)
+ .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
+
+ // clear the off diagonal vector
+ dst.col(k).tail(rows()-k-1).setZero();
+ }
+ // clear the remaining columns if needed
+ for(Index k = 0; k<cols()-vecs ; ++k)
+ dst.col(k).tail(rows()-k-1).setZero();
+ }
+ else
+ {
+ dst.setIdentity(rows(), rows());
+ for(Index k = vecs-1; k >= 0; --k)
+ {
+ Index cornerSize = rows() - k - m_shift;
+ if(m_trans)
+ dst.bottomRightCorner(cornerSize, cornerSize)
+ .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
+ else
+ dst.bottomRightCorner(cornerSize, cornerSize)
+ .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
+ }
}
}