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 // IWYU pragma: private
15 #include "./InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
60 namespace internal {
61 
62 template <typename VectorsType, typename CoeffsType, int Side>
63 struct traits<HouseholderSequence<VectorsType, CoeffsType, Side> > {
64  typedef typename VectorsType::Scalar Scalar;
65  typedef typename VectorsType::StorageIndex StorageIndex;
66  typedef typename VectorsType::StorageKind StorageKind;
67  enum {
68  RowsAtCompileTime =
70  ColsAtCompileTime = RowsAtCompileTime,
71  MaxRowsAtCompileTime =
73  MaxColsAtCompileTime = MaxRowsAtCompileTime,
74  Flags = 0
75  };
76 };
77 
79 
80 template <typename VectorsType, typename CoeffsType, int Side>
81 struct evaluator_traits<HouseholderSequence<VectorsType, CoeffsType, Side> >
82  : public evaluator_traits_base<HouseholderSequence<VectorsType, CoeffsType, Side> > {
84 };
85 
86 template <typename VectorsType, typename CoeffsType, int Side>
91  Index start = k + 1 + h.m_shift;
93  }
94 };
95 
96 template <typename VectorsType, typename CoeffsType>
97 struct hseq_side_dependent_impl<VectorsType, CoeffsType, OnTheRight> {
101  Index start = k + 1 + h.m_shift;
102  return Block<const VectorsType, 1, Dynamic>(h.m_vectors, k, start, 1, h.rows() - start).transpose();
103  }
104 };
105 
106 template <typename OtherScalarType, typename MatrixType>
109  typedef Matrix<ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, 0,
110  MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime>
112 };
113 
114 } // end namespace internal
115 
116 template <typename VectorsType, typename CoeffsType, int Side>
117 class HouseholderSequence : public EigenBase<HouseholderSequence<VectorsType, CoeffsType, Side> > {
120 
121  public:
122  enum {
127  };
129 
130  typedef HouseholderSequence<
134  CoeffsType>,
135  Side>
137 
138  typedef HouseholderSequence<
139  VectorsType,
141  CoeffsType>,
142  Side>
144 
145  typedef HouseholderSequence<
148  CoeffsType, Side>
150 
151  typedef HouseholderSequence<std::add_const_t<VectorsType>, std::add_const_t<CoeffsType>, Side>
153 
171  EIGEN_DEVICE_FUNC HouseholderSequence(const VectorsType& v, const CoeffsType& h)
172  : m_vectors(v), m_coeffs(h), m_reverse(false), m_length(v.diagonalSize()), m_shift(0) {}
173 
176  : m_vectors(other.m_vectors),
177  m_coeffs(other.m_coeffs),
178  m_reverse(other.m_reverse),
179  m_length(other.m_length),
180  m_shift(other.m_shift) {}
181 
187  return Side == OnTheLeft ? m_vectors.rows() : m_vectors.cols();
188  }
189 
195 
211  eigen_assert(k >= 0 && k < m_length);
213  }
214 
217  return TransposeReturnType(m_vectors.conjugate(), m_coeffs)
218  .setReverseFlag(!m_reverse)
219  .setLength(m_length)
220  .setShift(m_shift);
221  }
222 
225  return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
226  .setReverseFlag(m_reverse)
227  .setLength(m_length)
228  .setShift(m_shift);
229  }
230 
234  template <bool Cond>
235  EIGEN_DEVICE_FUNC inline std::conditional_t<Cond, ConjugateReturnType, ConstHouseholderSequence> conjugateIf() const {
236  typedef std::conditional_t<Cond, ConjugateReturnType, ConstHouseholderSequence> ReturnType;
237  return ReturnType(m_vectors.template conjugateIf<Cond>(), m_coeffs.template conjugateIf<Cond>());
238  }
239 
242  return AdjointReturnType(m_vectors, m_coeffs.conjugate())
243  .setReverseFlag(!m_reverse)
244  .setLength(m_length)
245  .setShift(m_shift);
246  }
247 
249  AdjointReturnType inverse() const { return adjoint(); }
250 
252  template <typename DestType>
253  inline EIGEN_DEVICE_FUNC void evalTo(DestType& dst) const {
255  rows());
256  evalTo(dst, workspace);
257  }
258 
260  template <typename Dest, typename Workspace>
261  EIGEN_DEVICE_FUNC void evalTo(Dest& dst, Workspace& workspace) const {
262  workspace.resize(rows());
263  Index vecs = m_length;
265  // in-place
266  dst.diagonal().setOnes();
267  dst.template triangularView<StrictlyUpper>().setZero();
268  for (Index k = vecs - 1; k >= 0; --k) {
269  Index cornerSize = rows() - k - m_shift;
270  if (m_reverse)
271  dst.bottomRightCorner(cornerSize, cornerSize)
272  .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data());
273  else
274  dst.bottomRightCorner(cornerSize, cornerSize)
275  .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data());
276 
277  // clear the off diagonal vector
278  dst.col(k).tail(rows() - k - 1).setZero();
279  }
280  // clear the remaining columns if needed
281  for (Index k = 0; k < cols() - vecs; ++k) dst.col(k).tail(rows() - k - 1).setZero();
282  } else if (m_length > BlockSize) {
283  dst.setIdentity(rows(), rows());
284  if (m_reverse)
285  applyThisOnTheLeft(dst, workspace, true);
286  else
287  applyThisOnTheLeft(dst, workspace, true);
288  } else {
289  dst.setIdentity(rows(), rows());
290  for (Index k = vecs - 1; k >= 0; --k) {
291  Index cornerSize = rows() - k - m_shift;
292  if (m_reverse)
293  dst.bottomRightCorner(cornerSize, cornerSize)
294  .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data());
295  else
296  dst.bottomRightCorner(cornerSize, cornerSize)
297  .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data());
298  }
299  }
300  }
301 
303  template <typename Dest>
304  inline void applyThisOnTheRight(Dest& dst) const {
306  applyThisOnTheRight(dst, workspace);
307  }
308 
310  template <typename Dest, typename Workspace>
311  inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const {
312  workspace.resize(dst.rows());
313  for (Index k = 0; k < m_length; ++k) {
314  Index actual_k = m_reverse ? m_length - k - 1 : k;
315  dst.rightCols(rows() - m_shift - actual_k)
316  .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
317  }
318  }
319 
321  template <typename Dest>
322  inline void applyThisOnTheLeft(Dest& dst, bool inputIsIdentity = false) const {
324  applyThisOnTheLeft(dst, workspace, inputIsIdentity);
325  }
326 
328  template <typename Dest, typename Workspace>
329  inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace, bool inputIsIdentity = false) const {
330  if (inputIsIdentity && m_reverse) inputIsIdentity = false;
331  // if the entries are large enough, then apply the reflectors by block
332  if (m_length >= BlockSize && dst.cols() > 1) {
333  // Make sure we have at least 2 useful blocks, otherwise it is point-less:
334  Index blockSize = m_length < Index(2 * BlockSize) ? (m_length + 1) / 2 : Index(BlockSize);
335  for (Index i = 0; i < m_length; i += blockSize) {
336  Index end = m_reverse ? (std::min)(m_length, i + blockSize) : m_length - i;
337  Index k = m_reverse ? i : (std::max)(Index(0), end - blockSize);
338  Index bs = end - k;
339  Index start = k + m_shift;
340 
342  SubVectorsType sub_vecs1(m_vectors.const_cast_derived(), Side == OnTheRight ? k : start,
343  Side == OnTheRight ? start : k, Side == OnTheRight ? bs : m_vectors.rows() - start,
344  Side == OnTheRight ? m_vectors.cols() - start : bs);
345  std::conditional_t<Side == OnTheRight, Transpose<SubVectorsType>, SubVectorsType&> sub_vecs(sub_vecs1);
346 
347  Index dstRows = rows() - m_shift - k;
348 
349  if (inputIsIdentity) {
350  Block<Dest, Dynamic, Dynamic> sub_dst = dst.bottomRightCorner(dstRows, dstRows);
351  apply_block_householder_on_the_left(sub_dst, sub_vecs, m_coeffs.segment(k, bs), !m_reverse);
352  } else {
353  auto sub_dst = dst.bottomRows(dstRows);
354  apply_block_householder_on_the_left(sub_dst, sub_vecs, m_coeffs.segment(k, bs), !m_reverse);
355  }
356  }
357  } else {
358  workspace.resize(dst.cols());
359  for (Index k = 0; k < m_length; ++k) {
360  Index actual_k = m_reverse ? k : m_length - k - 1;
361  Index dstRows = rows() - m_shift - actual_k;
362 
363  if (inputIsIdentity) {
364  Block<Dest, Dynamic, Dynamic> sub_dst = dst.bottomRightCorner(dstRows, dstRows);
365  sub_dst.applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
366  } else {
367  auto sub_dst = dst.bottomRows(dstRows);
368  sub_dst.applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
369  }
370  }
371  }
372  }
373 
381  template <typename OtherDerived>
383  const MatrixBase<OtherDerived>& other) const {
387  return res;
388  }
389 
390  template <typename VectorsType_, typename CoeffsType_, int Side_>
392 
403  m_length = length;
404  return *this;
405  }
406 
419  m_shift = shift;
420  return *this;
421  }
422 
424  return m_length;
425  }
428  return m_shift;
429  }
431  /* Necessary for .adjoint() and .conjugate() */
432  template <typename VectorsType2, typename CoeffsType2, int Side2>
433  friend class HouseholderSequence;
434 
435  protected:
447  m_reverse = reverse;
448  return *this;
449  }
450 
451  bool reverseFlag() const { return m_reverse; }
453  typename VectorsType::Nested m_vectors;
454  typename CoeffsType::Nested m_coeffs;
455  bool m_reverse;
458  enum { BlockSize = 48 };
459 };
460 
469 template <typename OtherDerived, typename VectorsType, typename CoeffsType, int Side>
473  other.template cast<typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,
474  OtherDerived>::ResultScalar>());
476  return res;
477 }
478 
483 template <typename VectorsType, typename CoeffsType>
484 HouseholderSequence<VectorsType, CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h) {
486 }
487 
494 template <typename VectorsType, typename CoeffsType>
496  const CoeffsType& h) {
498 }
499 
500 } // end namespace Eigen
501 
502 #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define EIGEN_NOEXCEPT
Definition: Macros.h:1267
#define EIGEN_CONSTEXPR
Definition: Macros.h:758
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
Side
Definition: Side.h:9
void reverse(const MatrixType &m)
Definition: array_reverse.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:110
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition: HouseholderSequence.h:117
AdjointReturnType inverse() const
Inverse of the Householder sequence (equals the adjoint).
Definition: HouseholderSequence.h:249
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Number of columns of transformation viewed as a matrix.
Definition: HouseholderSequence.h:194
EIGEN_DEVICE_FUNC HouseholderSequence(const VectorsType &v, const CoeffsType &h)
Constructor.
Definition: HouseholderSequence.h:171
Index m_length
Definition: HouseholderSequence.h:456
EIGEN_DEVICE_FUNC HouseholderSequence(const HouseholderSequence &other)
Copy constructor.
Definition: HouseholderSequence.h:175
internal::traits< HouseholderSequence >::Scalar Scalar
Definition: HouseholderSequence.h:128
@ ColsAtCompileTime
Definition: HouseholderSequence.h:124
@ MaxColsAtCompileTime
Definition: HouseholderSequence.h:126
@ MaxRowsAtCompileTime
Definition: HouseholderSequence.h:125
@ RowsAtCompileTime
Definition: HouseholderSequence.h:123
bool m_reverse
Definition: HouseholderSequence.h:455
HouseholderSequence< VectorsType, std::conditional_t< NumTraits< Scalar >::IsComplex, internal::remove_all_t< typename CoeffsType::ConjugateReturnType >, CoeffsType >, Side > AdjointReturnType
Definition: HouseholderSequence.h:143
CoeffsType::Nested m_coeffs
Definition: HouseholderSequence.h:454
EIGEN_DEVICE_FUNC HouseholderSequence & setLength(Index length)
Sets the length of the Householder sequence.
Definition: HouseholderSequence.h:402
HouseholderSequence< std::add_const_t< VectorsType >, std::add_const_t< CoeffsType >, Side > ConstHouseholderSequence
Definition: HouseholderSequence.h:152
void applyThisOnTheRight(Dest &dst) const
Definition: HouseholderSequence.h:304
EIGEN_DEVICE_FUNC HouseholderSequence & setShift(Index shift)
Sets the shift of the Householder sequence.
Definition: HouseholderSequence.h:418
EIGEN_DEVICE_FUNC const EssentialVectorType essentialVector(Index k) const
Essential part of a Householder vector.
Definition: HouseholderSequence.h:210
VectorsType::Nested m_vectors
Definition: HouseholderSequence.h:453
EIGEN_DEVICE_FUNC std::conditional_t< Cond, ConjugateReturnType, ConstHouseholderSequence > conjugateIf() const
Definition: HouseholderSequence.h:235
internal::hseq_side_dependent_impl< VectorsType, CoeffsType, Side >::EssentialVectorType EssentialVectorType
Definition: HouseholderSequence.h:119
EIGEN_DEVICE_FUNC void evalTo(Dest &dst, Workspace &workspace) const
Definition: HouseholderSequence.h:261
EIGEN_DEVICE_FUNC Index shift() const
Returns the shift of the Householder sequence.
Definition: HouseholderSequence.h:427
EIGEN_DEVICE_FUNC void evalTo(DestType &dst) const
Definition: HouseholderSequence.h:253
@ BlockSize
Definition: HouseholderSequence.h:458
HouseholderSequence< std::conditional_t< NumTraits< Scalar >::IsComplex, internal::remove_all_t< typename VectorsType::ConjugateReturnType >, VectorsType >, CoeffsType, Side > TransposeReturnType
Definition: HouseholderSequence.h:149
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.
Definition: HouseholderSequence.h:382
EIGEN_DEVICE_FUNC Index length() const
Returns the length of the Householder sequence.
Definition: HouseholderSequence.h:423
Index m_shift
Definition: HouseholderSequence.h:457
ConjugateReturnType conjugate() const
Complex conjugate of the Householder sequence.
Definition: HouseholderSequence.h:224
void applyThisOnTheLeft(Dest &dst, bool inputIsIdentity=false) const
Definition: HouseholderSequence.h:322
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Number of rows of transformation viewed as a matrix.
Definition: HouseholderSequence.h:186
bool reverseFlag() const
Returns the reverse flag.
Definition: HouseholderSequence.h:451
HouseholderSequence & setReverseFlag(bool reverse)
Sets the reverse flag.
Definition: HouseholderSequence.h:446
TransposeReturnType transpose() const
Transpose of the Householder sequence.
Definition: HouseholderSequence.h:216
HouseholderSequence< std::conditional_t< NumTraits< Scalar >::IsComplex, internal::remove_all_t< typename VectorsType::ConjugateReturnType >, VectorsType >, std::conditional_t< NumTraits< Scalar >::IsComplex, internal::remove_all_t< typename CoeffsType::ConjugateReturnType >, CoeffsType >, Side > ConjugateReturnType
Definition: HouseholderSequence.h:136
AdjointReturnType adjoint() const
Adjoint (conjugate transpose) of the Householder sequence.
Definition: HouseholderSequence.h:241
void applyThisOnTheLeft(Dest &dst, Workspace &workspace, bool inputIsIdentity=false) const
Definition: HouseholderSequence.h:329
void applyThisOnTheRight(Dest &dst, Workspace &workspace) const
Definition: HouseholderSequence.h:311
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
Expression of the transpose of a matrix.
Definition: Transpose.h:56
@ IsComplex
Definition: common.h:73
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
HouseholderSequence< VectorsType, CoeffsType > householderSequence(const VectorsType &v, const CoeffsType &h)
Convenience function for constructing a Householder sequence.
Definition: HouseholderSequence.h:484
HouseholderSequence< VectorsType, CoeffsType, OnTheRight > rightHouseholderSequence(const VectorsType &v, const CoeffsType &h)
Convenience function for constructing a Householder sequence.
Definition: HouseholderSequence.h:495
@ OnTheLeft
Definition: Constants.h:331
@ OnTheRight
Definition: Constants.h:333
res setZero()
char char char int int * k
Definition: level2_impl.h:374
typename remove_all< T >::type remove_all_t
Definition: Meta.h:142
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Definition: MathFunctions.h:362
void apply_block_householder_on_the_left(MatrixType &mat, const VectorsType &vectors, const CoeffsType &hCoeffs, bool forward)
Definition: BlockHouseholder.h:86
EIGEN_DEVICE_FUNC bool is_same_dense(const T1 &mat1, const T2 &mat2, std::enable_if_t< possibly_same_dense< T1, T2 >::value > *=0)
Definition: XprHelper.h:869
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
EIGEN_DEVICE_FUNC const Product< MatrixDerived, PermutationDerived, AliasFreeProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition: PermutationMatrix.h:471
const int Dynamic
Definition: Constants.h:25
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
Definition: Eigen_Colamd.h:49
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243
Definition: EigenBase.h:33
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:1043
Definition: HouseholderSequence.h:78
HouseholderSequenceShape Shape
Definition: HouseholderSequence.h:83
Definition: CoreEvaluators.h:87
Definition: CoreEvaluators.h:95
Transpose< Block< const VectorsType, 1, Dynamic > > EssentialVectorType
Definition: HouseholderSequence.h:98
static const EssentialVectorType essentialVector(const HouseholderSequenceType &h, Index k)
Definition: HouseholderSequence.h:100
HouseholderSequence< VectorsType, CoeffsType, OnTheRight > HouseholderSequenceType
Definition: HouseholderSequence.h:99
Definition: HouseholderSequence.h:87
HouseholderSequence< VectorsType, CoeffsType, OnTheLeft > HouseholderSequenceType
Definition: HouseholderSequence.h:89
Block< const VectorsType, Dynamic, 1 > EssentialVectorType
Definition: HouseholderSequence.h:88
static EIGEN_DEVICE_FUNC const EssentialVectorType essentialVector(const HouseholderSequenceType &h, Index k)
Definition: HouseholderSequence.h:90
Definition: XprHelper.h:844
Definition: HouseholderSequence.h:107
ScalarBinaryOpTraits< OtherScalarType, typename MatrixType::Scalar >::ReturnType ResultScalar
Definition: HouseholderSequence.h:108
Matrix< ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, 0, MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime > Type
Definition: HouseholderSequence.h:111
VectorsType::StorageIndex StorageIndex
Definition: HouseholderSequence.h:65
VectorsType::StorageKind StorageKind
Definition: HouseholderSequence.h:66
VectorsType::Scalar Scalar
Definition: HouseholderSequence.h:64
Definition: ForwardDeclarations.h:21