diff options
author | Gael Guennebaud <g.gael@free.fr> | 2014-09-04 09:15:59 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2014-09-04 09:15:59 +0200 |
commit | 8846aa6d1b68fb0951c70bc339af93b418117ae2 (patch) | |
tree | aee42b8826ec425d91845a7e8b6f8e46ae2aef61 /Eigen/src/Householder/HouseholderSequence.h | |
parent | 80993b95d3be6dbc11b149b253f72d22f41c586e (diff) |
Optimization: enable cache-efficient application of HouseholderSequence.
Diffstat (limited to 'Eigen/src/Householder/HouseholderSequence.h')
-rw-r--r-- | Eigen/src/Householder/HouseholderSequence.h | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h index 99d3eb21f..111936f0e 100644 --- a/Eigen/src/Householder/HouseholderSequence.h +++ b/Eigen/src/Householder/HouseholderSequence.h @@ -319,12 +319,36 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS template<typename Dest, typename Workspace> inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const { - workspace.resize(dst.cols()); - for(Index k = 0; k < m_length; ++k) + const Index BlockSize = 1; + // if the entries are large enough, then apply the reflectors by block + if(m_length>BlockSize && dst.cols()>1) + { + for(Index i = 0; i < m_length; i+=BlockSize) + { + Index end = m_trans ? (std::min)(m_length,i+BlockSize) : m_length-i; + Index k = m_trans ? i : (std::max)(Index(0),end-BlockSize); + Index bs = end-k; + Index start = k + m_shift; + + typedef Block<typename internal::remove_all<VectorsType>::type,Dynamic,Dynamic> SubVectorsType; + SubVectorsType sub_vecs1(m_vectors.const_cast_derived(), Side==OnTheRight ? k : start, + Side==OnTheRight ? start : k, + Side==OnTheRight ? bs : m_vectors.rows()-start, + Side==OnTheRight ? m_vectors.cols()-start : bs); + typename internal::conditional<Side==OnTheRight, Transpose<SubVectorsType>, SubVectorsType&>::type sub_vecs(sub_vecs1); + Block<Dest,Dynamic,Dynamic> sub_dst(dst,dst.rows()-rows()+m_shift+k,0, rows()-m_shift-k,dst.cols()); + apply_block_householder_on_the_left(sub_dst, sub_vecs, m_coeffs.segment(k, bs), !m_trans); + } + } + else { - Index actual_k = m_trans ? k : m_length-k-1; - dst.bottomRows(rows()-m_shift-actual_k) - .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); + workspace.resize(dst.cols()); + for(Index k = 0; k < m_length; ++k) + { + Index actual_k = m_trans ? k : m_length-k-1; + dst.bottomRows(rows()-m_shift-actual_k) + .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); + } } } |