12#ifndef EIGEN_HESSENBERGDECOMPOSITION_H
13#define EIGEN_HESSENBERGDECOMPOSITION_H
16#include "./InternalHeaderCheck.h"
22template <
typename MatrixType>
24template <
typename MatrixType>
26 using ReturnType =
typename MatrixType::PlainObject;
29template <
typename MatrixType,
typename CoeffVectorType,
typename WorkspaceType>
30void hessenberg_decomposition_inplace(MatrixType& matA, CoeffVectorType& hCoeffs, WorkspaceType& temp);
64template <
typename MatrixType_>
71 Size = MatrixType::RowsAtCompileTime,
72 SizeMinusOne = Size == Dynamic ? Dynamic : Size - 1,
73 Options = internal::plain_object_options<MatrixType>::value,
74 MaxSize = MatrixType::MaxRowsAtCompileTime,
75 MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : MaxSize - 1
79 using Scalar =
typename MatrixType::Scalar;
108 : m_matrix(size, size), m_temp(size), m_isInitialized(false) {
109 if (size > 1) m_hCoeffs.resize(size - 1);
121 template <
typename InputType>
123 : m_matrix(matrix.derived()), m_temp(matrix.rows()), m_isInitialized(false) {
135 template <
typename InputType>
137 : m_matrix(matrix.derived()), m_temp(matrix.rows()), m_isInitialized(false) {
158 template <
typename InputType>
179 eigen_assert(m_isInitialized &&
"HessenbergDecomposition is not initialized.");
213 eigen_assert(m_isInitialized &&
"HessenbergDecomposition is not initialized.");
232 eigen_assert(m_isInitialized &&
"HessenbergDecomposition is not initialized.");
257 eigen_assert(m_isInitialized &&
"HessenbergDecomposition is not initialized.");
258 return MatrixHReturnType(*
this);
262 using VectorType =
Matrix<Scalar, 1, Size, int(Options) | int(
RowMajor), 1, MaxSize>;
263 using RealScalar =
typename NumTraits<Scalar>::Real;
265 void computeInPlace() {
266 if (m_matrix.rows() < 2) {
267 m_isInitialized =
true;
270 m_hCoeffs.
resize(m_matrix.rows() - 1, 1);
271 internal::hessenberg_decomposition_inplace(m_matrix, m_hCoeffs, m_temp);
272 m_isInitialized =
true;
279 bool m_isInitialized;
299template <
typename MatrixType,
typename CoeffVectorType,
typename WorkspaceType>
300void hessenberg_decomposition_inplace(MatrixType& matA, CoeffVectorType& hCoeffs, WorkspaceType& temp) {
301 using Scalar =
typename MatrixType::Scalar;
302 using RealScalar =
typename NumTraits<Scalar>::Real;
303 eigen_assert(matA.rows() == matA.cols());
304 Index n = matA.rows();
306 for (Index i = 0; i < n - 1; ++i) {
308 Index remainingSize = n - i - 1;
311 auto householder = matA.col(i).tail(remainingSize);
312 const RealScalar tailSqNorm =
313 remainingSize == 1 ? RealScalar(0) : householder.tail(remainingSize - 1).unwind().squaredNorm();
314 const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
317 if (tailSqNorm <= tol && numext::abs2(numext::imag(householder.coeff(0))) <= tol) {
319 beta = numext::real(householder.coeff(0));
320 householder.tail(remainingSize - 1).setZero();
322 householder.makeHouseholderInPlace(h, beta);
324 matA.col(i).coeffRef(i + 1) = beta;
325 hCoeffs.coeffRef(i) = h;
331 matA.bottomRightCorner(remainingSize, remainingSize)
332 .applyHouseholderOnTheLeft(matA.col(i).tail(remainingSize - 1), h, &temp.coeffRef(0));
335 matA.rightCols(remainingSize)
336 .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize - 1), numext::conj(h), &temp.coeffRef(0));
352template <
typename MatrixType,
typename CoeffVectorType,
typename WorkspaceType,
typename MatrixQType>
353void hessenberg_decomposition_inplace(MatrixType& matA, CoeffVectorType& hCoeffs, WorkspaceType& temp,
354 MatrixQType& matQ,
bool computeQ) {
355 using HouseholderSequenceType =
356 HouseholderSequence<MatrixType, remove_all_t<typename CoeffVectorType::ConjugateReturnType>>;
357 const Index n = matA.rows();
358 hCoeffs.resize(n - 1);
359 hessenberg_decomposition_inplace(matA, hCoeffs, temp);
361 Index firstReflector = 0;
362 while (firstReflector < n - 1 && numext::is_exactly_zero(hCoeffs.coeff(firstReflector))) ++firstReflector;
363 if (firstReflector == n - 1) {
365 matQ.setIdentity(n, n);
367 HouseholderSequenceType(matA, hCoeffs.conjugate()).setLength(n - 1).setShift(1).evalTo(matQ, temp);
370 if (n > 2) matA.bottomLeftCorner(n - 2, n - 2).template triangularView<Lower>().setZero();
388template <
typename MatrixType>
390 :
public ReturnByValue<HessenbergDecompositionMatrixHReturnType<MatrixType>> {
403 template <
typename ResultType>
404 inline void evalTo(ResultType& result)
const {
405 result = m_hess.packedMatrix();
406 Index n = result.rows();
407 if (n > 2) result.bottomLeftCorner(n - 2, n - 2).template triangularView<Lower>().setZero();
410 Index rows()
const {
return m_hess.
packedMatrix().rows(); }
411 Index cols()
const {
return m_hess.
packedMatrix().cols(); }
414 const HessenbergDecomposition<MatrixType>& m_hess;
Reduces a square matrix to Hessenberg form by an orthogonal similarity transformation.
Definition HessenbergDecomposition.h:65
HessenbergDecomposition(EigenBase< InputType > &matrix)
Constructor for inplace decomposition .
Definition HessenbergDecomposition.h:136
HessenbergDecomposition(Index size=Size==Dynamic ? 2 :Size)
Default constructor; the decomposition will be computed later.
Definition HessenbergDecomposition.h:107
HouseholderSequence< MatrixType, internal::remove_all_t< typename CoeffVectorType::ConjugateReturnType > > HouseholderSequenceType
Return type of matrixQ()
Definition HessenbergDecomposition.h:91
HessenbergDecomposition(const EigenBase< InputType > &matrix)
Constructor; computes Hessenberg decomposition of given matrix.
Definition HessenbergDecomposition.h:122
MatrixType_ MatrixType
Synonym for the template parameter MatrixType_.
Definition HessenbergDecomposition.h:68
const MatrixType & packedMatrix() const
Returns the internal representation of the decomposition.
Definition HessenbergDecomposition.h:212
MatrixHReturnType matrixH() const
Constructs the Hessenberg matrix H in the decomposition.
Definition HessenbergDecomposition.h:256
HouseholderSequenceType matrixQ() const
Reconstructs the orthogonal matrix Q in the decomposition.
Definition HessenbergDecomposition.h:231
typename MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType.
Definition HessenbergDecomposition.h:79
Eigen::Index Index
Definition HessenbergDecomposition.h:80
HessenbergDecomposition & compute(const EigenBase< InputType > &matrix)
Computes Hessenberg decomposition of given matrix.
Definition HessenbergDecomposition.h:159
Matrix< Scalar, SizeMinusOne, 1, Options &~RowMajor, MaxSizeMinusOne, 1 > CoeffVectorType
Type for vector of Householder coefficients.
Definition HessenbergDecomposition.h:88
const CoeffVectorType & householderCoefficients() const
Returns the Householder coefficients.
Definition HessenbergDecomposition.h:178
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition HouseholderSequence.h:140
HouseholderSequence & setLength(Index length)
Sets the length of the Householder sequence.
Definition HouseholderSequence.h:526
HouseholderSequence & setShift(Index shift)
Sets the shift of the Householder sequence.
Definition HouseholderSequence.h:542
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
constexpr void resize(Index rows, Index cols)
Definition PlainObjectBase.h:282
@ RowMajor
Definition Constants.h:321
Definition EigenBase.h:34
constexpr Derived & derived()
Definition EigenBase.h:50
Expression type for return value of HessenbergDecomposition::matrixH()
Definition HessenbergDecomposition.h:390
void evalTo(ResultType &result) const
Hessenberg matrix in decomposition.
Definition HessenbergDecomposition.h:404
HessenbergDecompositionMatrixHReturnType(const HessenbergDecomposition< MatrixType > &hess)
Constructor.
Definition HessenbergDecomposition.h:396