xref: /aosp_15_r20/external/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2008-2009 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li // Copyright (C) 2010 Jitse Niesen <[email protected]>
6*bf2c3715SXin Li //
7*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
8*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
9*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10*bf2c3715SXin Li 
11*bf2c3715SXin Li #ifndef EIGEN_HESSENBERGDECOMPOSITION_H
12*bf2c3715SXin Li #define EIGEN_HESSENBERGDECOMPOSITION_H
13*bf2c3715SXin Li 
14*bf2c3715SXin Li namespace Eigen {
15*bf2c3715SXin Li 
16*bf2c3715SXin Li namespace internal {
17*bf2c3715SXin Li 
18*bf2c3715SXin Li template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType;
19*bf2c3715SXin Li template<typename MatrixType>
20*bf2c3715SXin Li struct traits<HessenbergDecompositionMatrixHReturnType<MatrixType> >
21*bf2c3715SXin Li {
22*bf2c3715SXin Li   typedef MatrixType ReturnType;
23*bf2c3715SXin Li };
24*bf2c3715SXin Li 
25*bf2c3715SXin Li }
26*bf2c3715SXin Li 
27*bf2c3715SXin Li /** \eigenvalues_module \ingroup Eigenvalues_Module
28*bf2c3715SXin Li   *
29*bf2c3715SXin Li   *
30*bf2c3715SXin Li   * \class HessenbergDecomposition
31*bf2c3715SXin Li   *
32*bf2c3715SXin Li   * \brief Reduces a square matrix to Hessenberg form by an orthogonal similarity transformation
33*bf2c3715SXin Li   *
34*bf2c3715SXin Li   * \tparam _MatrixType the type of the matrix of which we are computing the Hessenberg decomposition
35*bf2c3715SXin Li   *
36*bf2c3715SXin Li   * This class performs an Hessenberg decomposition of a matrix \f$ A \f$. In
37*bf2c3715SXin Li   * the real case, the Hessenberg decomposition consists of an orthogonal
38*bf2c3715SXin Li   * matrix \f$ Q \f$ and a Hessenberg matrix \f$ H \f$ such that \f$ A = Q H
39*bf2c3715SXin Li   * Q^T \f$. An orthogonal matrix is a matrix whose inverse equals its
40*bf2c3715SXin Li   * transpose (\f$ Q^{-1} = Q^T \f$). A Hessenberg matrix has zeros below the
41*bf2c3715SXin Li   * subdiagonal, so it is almost upper triangular. The Hessenberg decomposition
42*bf2c3715SXin Li   * of a complex matrix is \f$ A = Q H Q^* \f$ with \f$ Q \f$ unitary (that is,
43*bf2c3715SXin Li   * \f$ Q^{-1} = Q^* \f$).
44*bf2c3715SXin Li   *
45*bf2c3715SXin Li   * Call the function compute() to compute the Hessenberg decomposition of a
46*bf2c3715SXin Li   * given matrix. Alternatively, you can use the
47*bf2c3715SXin Li   * HessenbergDecomposition(const MatrixType&) constructor which computes the
48*bf2c3715SXin Li   * Hessenberg decomposition at construction time. Once the decomposition is
49*bf2c3715SXin Li   * computed, you can use the matrixH() and matrixQ() functions to construct
50*bf2c3715SXin Li   * the matrices H and Q in the decomposition.
51*bf2c3715SXin Li   *
52*bf2c3715SXin Li   * The documentation for matrixH() contains an example of the typical use of
53*bf2c3715SXin Li   * this class.
54*bf2c3715SXin Li   *
55*bf2c3715SXin Li   * \sa class ComplexSchur, class Tridiagonalization, \ref QR_Module "QR Module"
56*bf2c3715SXin Li   */
57*bf2c3715SXin Li template<typename _MatrixType> class HessenbergDecomposition
58*bf2c3715SXin Li {
59*bf2c3715SXin Li   public:
60*bf2c3715SXin Li 
61*bf2c3715SXin Li     /** \brief Synonym for the template parameter \p _MatrixType. */
62*bf2c3715SXin Li     typedef _MatrixType MatrixType;
63*bf2c3715SXin Li 
64*bf2c3715SXin Li     enum {
65*bf2c3715SXin Li       Size = MatrixType::RowsAtCompileTime,
66*bf2c3715SXin Li       SizeMinusOne = Size == Dynamic ? Dynamic : Size - 1,
67*bf2c3715SXin Li       Options = MatrixType::Options,
68*bf2c3715SXin Li       MaxSize = MatrixType::MaxRowsAtCompileTime,
69*bf2c3715SXin Li       MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : MaxSize - 1
70*bf2c3715SXin Li     };
71*bf2c3715SXin Li 
72*bf2c3715SXin Li     /** \brief Scalar type for matrices of type #MatrixType. */
73*bf2c3715SXin Li     typedef typename MatrixType::Scalar Scalar;
74*bf2c3715SXin Li     typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
75*bf2c3715SXin Li 
76*bf2c3715SXin Li     /** \brief Type for vector of Householder coefficients.
77*bf2c3715SXin Li       *
78*bf2c3715SXin Li       * This is column vector with entries of type #Scalar. The length of the
79*bf2c3715SXin Li       * vector is one less than the size of #MatrixType, if it is a fixed-side
80*bf2c3715SXin Li       * type.
81*bf2c3715SXin Li       */
82*bf2c3715SXin Li     typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
83*bf2c3715SXin Li 
84*bf2c3715SXin Li     /** \brief Return type of matrixQ() */
85*bf2c3715SXin Li     typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
86*bf2c3715SXin Li 
87*bf2c3715SXin Li     typedef internal::HessenbergDecompositionMatrixHReturnType<MatrixType> MatrixHReturnType;
88*bf2c3715SXin Li 
89*bf2c3715SXin Li     /** \brief Default constructor; the decomposition will be computed later.
90*bf2c3715SXin Li       *
91*bf2c3715SXin Li       * \param [in] size  The size of the matrix whose Hessenberg decomposition will be computed.
92*bf2c3715SXin Li       *
93*bf2c3715SXin Li       * The default constructor is useful in cases in which the user intends to
94*bf2c3715SXin Li       * perform decompositions via compute().  The \p size parameter is only
95*bf2c3715SXin Li       * used as a hint. It is not an error to give a wrong \p size, but it may
96*bf2c3715SXin Li       * impair performance.
97*bf2c3715SXin Li       *
98*bf2c3715SXin Li       * \sa compute() for an example.
99*bf2c3715SXin Li       */
100*bf2c3715SXin Li     explicit HessenbergDecomposition(Index size = Size==Dynamic ? 2 : Size)
101*bf2c3715SXin Li       : m_matrix(size,size),
102*bf2c3715SXin Li         m_temp(size),
103*bf2c3715SXin Li         m_isInitialized(false)
104*bf2c3715SXin Li     {
105*bf2c3715SXin Li       if(size>1)
106*bf2c3715SXin Li         m_hCoeffs.resize(size-1);
107*bf2c3715SXin Li     }
108*bf2c3715SXin Li 
109*bf2c3715SXin Li     /** \brief Constructor; computes Hessenberg decomposition of given matrix.
110*bf2c3715SXin Li       *
111*bf2c3715SXin Li       * \param[in]  matrix  Square matrix whose Hessenberg decomposition is to be computed.
112*bf2c3715SXin Li       *
113*bf2c3715SXin Li       * This constructor calls compute() to compute the Hessenberg
114*bf2c3715SXin Li       * decomposition.
115*bf2c3715SXin Li       *
116*bf2c3715SXin Li       * \sa matrixH() for an example.
117*bf2c3715SXin Li       */
118*bf2c3715SXin Li     template<typename InputType>
119*bf2c3715SXin Li     explicit HessenbergDecomposition(const EigenBase<InputType>& matrix)
120*bf2c3715SXin Li       : m_matrix(matrix.derived()),
121*bf2c3715SXin Li         m_temp(matrix.rows()),
122*bf2c3715SXin Li         m_isInitialized(false)
123*bf2c3715SXin Li     {
124*bf2c3715SXin Li       if(matrix.rows()<2)
125*bf2c3715SXin Li       {
126*bf2c3715SXin Li         m_isInitialized = true;
127*bf2c3715SXin Li         return;
128*bf2c3715SXin Li       }
129*bf2c3715SXin Li       m_hCoeffs.resize(matrix.rows()-1,1);
130*bf2c3715SXin Li       _compute(m_matrix, m_hCoeffs, m_temp);
131*bf2c3715SXin Li       m_isInitialized = true;
132*bf2c3715SXin Li     }
133*bf2c3715SXin Li 
134*bf2c3715SXin Li     /** \brief Computes Hessenberg decomposition of given matrix.
135*bf2c3715SXin Li       *
136*bf2c3715SXin Li       * \param[in]  matrix  Square matrix whose Hessenberg decomposition is to be computed.
137*bf2c3715SXin Li       * \returns    Reference to \c *this
138*bf2c3715SXin Li       *
139*bf2c3715SXin Li       * The Hessenberg decomposition is computed by bringing the columns of the
140*bf2c3715SXin Li       * matrix successively in the required form using Householder reflections
141*bf2c3715SXin Li       * (see, e.g., Algorithm 7.4.2 in Golub \& Van Loan, <i>%Matrix
142*bf2c3715SXin Li       * Computations</i>). The cost is \f$ 10n^3/3 \f$ flops, where \f$ n \f$
143*bf2c3715SXin Li       * denotes the size of the given matrix.
144*bf2c3715SXin Li       *
145*bf2c3715SXin Li       * This method reuses of the allocated data in the HessenbergDecomposition
146*bf2c3715SXin Li       * object.
147*bf2c3715SXin Li       *
148*bf2c3715SXin Li       * Example: \include HessenbergDecomposition_compute.cpp
149*bf2c3715SXin Li       * Output: \verbinclude HessenbergDecomposition_compute.out
150*bf2c3715SXin Li       */
151*bf2c3715SXin Li     template<typename InputType>
152*bf2c3715SXin Li     HessenbergDecomposition& compute(const EigenBase<InputType>& matrix)
153*bf2c3715SXin Li     {
154*bf2c3715SXin Li       m_matrix = matrix.derived();
155*bf2c3715SXin Li       if(matrix.rows()<2)
156*bf2c3715SXin Li       {
157*bf2c3715SXin Li         m_isInitialized = true;
158*bf2c3715SXin Li         return *this;
159*bf2c3715SXin Li       }
160*bf2c3715SXin Li       m_hCoeffs.resize(matrix.rows()-1,1);
161*bf2c3715SXin Li       _compute(m_matrix, m_hCoeffs, m_temp);
162*bf2c3715SXin Li       m_isInitialized = true;
163*bf2c3715SXin Li       return *this;
164*bf2c3715SXin Li     }
165*bf2c3715SXin Li 
166*bf2c3715SXin Li     /** \brief Returns the Householder coefficients.
167*bf2c3715SXin Li       *
168*bf2c3715SXin Li       * \returns a const reference to the vector of Householder coefficients
169*bf2c3715SXin Li       *
170*bf2c3715SXin Li       * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
171*bf2c3715SXin Li       * or the member function compute(const MatrixType&) has been called
172*bf2c3715SXin Li       * before to compute the Hessenberg decomposition of a matrix.
173*bf2c3715SXin Li       *
174*bf2c3715SXin Li       * The Householder coefficients allow the reconstruction of the matrix
175*bf2c3715SXin Li       * \f$ Q \f$ in the Hessenberg decomposition from the packed data.
176*bf2c3715SXin Li       *
177*bf2c3715SXin Li       * \sa packedMatrix(), \ref Householder_Module "Householder module"
178*bf2c3715SXin Li       */
179*bf2c3715SXin Li     const CoeffVectorType& householderCoefficients() const
180*bf2c3715SXin Li     {
181*bf2c3715SXin Li       eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
182*bf2c3715SXin Li       return m_hCoeffs;
183*bf2c3715SXin Li     }
184*bf2c3715SXin Li 
185*bf2c3715SXin Li     /** \brief Returns the internal representation of the decomposition
186*bf2c3715SXin Li       *
187*bf2c3715SXin Li       *	\returns a const reference to a matrix with the internal representation
188*bf2c3715SXin Li       *	         of the decomposition.
189*bf2c3715SXin Li       *
190*bf2c3715SXin Li       * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
191*bf2c3715SXin Li       * or the member function compute(const MatrixType&) has been called
192*bf2c3715SXin Li       * before to compute the Hessenberg decomposition of a matrix.
193*bf2c3715SXin Li       *
194*bf2c3715SXin Li       * The returned matrix contains the following information:
195*bf2c3715SXin Li       *  - the upper part and lower sub-diagonal represent the Hessenberg matrix H
196*bf2c3715SXin Li       *  - the rest of the lower part contains the Householder vectors that, combined with
197*bf2c3715SXin Li       *    Householder coefficients returned by householderCoefficients(),
198*bf2c3715SXin Li       *    allows to reconstruct the matrix Q as
199*bf2c3715SXin Li       *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
200*bf2c3715SXin Li       *    Here, the matrices \f$ H_i \f$ are the Householder transformations
201*bf2c3715SXin Li       *       \f$ H_i = (I - h_i v_i v_i^T) \f$
202*bf2c3715SXin Li       *    where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and
203*bf2c3715SXin Li       *    \f$ v_i \f$ is the Householder vector defined by
204*bf2c3715SXin Li       *       \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$
205*bf2c3715SXin Li       *    with M the matrix returned by this function.
206*bf2c3715SXin Li       *
207*bf2c3715SXin Li       * See LAPACK for further details on this packed storage.
208*bf2c3715SXin Li       *
209*bf2c3715SXin Li       * Example: \include HessenbergDecomposition_packedMatrix.cpp
210*bf2c3715SXin Li       * Output: \verbinclude HessenbergDecomposition_packedMatrix.out
211*bf2c3715SXin Li       *
212*bf2c3715SXin Li       * \sa householderCoefficients()
213*bf2c3715SXin Li       */
214*bf2c3715SXin Li     const MatrixType& packedMatrix() const
215*bf2c3715SXin Li     {
216*bf2c3715SXin Li       eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
217*bf2c3715SXin Li       return m_matrix;
218*bf2c3715SXin Li     }
219*bf2c3715SXin Li 
220*bf2c3715SXin Li     /** \brief Reconstructs the orthogonal matrix Q in the decomposition
221*bf2c3715SXin Li       *
222*bf2c3715SXin Li       * \returns object representing the matrix Q
223*bf2c3715SXin Li       *
224*bf2c3715SXin Li       * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
225*bf2c3715SXin Li       * or the member function compute(const MatrixType&) has been called
226*bf2c3715SXin Li       * before to compute the Hessenberg decomposition of a matrix.
227*bf2c3715SXin Li       *
228*bf2c3715SXin Li       * This function returns a light-weight object of template class
229*bf2c3715SXin Li       * HouseholderSequence. You can either apply it directly to a matrix or
230*bf2c3715SXin Li       * you can convert it to a matrix of type #MatrixType.
231*bf2c3715SXin Li       *
232*bf2c3715SXin Li       * \sa matrixH() for an example, class HouseholderSequence
233*bf2c3715SXin Li       */
234*bf2c3715SXin Li     HouseholderSequenceType matrixQ() const
235*bf2c3715SXin Li     {
236*bf2c3715SXin Li       eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
237*bf2c3715SXin Li       return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate())
238*bf2c3715SXin Li              .setLength(m_matrix.rows() - 1)
239*bf2c3715SXin Li              .setShift(1);
240*bf2c3715SXin Li     }
241*bf2c3715SXin Li 
242*bf2c3715SXin Li     /** \brief Constructs the Hessenberg matrix H in the decomposition
243*bf2c3715SXin Li       *
244*bf2c3715SXin Li       * \returns expression object representing the matrix H
245*bf2c3715SXin Li       *
246*bf2c3715SXin Li       * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
247*bf2c3715SXin Li       * or the member function compute(const MatrixType&) has been called
248*bf2c3715SXin Li       * before to compute the Hessenberg decomposition of a matrix.
249*bf2c3715SXin Li       *
250*bf2c3715SXin Li       * The object returned by this function constructs the Hessenberg matrix H
251*bf2c3715SXin Li       * when it is assigned to a matrix or otherwise evaluated. The matrix H is
252*bf2c3715SXin Li       * constructed from the packed matrix as returned by packedMatrix(): The
253*bf2c3715SXin Li       * upper part (including the subdiagonal) of the packed matrix contains
254*bf2c3715SXin Li       * the matrix H. It may sometimes be better to directly use the packed
255*bf2c3715SXin Li       * matrix instead of constructing the matrix H.
256*bf2c3715SXin Li       *
257*bf2c3715SXin Li       * Example: \include HessenbergDecomposition_matrixH.cpp
258*bf2c3715SXin Li       * Output: \verbinclude HessenbergDecomposition_matrixH.out
259*bf2c3715SXin Li       *
260*bf2c3715SXin Li       * \sa matrixQ(), packedMatrix()
261*bf2c3715SXin Li       */
262*bf2c3715SXin Li     MatrixHReturnType matrixH() const
263*bf2c3715SXin Li     {
264*bf2c3715SXin Li       eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
265*bf2c3715SXin Li       return MatrixHReturnType(*this);
266*bf2c3715SXin Li     }
267*bf2c3715SXin Li 
268*bf2c3715SXin Li   private:
269*bf2c3715SXin Li 
270*bf2c3715SXin Li     typedef Matrix<Scalar, 1, Size, int(Options) | int(RowMajor), 1, MaxSize> VectorType;
271*bf2c3715SXin Li     typedef typename NumTraits<Scalar>::Real RealScalar;
272*bf2c3715SXin Li     static void _compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp);
273*bf2c3715SXin Li 
274*bf2c3715SXin Li   protected:
275*bf2c3715SXin Li     MatrixType m_matrix;
276*bf2c3715SXin Li     CoeffVectorType m_hCoeffs;
277*bf2c3715SXin Li     VectorType m_temp;
278*bf2c3715SXin Li     bool m_isInitialized;
279*bf2c3715SXin Li };
280*bf2c3715SXin Li 
281*bf2c3715SXin Li /** \internal
282*bf2c3715SXin Li   * Performs a tridiagonal decomposition of \a matA in place.
283*bf2c3715SXin Li   *
284*bf2c3715SXin Li   * \param matA the input selfadjoint matrix
285*bf2c3715SXin Li   * \param hCoeffs returned Householder coefficients
286*bf2c3715SXin Li   *
287*bf2c3715SXin Li   * The result is written in the lower triangular part of \a matA.
288*bf2c3715SXin Li   *
289*bf2c3715SXin Li   * Implemented from Golub's "%Matrix Computations", algorithm 8.3.1.
290*bf2c3715SXin Li   *
291*bf2c3715SXin Li   * \sa packedMatrix()
292*bf2c3715SXin Li   */
293*bf2c3715SXin Li template<typename MatrixType>
294*bf2c3715SXin Li void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp)
295*bf2c3715SXin Li {
296*bf2c3715SXin Li   eigen_assert(matA.rows()==matA.cols());
297*bf2c3715SXin Li   Index n = matA.rows();
298*bf2c3715SXin Li   temp.resize(n);
299*bf2c3715SXin Li   for (Index i = 0; i<n-1; ++i)
300*bf2c3715SXin Li   {
301*bf2c3715SXin Li     // let's consider the vector v = i-th column starting at position i+1
302*bf2c3715SXin Li     Index remainingSize = n-i-1;
303*bf2c3715SXin Li     RealScalar beta;
304*bf2c3715SXin Li     Scalar h;
305*bf2c3715SXin Li     matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
306*bf2c3715SXin Li     matA.col(i).coeffRef(i+1) = beta;
307*bf2c3715SXin Li     hCoeffs.coeffRef(i) = h;
308*bf2c3715SXin Li 
309*bf2c3715SXin Li     // Apply similarity transformation to remaining columns,
310*bf2c3715SXin Li     // i.e., compute A = H A H'
311*bf2c3715SXin Li 
312*bf2c3715SXin Li     // A = H A
313*bf2c3715SXin Li     matA.bottomRightCorner(remainingSize, remainingSize)
314*bf2c3715SXin Li         .applyHouseholderOnTheLeft(matA.col(i).tail(remainingSize-1), h, &temp.coeffRef(0));
315*bf2c3715SXin Li 
316*bf2c3715SXin Li     // A = A H'
317*bf2c3715SXin Li     matA.rightCols(remainingSize)
318*bf2c3715SXin Li         .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1), numext::conj(h), &temp.coeffRef(0));
319*bf2c3715SXin Li   }
320*bf2c3715SXin Li }
321*bf2c3715SXin Li 
322*bf2c3715SXin Li namespace internal {
323*bf2c3715SXin Li 
324*bf2c3715SXin Li /** \eigenvalues_module \ingroup Eigenvalues_Module
325*bf2c3715SXin Li   *
326*bf2c3715SXin Li   *
327*bf2c3715SXin Li   * \brief Expression type for return value of HessenbergDecomposition::matrixH()
328*bf2c3715SXin Li   *
329*bf2c3715SXin Li   * \tparam MatrixType type of matrix in the Hessenberg decomposition
330*bf2c3715SXin Li   *
331*bf2c3715SXin Li   * Objects of this type represent the Hessenberg matrix in the Hessenberg
332*bf2c3715SXin Li   * decomposition of some matrix. The object holds a reference to the
333*bf2c3715SXin Li   * HessenbergDecomposition class until the it is assigned or evaluated for
334*bf2c3715SXin Li   * some other reason (the reference should remain valid during the life time
335*bf2c3715SXin Li   * of this object). This class is the return type of
336*bf2c3715SXin Li   * HessenbergDecomposition::matrixH(); there is probably no other use for this
337*bf2c3715SXin Li   * class.
338*bf2c3715SXin Li   */
339*bf2c3715SXin Li template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType
340*bf2c3715SXin Li : public ReturnByValue<HessenbergDecompositionMatrixHReturnType<MatrixType> >
341*bf2c3715SXin Li {
342*bf2c3715SXin Li   public:
343*bf2c3715SXin Li     /** \brief Constructor.
344*bf2c3715SXin Li       *
345*bf2c3715SXin Li       * \param[in] hess  Hessenberg decomposition
346*bf2c3715SXin Li       */
347*bf2c3715SXin Li     HessenbergDecompositionMatrixHReturnType(const HessenbergDecomposition<MatrixType>& hess) : m_hess(hess) { }
348*bf2c3715SXin Li 
349*bf2c3715SXin Li     /** \brief Hessenberg matrix in decomposition.
350*bf2c3715SXin Li       *
351*bf2c3715SXin Li       * \param[out] result  Hessenberg matrix in decomposition \p hess which
352*bf2c3715SXin Li       *                     was passed to the constructor
353*bf2c3715SXin Li       */
354*bf2c3715SXin Li     template <typename ResultType>
355*bf2c3715SXin Li     inline void evalTo(ResultType& result) const
356*bf2c3715SXin Li     {
357*bf2c3715SXin Li       result = m_hess.packedMatrix();
358*bf2c3715SXin Li       Index n = result.rows();
359*bf2c3715SXin Li       if (n>2)
360*bf2c3715SXin Li         result.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
361*bf2c3715SXin Li     }
362*bf2c3715SXin Li 
363*bf2c3715SXin Li     Index rows() const { return m_hess.packedMatrix().rows(); }
364*bf2c3715SXin Li     Index cols() const { return m_hess.packedMatrix().cols(); }
365*bf2c3715SXin Li 
366*bf2c3715SXin Li   protected:
367*bf2c3715SXin Li     const HessenbergDecomposition<MatrixType>& m_hess;
368*bf2c3715SXin Li };
369*bf2c3715SXin Li 
370*bf2c3715SXin Li } // end namespace internal
371*bf2c3715SXin Li 
372*bf2c3715SXin Li } // end namespace Eigen
373*bf2c3715SXin Li 
374*bf2c3715SXin Li #endif // EIGEN_HESSENBERGDECOMPOSITION_H
375