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 cols() const
Number of columns of transformation viewed as a matrix.
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
ConjugateReturnType inverse() const
Inverse of the Householder sequence (equals the adjoint).
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
Expression of the transpose of a matrix.
Definition: Transpose.h:57
HouseholderSequence(const HouseholderSequence &other)
Copy constructor.
bool trans() const
Returns the transpose flag.
ConjugateReturnType adjoint() const
Adjoint (conjugate transpose) of the Householder sequence.
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: matrix.hpp:471
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)
Block< const VectorsType, Dynamic, 1 > EssentialVectorType
Sequence of Householder reflections acting on subspaces with decreasing size.
NewType cast(const OldType &x)
void applyThisOnTheLeft(Dest &dst, Workspace &workspace) const
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.
ConjugateReturnType conjugate() const
void evalTo(DestType &dst) const
void evalTo(Dest &dst, Workspace &workspace) const
Index length() const
Returns the length of the Householder sequence.
HouseholderSequence & setShift(Index shift)
Sets the shift of the Householder sequence.
#define v
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.
const EssentialVectorType essentialVector(Index k) const
Essential part of a Householder vector.
Expression of a fixed-size or dynamic-size block.
Definition: Core/Block.h:102
void applyThisOnTheRight(Dest &dst, Workspace &workspace) const
scalar_product_traits< OtherScalarType, typename MatrixType::Scalar >::ReturnType ResultScalar
internal::conditional< NumTraits< Scalar >::IsComplex, const CwiseUnaryOp< internal::scalar_conjugate_op< Scalar >, const Derived >, const Derived &>::type ConjugateReturnType
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
void applyThisOnTheRight(Dest &dst) const
#define eigen_assert(x)
Index shift() const
Returns the shift of the Householder sequence.
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)
HouseholderSequence transpose() const
Transpose of the Householder sequence.
ConjugateReturnType conjugate() const
Complex conjugate of the Householder sequence.
void applyThisOnTheLeft(Dest &dst) const
Index rows() const
Number of rows of transformation viewed as a matrix.
internal::traits< HouseholderSequence >::Scalar Scalar


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Feb 28 2022 21:31:56