11 #ifndef EIGEN_TRIDIAGONALIZATION_H
12 #define EIGEN_TRIDIAGONALIZATION_H
14 #include "./InternalHeaderCheck.h"
20 template<
typename MatrixType>
struct TridiagonalizationMatrixTReturnType;
21 template<
typename MatrixType>
22 struct traits<TridiagonalizationMatrixTReturnType<MatrixType> >
23 :
public traits<typename MatrixType::PlainObject>
25 typedef typename MatrixType::PlainObject ReturnType;
29 template<
typename MatrixType,
typename CoeffVectorType>
31 void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs);
73 typedef typename MatrixType::Scalar Scalar;
78 Size = MatrixType::RowsAtCompileTime,
79 SizeMinusOne = Size ==
Dynamic ?
Dynamic : (Size > 1 ? Size - 1 : 1),
80 Options = MatrixType::Options,
81 MaxSize = MatrixType::MaxRowsAtCompileTime,
82 MaxSizeMinusOne = MaxSize ==
Dynamic ?
Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1)
86 typedef typename internal::plain_col_type<MatrixType, RealScalar>::type DiagonalType;
88 typedef internal::remove_all_t<typename MatrixType::RealReturnType> MatrixTypeRealView;
89 typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType;
91 typedef std::conditional_t<NumTraits<Scalar>::IsComplex,
92 internal::add_const_on_value_type_t<typename Diagonal<const MatrixType>::RealReturnType>,
96 typedef std::conditional_t<NumTraits<Scalar>::IsComplex,
97 internal::add_const_on_value_type_t<
typename Diagonal<
const MatrixType, -1>::RealReturnType>,
99 > SubDiagonalReturnType;
117 : m_matrix(size,size),
118 m_hCoeffs(size > 1 ? size-1 : 1),
119 m_isInitialized(false)
132 template<
typename InputType>
134 : m_matrix(matrix.derived()),
135 m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1),
136 m_isInitialized(false)
138 internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
139 m_isInitialized =
true;
159 template<
typename InputType>
164 internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
165 m_isInitialized =
true;
187 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
224 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
245 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
247 .setLength(m_matrix.rows() - 1)
270 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
271 return MatrixTReturnType(m_matrix.real());
287 DiagonalReturnType
diagonal()
const;
304 CoeffVectorType m_hCoeffs;
305 bool m_isInitialized;
308 template<
typename MatrixType>
309 typename Tridiagonalization<MatrixType>::DiagonalReturnType
312 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
313 return m_matrix.diagonal().real();
316 template<
typename MatrixType>
317 typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
320 eigen_assert(m_isInitialized &&
"Tridiagonalization is not initialized.");
321 return m_matrix.template diagonal<-1>().
real();
349 template<
typename MatrixType,
typename CoeffVectorType>
351 void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
354 typedef typename MatrixType::Scalar Scalar;
355 typedef typename MatrixType::RealScalar RealScalar;
356 Index n = matA.rows();
357 eigen_assert(n==matA.cols());
358 eigen_assert(n==hCoeffs.size()+1 || n==1);
360 for (
Index i = 0; i<n-1; ++i)
362 Index remainingSize = n-i-1;
365 matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
369 matA.col(i).coeffRef(i+1) = 1;
371 hCoeffs.tail(n-i-1).noalias() = (matA.bottomRightCorner(remainingSize,remainingSize).template selfadjointView<Lower>()
372 * (
conj(h) * matA.col(i).tail(remainingSize)));
374 hCoeffs.tail(n-i-1) += (
conj(h)*RealScalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1);
376 matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>()
377 .rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1));
379 matA.col(i).coeffRef(i+1) = beta;
380 hCoeffs.coeffRef(i) = h;
385 template<
typename MatrixType,
386 int Size=MatrixType::ColsAtCompileTime,
387 bool IsComplex=NumTraits<typename MatrixType::Scalar>::IsComplex>
388 struct tridiagonalization_inplace_selector;
430 template<
typename MatrixType,
typename DiagonalType,
typename SubDiagonalType,
typename CoeffVectorType>
432 void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag,
433 CoeffVectorType& hcoeffs,
bool extractQ)
435 eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1);
436 tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, hcoeffs, extractQ);
442 template<
typename MatrixType,
int Size,
bool IsComplex>
443 struct tridiagonalization_inplace_selector
446 template<
typename DiagonalType,
typename SubDiagonalType,
typename CoeffVectorType>
447 static EIGEN_DEVICE_FUNC
448 void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType& hCoeffs,
bool extractQ)
450 tridiagonalization_inplace(mat, hCoeffs);
451 diag = mat.diagonal().real();
452 subdiag = mat.template diagonal<-1>().
real();
454 mat = HouseholderSequenceType(mat, hCoeffs.conjugate())
455 .setLength(mat.rows() - 1)
464 template<
typename MatrixType>
465 struct tridiagonalization_inplace_selector<MatrixType,3,false>
467 typedef typename MatrixType::Scalar Scalar;
468 typedef typename MatrixType::RealScalar RealScalar;
470 template<
typename DiagonalType,
typename SubDiagonalType,
typename CoeffVectorType>
471 static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType&,
bool extractQ)
474 const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
476 RealScalar v1norm2 = numext::abs2(mat(2,0));
481 subdiag[0] = mat(1,0);
482 subdiag[1] = mat(2,1);
488 RealScalar beta =
sqrt(numext::abs2(mat(1,0)) + v1norm2);
489 RealScalar invBeta = RealScalar(1)/beta;
490 Scalar m01 = mat(1,0) * invBeta;
491 Scalar m02 = mat(2,0) * invBeta;
492 Scalar q = RealScalar(2)*m01*mat(2,1) + m02*(mat(2,2) - mat(1,1));
493 diag[1] = mat(1,1) + m02*q;
494 diag[2] = mat(2,2) - m02*q;
496 subdiag[1] = mat(2,1) - m01 * q;
510 template<
typename MatrixType,
bool IsComplex>
511 struct tridiagonalization_inplace_selector<MatrixType,1,IsComplex>
513 typedef typename MatrixType::Scalar Scalar;
515 template<
typename DiagonalType,
typename SubDiagonalType,
typename CoeffVectorType>
516 static EIGEN_DEVICE_FUNC
517 void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, CoeffVectorType&,
bool extractQ)
519 diag(0,0) = numext::real(mat(0,0));
521 mat(0,0) = Scalar(1);
532 template<
typename MatrixType>
struct TridiagonalizationMatrixTReturnType
533 :
public ReturnByValue<TridiagonalizationMatrixTReturnType<MatrixType> >
540 TridiagonalizationMatrixTReturnType(
const MatrixType& mat) : m_matrix(mat) { }
542 template <
typename ResultType>
543 inline void evalTo(ResultType& result)
const
546 result.template diagonal<1>() = m_matrix.template diagonal<-1>().conjugate();
547 result.diagonal() = m_matrix.diagonal();
548 result.template diagonal<-1>() = m_matrix.template diagonal<-1>();
551 EIGEN_CONSTEXPR
Index rows() const EIGEN_NOEXCEPT {
return m_matrix.rows(); }
552 EIGEN_CONSTEXPR
Index cols() const EIGEN_NOEXCEPT {
return m_matrix.cols(); }
555 typename MatrixType::Nested m_matrix;
Expression of a diagonal/subdiagonal/superdiagonal in a matrix.
Definition: Diagonal.h:67
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition: HouseholderSequence.h:123
void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:283
Tridiagonal decomposition of a selfadjoint matrix.
Definition: Tridiagonalization.h:67
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:310
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition: Tridiagonalization.h:71
Tridiagonalization & compute(const EigenBase< InputType > &matrix)
Computes tridiagonal decomposition of given matrix.
Definition: Tridiagonalization.h:160
CoeffVectorType householderCoefficients() const
Returns the Householder coefficients.
Definition: Tridiagonalization.h:185
SubDiagonalReturnType subDiagonal() const
Returns the subdiagonal of the tridiagonal matrix T in the decomposition.
Definition: Tridiagonalization.h:318
HouseholderSequence< MatrixType, internal::remove_all_t< typename CoeffVectorType::ConjugateReturnType > > HouseholderSequenceType
Return type of matrixQ()
Definition: Tridiagonalization.h:102
HouseholderSequenceType matrixQ() const
Returns the unitary matrix Q in the decomposition.
Definition: Tridiagonalization.h:243
const MatrixType & packedMatrix() const
Returns the internal representation of the decomposition.
Definition: Tridiagonalization.h:222
MatrixTReturnType matrixT() const
Returns an expression of the tridiagonal matrix T in the decomposition.
Definition: Tridiagonalization.h:268
Tridiagonalization(const EigenBase< InputType > &matrix)
Constructor; computes tridiagonal decomposition of given matrix.
Definition: Tridiagonalization.h:133
Eigen::Index Index
Definition: Tridiagonalization.h:75
Namespace containing all symbols from the Eigen library.
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const int Dynamic
Definition: Constants.h:24
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
Definition: EigenBase.h:32
Derived & derived()
Definition: EigenBase.h:48
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: EigenBase.h:62
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231