HouseholderSequence.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
  5. // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
  6. //
  7. // This Source Code Form is subject to the terms of the Mozilla
  8. // Public License v. 2.0. If a copy of the MPL was not distributed
  9. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  10. #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H
  11. #define EIGEN_HOUSEHOLDER_SEQUENCE_H
  12. namespace Eigen {
  13. /** \ingroup Householder_Module
  14. * \householder_module
  15. * \class HouseholderSequence
  16. * \brief Sequence of Householder reflections acting on subspaces with decreasing size
  17. * \tparam VectorsType type of matrix containing the Householder vectors
  18. * \tparam CoeffsType type of vector containing the Householder coefficients
  19. * \tparam Side either OnTheLeft (the default) or OnTheRight
  20. *
  21. * This class represents a product sequence of Householder reflections where the first Householder reflection
  22. * acts on the whole space, the second Householder reflection leaves the one-dimensional subspace spanned by
  23. * the first unit vector invariant, the third Householder reflection leaves the two-dimensional subspace
  24. * spanned by the first two unit vectors invariant, and so on up to the last reflection which leaves all but
  25. * one dimensions invariant and acts only on the last dimension. Such sequences of Householder reflections
  26. * are used in several algorithms to zero out certain parts of a matrix. Indeed, the methods
  27. * HessenbergDecomposition::matrixQ(), Tridiagonalization::matrixQ(), HouseholderQR::householderQ(),
  28. * and ColPivHouseholderQR::householderQ() all return a %HouseholderSequence.
  29. *
  30. * More precisely, the class %HouseholderSequence represents an \f$ n \times n \f$ matrix \f$ H \f$ of the
  31. * form \f$ H = \prod_{i=0}^{n-1} H_i \f$ where the i-th Householder reflection is \f$ H_i = I - h_i v_i
  32. * v_i^* \f$. The i-th Householder coefficient \f$ h_i \f$ is a scalar and the i-th Householder vector \f$
  33. * v_i \f$ is a vector of the form
  34. * \f[
  35. * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
  36. * \f]
  37. * The last \f$ n-i \f$ entries of \f$ v_i \f$ are called the essential part of the Householder vector.
  38. *
  39. * Typical usages are listed below, where H is a HouseholderSequence:
  40. * \code
  41. * A.applyOnTheRight(H); // A = A * H
  42. * A.applyOnTheLeft(H); // A = H * A
  43. * A.applyOnTheRight(H.adjoint()); // A = A * H^*
  44. * A.applyOnTheLeft(H.adjoint()); // A = H^* * A
  45. * MatrixXd Q = H; // conversion to a dense matrix
  46. * \endcode
  47. * In addition to the adjoint, you can also apply the inverse (=adjoint), the transpose, and the conjugate operators.
  48. *
  49. * See the documentation for HouseholderSequence(const VectorsType&, const CoeffsType&) for an example.
  50. *
  51. * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
  52. */
  53. namespace internal {
  54. template<typename VectorsType, typename CoeffsType, int Side>
  55. struct traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
  56. {
  57. typedef typename VectorsType::Scalar Scalar;
  58. typedef typename VectorsType::StorageIndex StorageIndex;
  59. typedef typename VectorsType::StorageKind StorageKind;
  60. enum {
  61. RowsAtCompileTime = Side==OnTheLeft ? traits<VectorsType>::RowsAtCompileTime
  62. : traits<VectorsType>::ColsAtCompileTime,
  63. ColsAtCompileTime = RowsAtCompileTime,
  64. MaxRowsAtCompileTime = Side==OnTheLeft ? traits<VectorsType>::MaxRowsAtCompileTime
  65. : traits<VectorsType>::MaxColsAtCompileTime,
  66. MaxColsAtCompileTime = MaxRowsAtCompileTime,
  67. Flags = 0
  68. };
  69. };
  70. struct HouseholderSequenceShape {};
  71. template<typename VectorsType, typename CoeffsType, int Side>
  72. struct evaluator_traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
  73. : public evaluator_traits_base<HouseholderSequence<VectorsType,CoeffsType,Side> >
  74. {
  75. typedef HouseholderSequenceShape Shape;
  76. };
  77. template<typename VectorsType, typename CoeffsType, int Side>
  78. struct hseq_side_dependent_impl
  79. {
  80. typedef Block<const VectorsType, Dynamic, 1> EssentialVectorType;
  81. typedef HouseholderSequence<VectorsType, CoeffsType, OnTheLeft> HouseholderSequenceType;
  82. static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k)
  83. {
  84. Index start = k+1+h.m_shift;
  85. return Block<const VectorsType,Dynamic,1>(h.m_vectors, start, k, h.rows()-start, 1);
  86. }
  87. };
  88. template<typename VectorsType, typename CoeffsType>
  89. struct hseq_side_dependent_impl<VectorsType, CoeffsType, OnTheRight>
  90. {
  91. typedef Transpose<Block<const VectorsType, 1, Dynamic> > EssentialVectorType;
  92. typedef HouseholderSequence<VectorsType, CoeffsType, OnTheRight> HouseholderSequenceType;
  93. static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k)
  94. {
  95. Index start = k+1+h.m_shift;
  96. return Block<const VectorsType,1,Dynamic>(h.m_vectors, k, start, 1, h.rows()-start).transpose();
  97. }
  98. };
  99. template<typename OtherScalarType, typename MatrixType> struct matrix_type_times_scalar_type
  100. {
  101. typedef typename ScalarBinaryOpTraits<OtherScalarType, typename MatrixType::Scalar>::ReturnType
  102. ResultScalar;
  103. typedef Matrix<ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
  104. 0, MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime> Type;
  105. };
  106. } // end namespace internal
  107. template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
  108. : public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
  109. {
  110. typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType EssentialVectorType;
  111. public:
  112. enum {
  113. RowsAtCompileTime = internal::traits<HouseholderSequence>::RowsAtCompileTime,
  114. ColsAtCompileTime = internal::traits<HouseholderSequence>::ColsAtCompileTime,
  115. MaxRowsAtCompileTime = internal::traits<HouseholderSequence>::MaxRowsAtCompileTime,
  116. MaxColsAtCompileTime = internal::traits<HouseholderSequence>::MaxColsAtCompileTime
  117. };
  118. typedef typename internal::traits<HouseholderSequence>::Scalar Scalar;
  119. typedef HouseholderSequence<
  120. typename internal::conditional<NumTraits<Scalar>::IsComplex,
  121. typename internal::remove_all<typename VectorsType::ConjugateReturnType>::type,
  122. VectorsType>::type,
  123. typename internal::conditional<NumTraits<Scalar>::IsComplex,
  124. typename internal::remove_all<typename CoeffsType::ConjugateReturnType>::type,
  125. CoeffsType>::type,
  126. Side
  127. > ConjugateReturnType;
  128. /** \brief Constructor.
  129. * \param[in] v %Matrix containing the essential parts of the Householder vectors
  130. * \param[in] h Vector containing the Householder coefficients
  131. *
  132. * Constructs the Householder sequence with coefficients given by \p h and vectors given by \p v. The
  133. * i-th Householder coefficient \f$ h_i \f$ is given by \p h(i) and the essential part of the i-th
  134. * Householder vector \f$ v_i \f$ is given by \p v(k,i) with \p k > \p i (the subdiagonal part of the
  135. * i-th column). If \p v has fewer columns than rows, then the Householder sequence contains as many
  136. * Householder reflections as there are columns.
  137. *
  138. * \note The %HouseholderSequence object stores \p v and \p h by reference.
  139. *
  140. * Example: \include HouseholderSequence_HouseholderSequence.cpp
  141. * Output: \verbinclude HouseholderSequence_HouseholderSequence.out
  142. *
  143. * \sa setLength(), setShift()
  144. */
  145. HouseholderSequence(const VectorsType& v, const CoeffsType& h)
  146. : m_vectors(v), m_coeffs(h), m_trans(false), m_length(v.diagonalSize()),
  147. m_shift(0)
  148. {
  149. }
  150. /** \brief Copy constructor. */
  151. HouseholderSequence(const HouseholderSequence& other)
  152. : m_vectors(other.m_vectors),
  153. m_coeffs(other.m_coeffs),
  154. m_trans(other.m_trans),
  155. m_length(other.m_length),
  156. m_shift(other.m_shift)
  157. {
  158. }
  159. /** \brief Number of rows of transformation viewed as a matrix.
  160. * \returns Number of rows
  161. * \details This equals the dimension of the space that the transformation acts on.
  162. */
  163. Index rows() const { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); }
  164. /** \brief Number of columns of transformation viewed as a matrix.
  165. * \returns Number of columns
  166. * \details This equals the dimension of the space that the transformation acts on.
  167. */
  168. Index cols() const { return rows(); }
  169. /** \brief Essential part of a Householder vector.
  170. * \param[in] k Index of Householder reflection
  171. * \returns Vector containing non-trivial entries of k-th Householder vector
  172. *
  173. * This function returns the essential part of the Householder vector \f$ v_i \f$. This is a vector of
  174. * length \f$ n-i \f$ containing the last \f$ n-i \f$ entries of the vector
  175. * \f[
  176. * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
  177. * \f]
  178. * The index \f$ i \f$ equals \p k + shift(), corresponding to the k-th column of the matrix \p v
  179. * passed to the constructor.
  180. *
  181. * \sa setShift(), shift()
  182. */
  183. const EssentialVectorType essentialVector(Index k) const
  184. {
  185. eigen_assert(k >= 0 && k < m_length);
  186. return internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::essentialVector(*this, k);
  187. }
  188. /** \brief %Transpose of the Householder sequence. */
  189. HouseholderSequence transpose() const
  190. {
  191. return HouseholderSequence(*this).setTrans(!m_trans);
  192. }
  193. /** \brief Complex conjugate of the Householder sequence. */
  194. ConjugateReturnType conjugate() const
  195. {
  196. return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
  197. .setTrans(m_trans)
  198. .setLength(m_length)
  199. .setShift(m_shift);
  200. }
  201. /** \brief Adjoint (conjugate transpose) of the Householder sequence. */
  202. ConjugateReturnType adjoint() const
  203. {
  204. return conjugate().setTrans(!m_trans);
  205. }
  206. /** \brief Inverse of the Householder sequence (equals the adjoint). */
  207. ConjugateReturnType inverse() const { return adjoint(); }
  208. /** \internal */
  209. template<typename DestType> inline void evalTo(DestType& dst) const
  210. {
  211. Matrix<Scalar, DestType::RowsAtCompileTime, 1,
  212. AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> workspace(rows());
  213. evalTo(dst, workspace);
  214. }
  215. /** \internal */
  216. template<typename Dest, typename Workspace>
  217. void evalTo(Dest& dst, Workspace& workspace) const
  218. {
  219. workspace.resize(rows());
  220. Index vecs = m_length;
  221. if(internal::is_same_dense(dst,m_vectors))
  222. {
  223. // in-place
  224. dst.diagonal().setOnes();
  225. dst.template triangularView<StrictlyUpper>().setZero();
  226. for(Index k = vecs-1; k >= 0; --k)
  227. {
  228. Index cornerSize = rows() - k - m_shift;
  229. if(m_trans)
  230. dst.bottomRightCorner(cornerSize, cornerSize)
  231. .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data());
  232. else
  233. dst.bottomRightCorner(cornerSize, cornerSize)
  234. .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data());
  235. // clear the off diagonal vector
  236. dst.col(k).tail(rows()-k-1).setZero();
  237. }
  238. // clear the remaining columns if needed
  239. for(Index k = 0; k<cols()-vecs ; ++k)
  240. dst.col(k).tail(rows()-k-1).setZero();
  241. }
  242. else
  243. {
  244. dst.setIdentity(rows(), rows());
  245. for(Index k = vecs-1; k >= 0; --k)
  246. {
  247. Index cornerSize = rows() - k - m_shift;
  248. if(m_trans)
  249. dst.bottomRightCorner(cornerSize, cornerSize)
  250. .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
  251. else
  252. dst.bottomRightCorner(cornerSize, cornerSize)
  253. .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
  254. }
  255. }
  256. }
  257. /** \internal */
  258. template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
  259. {
  260. Matrix<Scalar,1,Dest::RowsAtCompileTime,RowMajor,1,Dest::MaxRowsAtCompileTime> workspace(dst.rows());
  261. applyThisOnTheRight(dst, workspace);
  262. }
  263. /** \internal */
  264. template<typename Dest, typename Workspace>
  265. inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const
  266. {
  267. workspace.resize(dst.rows());
  268. for(Index k = 0; k < m_length; ++k)
  269. {
  270. Index actual_k = m_trans ? m_length-k-1 : k;
  271. dst.rightCols(rows()-m_shift-actual_k)
  272. .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
  273. }
  274. }
  275. /** \internal */
  276. template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
  277. {
  278. Matrix<Scalar,1,Dest::ColsAtCompileTime,RowMajor,1,Dest::MaxColsAtCompileTime> workspace;
  279. applyThisOnTheLeft(dst, workspace);
  280. }
  281. /** \internal */
  282. template<typename Dest, typename Workspace>
  283. inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const
  284. {
  285. const Index BlockSize = 48;
  286. // if the entries are large enough, then apply the reflectors by block
  287. if(m_length>=BlockSize && dst.cols()>1)
  288. {
  289. for(Index i = 0; i < m_length; i+=BlockSize)
  290. {
  291. Index end = m_trans ? (std::min)(m_length,i+BlockSize) : m_length-i;
  292. Index k = m_trans ? i : (std::max)(Index(0),end-BlockSize);
  293. Index bs = end-k;
  294. Index start = k + m_shift;
  295. typedef Block<typename internal::remove_all<VectorsType>::type,Dynamic,Dynamic> SubVectorsType;
  296. SubVectorsType sub_vecs1(m_vectors.const_cast_derived(), Side==OnTheRight ? k : start,
  297. Side==OnTheRight ? start : k,
  298. Side==OnTheRight ? bs : m_vectors.rows()-start,
  299. Side==OnTheRight ? m_vectors.cols()-start : bs);
  300. typename internal::conditional<Side==OnTheRight, Transpose<SubVectorsType>, SubVectorsType&>::type sub_vecs(sub_vecs1);
  301. Block<Dest,Dynamic,Dynamic> sub_dst(dst,dst.rows()-rows()+m_shift+k,0, rows()-m_shift-k,dst.cols());
  302. apply_block_householder_on_the_left(sub_dst, sub_vecs, m_coeffs.segment(k, bs), !m_trans);
  303. }
  304. }
  305. else
  306. {
  307. workspace.resize(dst.cols());
  308. for(Index k = 0; k < m_length; ++k)
  309. {
  310. Index actual_k = m_trans ? k : m_length-k-1;
  311. dst.bottomRows(rows()-m_shift-actual_k)
  312. .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
  313. }
  314. }
  315. }
  316. /** \brief Computes the product of a Householder sequence with a matrix.
  317. * \param[in] other %Matrix being multiplied.
  318. * \returns Expression object representing the product.
  319. *
  320. * This function computes \f$ HM \f$ where \f$ H \f$ is the Householder sequence represented by \p *this
  321. * and \f$ M \f$ is the matrix \p other.
  322. */
  323. template<typename OtherDerived>
  324. typename internal::matrix_type_times_scalar_type<Scalar, OtherDerived>::Type operator*(const MatrixBase<OtherDerived>& other) const
  325. {
  326. typename internal::matrix_type_times_scalar_type<Scalar, OtherDerived>::Type
  327. res(other.template cast<typename internal::matrix_type_times_scalar_type<Scalar,OtherDerived>::ResultScalar>());
  328. applyThisOnTheLeft(res);
  329. return res;
  330. }
  331. template<typename _VectorsType, typename _CoeffsType, int _Side> friend struct internal::hseq_side_dependent_impl;
  332. /** \brief Sets the length of the Householder sequence.
  333. * \param [in] length New value for the length.
  334. *
  335. * By default, the length \f$ n \f$ of the Householder sequence \f$ H = H_0 H_1 \ldots H_{n-1} \f$ is set
  336. * to the number of columns of the matrix \p v passed to the constructor, or the number of rows if that
  337. * is smaller. After this function is called, the length equals \p length.
  338. *
  339. * \sa length()
  340. */
  341. HouseholderSequence& setLength(Index length)
  342. {
  343. m_length = length;
  344. return *this;
  345. }
  346. /** \brief Sets the shift of the Householder sequence.
  347. * \param [in] shift New value for the shift.
  348. *
  349. * By default, a %HouseholderSequence object represents \f$ H = H_0 H_1 \ldots H_{n-1} \f$ and the i-th
  350. * column of the matrix \p v passed to the constructor corresponds to the i-th Householder
  351. * reflection. After this function is called, the object represents \f$ H = H_{\mathrm{shift}}
  352. * H_{\mathrm{shift}+1} \ldots H_{n-1} \f$ and the i-th column of \p v corresponds to the (shift+i)-th
  353. * Householder reflection.
  354. *
  355. * \sa shift()
  356. */
  357. HouseholderSequence& setShift(Index shift)
  358. {
  359. m_shift = shift;
  360. return *this;
  361. }
  362. Index length() const { return m_length; } /**< \brief Returns the length of the Householder sequence. */
  363. Index shift() const { return m_shift; } /**< \brief Returns the shift of the Householder sequence. */
  364. /* Necessary for .adjoint() and .conjugate() */
  365. template <typename VectorsType2, typename CoeffsType2, int Side2> friend class HouseholderSequence;
  366. protected:
  367. /** \brief Sets the transpose flag.
  368. * \param [in] trans New value of the transpose flag.
  369. *
  370. * By default, the transpose flag is not set. If the transpose flag is set, then this object represents
  371. * \f$ H^T = H_{n-1}^T \ldots H_1^T H_0^T \f$ instead of \f$ H = H_0 H_1 \ldots H_{n-1} \f$.
  372. *
  373. * \sa trans()
  374. */
  375. HouseholderSequence& setTrans(bool trans)
  376. {
  377. m_trans = trans;
  378. return *this;
  379. }
  380. bool trans() const { return m_trans; } /**< \brief Returns the transpose flag. */
  381. typename VectorsType::Nested m_vectors;
  382. typename CoeffsType::Nested m_coeffs;
  383. bool m_trans;
  384. Index m_length;
  385. Index m_shift;
  386. };
  387. /** \brief Computes the product of a matrix with a Householder sequence.
  388. * \param[in] other %Matrix being multiplied.
  389. * \param[in] h %HouseholderSequence being multiplied.
  390. * \returns Expression object representing the product.
  391. *
  392. * This function computes \f$ MH \f$ where \f$ M \f$ is the matrix \p other and \f$ H \f$ is the
  393. * Householder sequence represented by \p h.
  394. */
  395. template<typename OtherDerived, typename VectorsType, typename CoeffsType, int Side>
  396. typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::Type operator*(const MatrixBase<OtherDerived>& other, const HouseholderSequence<VectorsType,CoeffsType,Side>& h)
  397. {
  398. typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::Type
  399. res(other.template cast<typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::ResultScalar>());
  400. h.applyThisOnTheRight(res);
  401. return res;
  402. }
  403. /** \ingroup Householder_Module \householder_module
  404. * \brief Convenience function for constructing a Householder sequence.
  405. * \returns A HouseholderSequence constructed from the specified arguments.
  406. */
  407. template<typename VectorsType, typename CoeffsType>
  408. HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h)
  409. {
  410. return HouseholderSequence<VectorsType,CoeffsType,OnTheLeft>(v, h);
  411. }
  412. /** \ingroup Householder_Module \householder_module
  413. * \brief Convenience function for constructing a Householder sequence.
  414. * \returns A HouseholderSequence constructed from the specified arguments.
  415. * \details This function differs from householderSequence() in that the template argument \p OnTheSide of
  416. * the constructed HouseholderSequence is set to OnTheRight, instead of the default OnTheLeft.
  417. */
  418. template<typename VectorsType, typename CoeffsType>
  419. HouseholderSequence<VectorsType,CoeffsType,OnTheRight> rightHouseholderSequence(const VectorsType& v, const CoeffsType& h)
  420. {
  421. return HouseholderSequence<VectorsType,CoeffsType,OnTheRight>(v, h);
  422. }
  423. } // end namespace Eigen
  424. #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H