HouseholderSequence.h
Go to the documentation of this file.
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 
11 #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H
12 #define EIGEN_HOUSEHOLDER_SEQUENCE_H
13 
14 namespace Eigen {
15 
57 namespace internal {
58 
59 template<typename VectorsType, typename CoeffsType, int Side>
60 struct traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
61 {
62  typedef typename VectorsType::Scalar Scalar;
63  typedef typename VectorsType::Index Index;
64  typedef typename VectorsType::StorageKind StorageKind;
65  enum {
68  ColsAtCompileTime = RowsAtCompileTime,
71  MaxColsAtCompileTime = MaxRowsAtCompileTime,
72  Flags = 0
73  };
74 };
75 
76 template<typename VectorsType, typename CoeffsType, int Side>
78 {
81  typedef typename VectorsType::Index Index;
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 
89 template<typename VectorsType, typename CoeffsType>
90 struct hseq_side_dependent_impl<VectorsType, CoeffsType, OnTheRight>
91 {
94  typedef typename VectorsType::Index Index;
95  static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k)
96  {
97  Index start = k+1+h.m_shift;
98  return Block<const VectorsType,1,Dynamic>(h.m_vectors, k, start, 1, h.rows()-start).transpose();
99  }
100 };
101 
102 template<typename OtherScalarType, typename MatrixType> struct matrix_type_times_scalar_type
103 {
106  typedef Matrix<ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
107  0, MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime> Type;
108 };
109 
110 } // end namespace internal
111 
112 template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
113  : public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
114 {
116 
117  public:
118  enum {
123  };
125  typedef typename VectorsType::Index Index;
126 
127  typedef HouseholderSequence<
130  VectorsType>::type,
131  typename internal::conditional<NumTraits<Scalar>::IsComplex,
133  CoeffsType>::type,
134  Side
136 
154  HouseholderSequence(const VectorsType& v, const CoeffsType& h)
155  : m_vectors(v), m_coeffs(h), m_trans(false), m_length(v.diagonalSize()),
156  m_shift(0)
157  {
158  }
159 
162  : m_vectors(other.m_vectors),
163  m_coeffs(other.m_coeffs),
164  m_trans(other.m_trans),
165  m_length(other.m_length),
166  m_shift(other.m_shift)
167  {
168  }
169 
174  Index rows() const { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); }
175 
180  Index cols() const { return rows(); }
181 
196  const EssentialVectorType essentialVector(Index k) const
197  {
198  eigen_assert(k >= 0 && k < m_length);
200  }
201 
204  {
205  return HouseholderSequence(*this).setTrans(!m_trans);
206  }
207 
210  {
211  return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
212  .setTrans(m_trans)
213  .setLength(m_length)
214  .setShift(m_shift);
215  }
216 
219  {
220  return conjugate().setTrans(!m_trans);
221  }
222 
224  ConjugateReturnType inverse() const { return adjoint(); }
225 
227  template<typename DestType> inline void evalTo(DestType& dst) const
228  {
229  Matrix<Scalar, DestType::RowsAtCompileTime, 1,
230  AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> workspace(rows());
231  evalTo(dst, workspace);
232  }
233 
235  template<typename Dest, typename Workspace>
236  void evalTo(Dest& dst, Workspace& workspace) const
237  {
238  workspace.resize(rows());
239  Index vecs = m_length;
241  && internal::extract_data(dst) == internal::extract_data(m_vectors))
242  {
243  // in-place
244  dst.diagonal().setOnes();
245  dst.template triangularView<StrictlyUpper>().setZero();
246  for(Index k = vecs-1; k >= 0; --k)
247  {
248  Index cornerSize = rows() - k - m_shift;
249  if(m_trans)
250  dst.bottomRightCorner(cornerSize, cornerSize)
251  .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data());
252  else
253  dst.bottomRightCorner(cornerSize, cornerSize)
254  .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data());
255 
256  // clear the off diagonal vector
257  dst.col(k).tail(rows()-k-1).setZero();
258  }
259  // clear the remaining columns if needed
260  for(Index k = 0; k<cols()-vecs ; ++k)
261  dst.col(k).tail(rows()-k-1).setZero();
262  }
263  else
264  {
265  dst.setIdentity(rows(), rows());
266  for(Index k = vecs-1; k >= 0; --k)
267  {
268  Index cornerSize = rows() - k - m_shift;
269  if(m_trans)
270  dst.bottomRightCorner(cornerSize, cornerSize)
271  .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
272  else
273  dst.bottomRightCorner(cornerSize, cornerSize)
274  .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
275  }
276  }
277  }
278 
280  template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
281  {
283  applyThisOnTheRight(dst, workspace);
284  }
285 
287  template<typename Dest, typename Workspace>
288  inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const
289  {
290  workspace.resize(dst.rows());
291  for(Index k = 0; k < m_length; ++k)
292  {
293  Index actual_k = m_trans ? m_length-k-1 : k;
294  dst.rightCols(rows()-m_shift-actual_k)
295  .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
296  }
297  }
298 
300  template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
301  {
303  applyThisOnTheLeft(dst, workspace);
304  }
305 
307  template<typename Dest, typename Workspace>
308  inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const
309  {
310  workspace.resize(dst.cols());
311  for(Index k = 0; k < m_length; ++k)
312  {
313  Index actual_k = m_trans ? k : m_length-k-1;
314  dst.bottomRows(rows()-m_shift-actual_k)
315  .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
316  }
317  }
318 
326  template<typename OtherDerived>
328  {
331  applyThisOnTheLeft(res);
332  return res;
333  }
334 
335  template<typename _VectorsType, typename _CoeffsType, int _Side> friend struct internal::hseq_side_dependent_impl;
336 
347  {
348  m_length = length;
349  return *this;
350  }
351 
364  {
365  m_shift = shift;
366  return *this;
367  }
368 
369  Index length() const { return m_length; }
370  Index shift() const { return m_shift; }
372  /* Necessary for .adjoint() and .conjugate() */
373  template <typename VectorsType2, typename CoeffsType2, int Side2> friend class HouseholderSequence;
374 
375  protected:
376 
386  {
387  m_trans = trans;
388  return *this;
389  }
390 
391  bool trans() const { return m_trans; }
393  typename VectorsType::Nested m_vectors;
394  typename CoeffsType::Nested m_coeffs;
395  bool m_trans;
396  Index m_length;
397  Index m_shift;
398 };
399 
408 template<typename OtherDerived, typename VectorsType, typename CoeffsType, int Side>
410 {
413  h.applyThisOnTheRight(res);
414  return res;
415 }
416 
421 template<typename VectorsType, typename CoeffsType>
422 HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h)
423 {
425 }
426 
433 template<typename VectorsType, typename CoeffsType>
435 {
437 }
438 
439 } // end namespace Eigen
440 
441 #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
HouseholderSequence< VectorsType, CoeffsType, OnTheRight > HouseholderSequenceType
HouseholderSequence< VectorsType, CoeffsType > householderSequence(const VectorsType &v, const CoeffsType &h)
Convenience function for constructing a Householder sequence.
Index length() const
Returns the length of the Householder sequence.
HouseholderSequence< typename internal::conditional< NumTraits< Scalar >::IsComplex, typename internal::remove_all< typename VectorsType::ConjugateReturnType >::type, VectorsType >::type, typename internal::conditional< NumTraits< Scalar >::IsComplex, typename internal::remove_all< typename CoeffsType::ConjugateReturnType >::type, CoeffsType >::type, Side > ConjugateReturnType
Matrix< ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, 0, MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime > Type
HouseholderSequence & setLength(Index length)
Sets the length of the Householder sequence.
internal::hseq_side_dependent_impl< VectorsType, CoeffsType, Side >::EssentialVectorType EssentialVectorType
Index cols() const
Number of columns of transformation viewed as a matrix.
Expression of the transpose of a matrix.
Definition: Transpose.h:57
HouseholderSequence(const HouseholderSequence &other)
Copy constructor.
void applyThisOnTheLeft(Dest &dst) const
Definition: LDLT.h:16
HouseholderSequence(const VectorsType &v, const CoeffsType &h)
Constructor.
const internal::permut_matrix_product_retval< PermutationDerived, Derived, OnTheRight > operator*(const MatrixBase< Derived > &matrix, const PermutationBase< PermutationDerived > &permutation)
HouseholderSequence transpose() const
Transpose of the Householder sequence.
Block< const VectorsType, Dynamic, 1 > EssentialVectorType
void applyThisOnTheRight(Dest &dst, Workspace &workspace) const
Sequence of Householder reflections acting on subspaces with decreasing size.
void setZero()
NewType cast(const OldType &x)
static const EssentialVectorType essentialVector(const HouseholderSequenceType &h, Index k)
HouseholderSequence< VectorsType, CoeffsType, OnTheRight > rightHouseholderSequence(const VectorsType &v, const CoeffsType &h)
Convenience function for constructing a Householder sequence.
HouseholderSequence & setTrans(bool trans)
Sets the transpose flag.
internal::matrix_type_times_scalar_type< Scalar, OtherDerived >::Type operator*(const MatrixBase< OtherDerived > &other) const
Computes the product of a Householder sequence with a matrix.
ConjugateReturnType conjugate() const
Complex conjugate of the Householder sequence.
void applyThisOnTheLeft(Dest &dst, Workspace &workspace) const
void evalTo(Dest &dst, Workspace &workspace) const
Index rows() const
Number of rows of transformation viewed as a matrix.
HouseholderSequence & setShift(Index shift)
Sets the shift of the Householder sequence.
ConjugateReturnType conjugate() const
void applyThisOnTheRight(Dest &dst) const
ConjugateReturnType adjoint() const
Adjoint (conjugate transpose) of the Householder sequence.
void evalTo(DestType &dst) const
Expression of a fixed-size or dynamic-size block.
Definition: Core/Block.h:102
ConjugateReturnType inverse() const
Inverse of the Householder sequence (equals the adjoint).
const EssentialVectorType essentialVector(Index k) const
Essential part of a Householder vector.
scalar_product_traits< OtherScalarType, typename MatrixType::Scalar >::ReturnType ResultScalar
bool trans() const
Returns the transpose flag.
internal::conditional< NumTraits< Scalar >::IsComplex, const CwiseUnaryOp< internal::scalar_conjugate_op< Scalar >, const Derived >, const Derived & >::type ConjugateReturnType
Index shift() const
Returns the shift of the Householder sequence.
const T::Scalar * extract_data(const T &m)
Definition: BlasUtil.h:255
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
#define eigen_assert(x)
HouseholderSequence< VectorsType, CoeffsType, OnTheLeft > HouseholderSequenceType
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
static const EssentialVectorType essentialVector(const HouseholderSequenceType &h, Index k)
internal::traits< HouseholderSequence >::Scalar Scalar


tuw_aruco
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:40:51