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