Tridiagonalization.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) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
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_TRIDIAGONALIZATION_H
12 #define EIGEN_TRIDIAGONALIZATION_H
13 
14 // IWYU pragma: private
15 #include "./InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
19 namespace internal {
20 
21 template <typename MatrixType>
22 struct TridiagonalizationMatrixTReturnType;
23 template <typename MatrixType>
24 struct traits<TridiagonalizationMatrixTReturnType<MatrixType>> : public traits<typename MatrixType::PlainObject> {
25  typedef typename MatrixType::PlainObject ReturnType; // FIXME shall it be a BandMatrix?
26  enum { Flags = 0 };
27 };
28 
29 template <typename MatrixType, typename CoeffVectorType>
30 EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs);
31 } // namespace internal
32 
65 template <typename MatrixType_>
67  public:
69  typedef MatrixType_ MatrixType;
70 
71  typedef typename MatrixType::Scalar Scalar;
73  typedef Eigen::Index Index;
74 
75  enum {
76  Size = MatrixType::RowsAtCompileTime,
77  SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1),
79  MaxSize = MatrixType::MaxRowsAtCompileTime,
80  MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1)
81  };
82 
88 
93 
94  typedef std::conditional_t<
96  internal::add_const_on_value_type_t<typename Diagonal<const MatrixType, -1>::RealReturnType>,
97  const Diagonal<const MatrixType, -1>>
99 
103 
117  : m_matrix(size, size), m_hCoeffs(size > 1 ? size - 1 : 1), m_isInitialized(false) {}
118 
129  template <typename InputType>
131  : m_matrix(matrix.derived()), m_hCoeffs(matrix.cols() > 1 ? matrix.cols() - 1 : 1), m_isInitialized(false) {
133  m_isInitialized = true;
134  }
135 
153  template <typename InputType>
155  m_matrix = matrix.derived();
156  m_hCoeffs.resize(matrix.rows() - 1, 1);
158  m_isInitialized = true;
159  return *this;
160  }
161 
179  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
180  return m_hCoeffs;
181  }
182 
214  inline const MatrixType& packedMatrix() const {
215  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
216  return m_matrix;
217  }
218 
235  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
236  return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate()).setLength(m_matrix.rows() - 1).setShift(1);
237  }
238 
257  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
258  return MatrixTReturnType(m_matrix.real());
259  }
260 
275 
287 
288  protected:
292 };
293 
294 template <typename MatrixType>
296  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
297  return m_matrix.diagonal().real();
298 }
299 
300 template <typename MatrixType>
302  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
303  return m_matrix.template diagonal<-1>().real();
304 }
305 
306 namespace internal {
307 
331 template <typename MatrixType, typename CoeffVectorType>
333  using numext::conj;
334  typedef typename MatrixType::Scalar Scalar;
335  typedef typename MatrixType::RealScalar RealScalar;
336  Index n = matA.rows();
337  eigen_assert(n == matA.cols());
338  eigen_assert(n == hCoeffs.size() + 1 || n == 1);
339 
340  for (Index i = 0; i < n - 1; ++i) {
341  Index remainingSize = n - i - 1;
343  Scalar h;
344  matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
345 
346  // Apply similarity transformation to remaining columns,
347  // i.e., A = H A H' where H = I - h v v' and v = matA.col(i).tail(n-i-1)
348  matA.col(i).coeffRef(i + 1) = 1;
349 
350  hCoeffs.tail(n - i - 1).noalias() =
351  (matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>() *
352  (conj(h) * matA.col(i).tail(remainingSize)));
353 
354  hCoeffs.tail(n - i - 1) +=
355  (conj(h) * RealScalar(-0.5) * (hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) *
356  matA.col(i).tail(n - i - 1);
357 
358  matA.bottomRightCorner(remainingSize, remainingSize)
359  .template selfadjointView<Lower>()
360  .rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1));
361 
362  matA.col(i).coeffRef(i + 1) = beta;
363  hCoeffs.coeffRef(i) = h;
364  }
365 }
366 
367 // forward declaration, implementation at the end of this file
368 template <typename MatrixType, int Size = MatrixType::ColsAtCompileTime,
370 struct tridiagonalization_inplace_selector;
371 
412 template <typename MatrixType, typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType,
413  typename WorkSpaceType>
414 EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag,
415  CoeffVectorType& hcoeffs, WorkSpaceType& workspace, bool extractQ) {
416  eigen_assert(mat.cols() == mat.rows() && diag.size() == mat.rows() && subdiag.size() == mat.rows() - 1);
417  tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, hcoeffs, workspace, extractQ);
418 }
419 
423 template <typename MatrixType, int Size, bool IsComplex>
426  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
427  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag,
428  CoeffVectorType& hCoeffs, WorkSpaceType& workspace, bool extractQ) {
430  diag = mat.diagonal().real();
431  subdiag = mat.template diagonal<-1>().real();
432  if (extractQ) {
433  HouseholderSequenceType(mat, hCoeffs.conjugate()).setLength(mat.rows() - 1).setShift(1).evalTo(mat, workspace);
434  }
435  }
436 };
437 
442 template <typename MatrixType>
444  typedef typename MatrixType::Scalar Scalar;
446 
447  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
448  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType&,
449  WorkSpaceType&, bool extractQ) {
450  using std::sqrt;
452  diag[0] = mat(0, 0);
453  RealScalar v1norm2 = numext::abs2(mat(2, 0));
454  if (v1norm2 <= tol) {
455  diag[1] = mat(1, 1);
456  diag[2] = mat(2, 2);
457  subdiag[0] = mat(1, 0);
458  subdiag[1] = mat(2, 1);
459  if (extractQ) mat.setIdentity();
460  } else {
461  RealScalar beta = sqrt(numext::abs2(mat(1, 0)) + v1norm2);
462  RealScalar invBeta = RealScalar(1) / beta;
463  Scalar m01 = mat(1, 0) * invBeta;
464  Scalar m02 = mat(2, 0) * invBeta;
465  Scalar q = RealScalar(2) * m01 * mat(2, 1) + m02 * (mat(2, 2) - mat(1, 1));
466  diag[1] = mat(1, 1) + m02 * q;
467  diag[2] = mat(2, 2) - m02 * q;
468  subdiag[0] = beta;
469  subdiag[1] = mat(2, 1) - m01 * q;
470  if (extractQ) {
471  mat << 1, 0, 0, 0, m01, m02, 0, m02, -m01;
472  }
473  }
474  }
475 };
476 
480 template <typename MatrixType, bool IsComplex>
482  typedef typename MatrixType::Scalar Scalar;
483 
484  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
485  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, CoeffVectorType&,
486  WorkSpaceType&, bool extractQ) {
487  diag(0, 0) = numext::real(mat(0, 0));
488  if (extractQ) mat(0, 0) = Scalar(1);
489  }
490 };
491 
499 template <typename MatrixType>
500 struct TridiagonalizationMatrixTReturnType : public ReturnByValue<TridiagonalizationMatrixTReturnType<MatrixType>> {
501  public:
507 
508  template <typename ResultType>
509  inline void evalTo(ResultType& result) const {
510  result.setZero();
511  result.template diagonal<1>() = m_matrix.template diagonal<-1>().conjugate();
512  result.diagonal() = m_matrix.diagonal();
513  result.template diagonal<-1>() = m_matrix.template diagonal<-1>();
514  }
515 
516  EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
517  EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
518 
519  protected:
520  typename MatrixType::Nested m_matrix;
521 };
522 
523 } // end namespace internal
524 
525 } // end namespace Eigen
526 
527 #endif // EIGEN_TRIDIAGONALIZATION_H
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
#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
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Expression of a diagonal/subdiagonal/superdiagonal in a matrix.
Definition: Diagonal.h:68
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition: HouseholderSequence.h:117
EIGEN_DEVICE_FUNC HouseholderSequence & setLength(Index length)
Sets the length of the Householder sequence.
Definition: HouseholderSequence.h:402
EIGEN_DEVICE_FUNC HouseholderSequence & setShift(Index shift)
Sets the shift of the Householder sequence.
Definition: HouseholderSequence.h:418
EIGEN_DEVICE_FUNC void evalTo(DestType &dst) const
Definition: HouseholderSequence.h:253
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:192
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
Definition: ReturnByValue.h:50
const ConstDiagonalReturnType diagonal() const
Definition: SparseMatrix.h:757
Index cols() const
Definition: SparseMatrix.h:161
Index rows() const
Definition: SparseMatrix.h:159
void setIdentity()
Definition: SparseMatrix.h:842
Tridiagonal decomposition of a selfadjoint matrix.
Definition: Tridiagonalization.h:66
Tridiagonalization(Index size=Size==Dynamic ? 2 :Size)
Default constructor.
Definition: Tridiagonalization.h:116
DiagonalReturnType diagonal() const
Returns the diagonal of the tridiagonal matrix T in the decomposition.
Definition: Tridiagonalization.h:295
internal::plain_col_type< MatrixType, RealScalar >::type DiagonalType
Definition: Tridiagonalization.h:84
std::conditional_t< NumTraits< Scalar >::IsComplex, internal::add_const_on_value_type_t< typename Diagonal< const MatrixType >::RealReturnType >, const Diagonal< const MatrixType > > DiagonalReturnType
Definition: Tridiagonalization.h:92
bool m_isInitialized
Definition: Tridiagonalization.h:291
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition: Tridiagonalization.h:69
Tridiagonalization & compute(const EigenBase< InputType > &matrix)
Computes tridiagonal decomposition of given matrix.
Definition: Tridiagonalization.h:154
CoeffVectorType householderCoefficients() const
Returns the Householder coefficients.
Definition: Tridiagonalization.h:178
MatrixType m_matrix
Definition: Tridiagonalization.h:289
MatrixType::Scalar Scalar
Definition: Tridiagonalization.h:71
internal::remove_all_t< typename MatrixType::RealReturnType > MatrixTypeRealView
Definition: Tridiagonalization.h:86
internal::TridiagonalizationMatrixTReturnType< MatrixTypeRealView > MatrixTReturnType
Definition: Tridiagonalization.h:87
Matrix< Scalar, SizeMinusOne, 1, Options &~RowMajor, MaxSizeMinusOne, 1 > CoeffVectorType
Definition: Tridiagonalization.h:83
@ SizeMinusOne
Definition: Tridiagonalization.h:77
@ Size
Definition: Tridiagonalization.h:76
@ Options
Definition: Tridiagonalization.h:78
@ MaxSizeMinusOne
Definition: Tridiagonalization.h:80
@ MaxSize
Definition: Tridiagonalization.h:79
HouseholderSequence< MatrixType, internal::remove_all_t< typename CoeffVectorType::ConjugateReturnType > > HouseholderSequenceType
Return type of matrixQ()
Definition: Tridiagonalization.h:102
CoeffVectorType m_hCoeffs
Definition: Tridiagonalization.h:290
std::conditional_t< NumTraits< Scalar >::IsComplex, internal::add_const_on_value_type_t< typename Diagonal< const MatrixType, -1 >::RealReturnType >, const Diagonal< const MatrixType, -1 > > SubDiagonalReturnType
Definition: Tridiagonalization.h:98
SubDiagonalReturnType subDiagonal() const
Returns the subdiagonal of the tridiagonal matrix T in the decomposition.
Definition: Tridiagonalization.h:301
HouseholderSequenceType matrixQ() const
Returns the unitary matrix Q in the decomposition.
Definition: Tridiagonalization.h:234
const MatrixType & packedMatrix() const
Returns the internal representation of the decomposition.
Definition: Tridiagonalization.h:214
MatrixTReturnType matrixT() const
Returns an expression of the tridiagonal matrix T in the decomposition.
Definition: Tridiagonalization.h:256
Tridiagonalization(const EigenBase< InputType > &matrix)
Constructor; computes tridiagonal decomposition of given matrix.
Definition: Tridiagonalization.h:130
Matrix< RealScalar, SizeMinusOne, 1, Options &~RowMajor, MaxSizeMinusOne, 1 > SubDiagonalType
Definition: Tridiagonalization.h:85
NumTraits< Scalar >::Real RealScalar
Definition: Tridiagonalization.h:72
Eigen::Index Index
Definition: Tridiagonalization.h:73
@ IsComplex
Definition: common.h:73
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
float real
Definition: datatypes.h:10
#define min(a, b)
Definition: datatypes.h:22
void diagonal(const MatrixType &m)
Definition: diagonal.cpp:13
Scalar beta
Definition: level2_cplx_impl.h:36
const char const char const char * diag
Definition: level2_impl.h:86
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > matA(size, size)
EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType &matA, CoeffVectorType &hCoeffs)
Definition: Tridiagonalization.h:332
typename remove_all< T >::type remove_all_t
Definition: Meta.h:142
typename add_const_on_value_type< T >::type add_const_on_value_type_t
Definition: Meta.h:274
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1102
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
const AutoDiffScalar< DerType > & real(const AutoDiffScalar< DerType > &x)
Definition: AutoDiffScalar.h:486
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const AutoDiffScalar< DerType > & conj(const AutoDiffScalar< DerType > &x)
Definition: AutoDiffScalar.h:482
const int Dynamic
Definition: Constants.h:25
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
Definition: Eigen_Colamd.h:49
Definition: EigenBase.h:33
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Expression type for return value of Tridiagonalization::matrixT()
Definition: Tridiagonalization.h:500
MatrixType::Nested m_matrix
Definition: Tridiagonalization.h:520
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: Tridiagonalization.h:517
void evalTo(ResultType &result) const
Definition: Tridiagonalization.h:509
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: Tridiagonalization.h:516
TridiagonalizationMatrixTReturnType(const MatrixType &mat)
Constructor.
Definition: Tridiagonalization.h:506
std::conditional_t< is_same< typename traits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixColType, ArrayColType > type
Definition: XprHelper.h:782
MatrixType::PlainObject ReturnType
Definition: Tridiagonalization.h:25
Definition: ForwardDeclarations.h:21
static EIGEN_DEVICE_FUNC void run(MatrixType &mat, DiagonalType &diag, SubDiagonalType &, CoeffVectorType &, WorkSpaceType &, bool extractQ)
Definition: Tridiagonalization.h:485
MatrixType::Scalar Scalar
Definition: Tridiagonalization.h:482
MatrixType::Scalar Scalar
Definition: Tridiagonalization.h:444
MatrixType::RealScalar RealScalar
Definition: Tridiagonalization.h:445
static EIGEN_DEVICE_FUNC void run(MatrixType &mat, DiagonalType &diag, SubDiagonalType &subdiag, CoeffVectorType &, WorkSpaceType &, bool extractQ)
Definition: Tridiagonalization.h:448
Definition: Tridiagonalization.h:424
Tridiagonalization< MatrixType >::HouseholderSequenceType HouseholderSequenceType
Definition: Tridiagonalization.h:425
static EIGEN_DEVICE_FUNC void run(MatrixType &mat, DiagonalType &diag, SubDiagonalType &subdiag, CoeffVectorType &hCoeffs, WorkSpaceType &workspace, bool extractQ)
Definition: Tridiagonalization.h:427
Definition: oomph_metis_from_parmetis_3.1.1/struct.h:100