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) 2009 Claire Maurice
      5 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 // Copyright (C) 2010 Jitse Niesen <jitse (at) maths.leeds.ac.uk>
      7 //
      8 // This Source Code Form is subject to the terms of the Mozilla
      9 // Public License v. 2.0. If a copy of the MPL was not distributed
     10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     11 
     12 #ifndef EIGEN_COMPLEX_SCHUR_H
     13 #define EIGEN_COMPLEX_SCHUR_H
     14 
     15 #include "./HessenbergDecomposition.h"
     16 
     17 namespace Eigen {
     18 
     19 namespace internal {
     20 template<typename MatrixType, bool IsComplex> struct complex_schur_reduce_to_hessenberg;
     21 }
     22 
     23 /** \eigenvalues_module \ingroup Eigenvalues_Module
     24   *
     25   *
     26   * \class ComplexSchur
     27   *
     28   * \brief Performs a complex Schur decomposition of a real or complex square matrix
     29   *
     30   * \tparam _MatrixType the type of the matrix of which we are
     31   * computing the Schur decomposition; this is expected to be an
     32   * instantiation of the Matrix class template.
     33   *
     34   * Given a real or complex square matrix A, this class computes the
     35   * Schur decomposition: \f$ A = U T U^*\f$ where U is a unitary
     36   * complex matrix, and T is a complex upper triangular matrix.  The
     37   * diagonal of the matrix T corresponds to the eigenvalues of the
     38   * matrix A.
     39   *
     40   * Call the function compute() to compute the Schur decomposition of
     41   * a given matrix. Alternatively, you can use the
     42   * ComplexSchur(const MatrixType&, bool) constructor which computes
     43   * the Schur decomposition at construction time. Once the
     44   * decomposition is computed, you can use the matrixU() and matrixT()
     45   * functions to retrieve the matrices U and V in the decomposition.
     46   *
     47   * \note This code is inspired from Jampack
     48   *
     49   * \sa class RealSchur, class EigenSolver, class ComplexEigenSolver
     50   */
     51 template<typename _MatrixType> class ComplexSchur
     52 {
     53   public:
     54     typedef _MatrixType MatrixType;
     55     enum {
     56       RowsAtCompileTime = MatrixType::RowsAtCompileTime,
     57       ColsAtCompileTime = MatrixType::ColsAtCompileTime,
     58       Options = MatrixType::Options,
     59       MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
     60       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
     61     };
     62 
     63     /** \brief Scalar type for matrices of type \p _MatrixType. */
     64     typedef typename MatrixType::Scalar Scalar;
     65     typedef typename NumTraits<Scalar>::Real RealScalar;
     66     typedef typename MatrixType::Index Index;
     67 
     68     /** \brief Complex scalar type for \p _MatrixType.
     69       *
     70       * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
     71       * \c float or \c double) and just \c Scalar if #Scalar is
     72       * complex.
     73       */
     74     typedef std::complex<RealScalar> ComplexScalar;
     75 
     76     /** \brief Type for the matrices in the Schur decomposition.
     77       *
     78       * This is a square matrix with entries of type #ComplexScalar.
     79       * The size is the same as the size of \p _MatrixType.
     80       */
     81     typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> ComplexMatrixType;
     82 
     83     /** \brief Default constructor.
     84       *
     85       * \param [in] size  Positive integer, size of the matrix whose Schur decomposition will be computed.
     86       *
     87       * The default constructor is useful in cases in which the user
     88       * intends to perform decompositions via compute().  The \p size
     89       * parameter is only used as a hint. It is not an error to give a
     90       * wrong \p size, but it may impair performance.
     91       *
     92       * \sa compute() for an example.
     93       */
     94     ComplexSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
     95       : m_matT(size,size),
     96         m_matU(size,size),
     97         m_hess(size),
     98         m_isInitialized(false),
     99         m_matUisUptodate(false)
    100     {}
    101 
    102     /** \brief Constructor; computes Schur decomposition of given matrix.
    103       *
    104       * \param[in]  matrix    Square matrix whose Schur decomposition is to be computed.
    105       * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
    106       *
    107       * This constructor calls compute() to compute the Schur decomposition.
    108       *
    109       * \sa matrixT() and matrixU() for examples.
    110       */
    111     ComplexSchur(const MatrixType& matrix, bool computeU = true)
    112             : m_matT(matrix.rows(),matrix.cols()),
    113               m_matU(matrix.rows(),matrix.cols()),
    114               m_hess(matrix.rows()),
    115               m_isInitialized(false),
    116               m_matUisUptodate(false)
    117     {
    118       compute(matrix, computeU);
    119     }
    120 
    121     /** \brief Returns the unitary matrix in the Schur decomposition.
    122       *
    123       * \returns A const reference to the matrix U.
    124       *
    125       * It is assumed that either the constructor
    126       * ComplexSchur(const MatrixType& matrix, bool computeU) or the
    127       * member function compute(const MatrixType& matrix, bool computeU)
    128       * has been called before to compute the Schur decomposition of a
    129       * matrix, and that \p computeU was set to true (the default
    130       * value).
    131       *
    132       * Example: \include ComplexSchur_matrixU.cpp
    133       * Output: \verbinclude ComplexSchur_matrixU.out
    134       */
    135     const ComplexMatrixType& matrixU() const
    136     {
    137       eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
    138       eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the ComplexSchur decomposition.");
    139       return m_matU;
    140     }
    141 
    142     /** \brief Returns the triangular matrix in the Schur decomposition.
    143       *
    144       * \returns A const reference to the matrix T.
    145       *
    146       * It is assumed that either the constructor
    147       * ComplexSchur(const MatrixType& matrix, bool computeU) or the
    148       * member function compute(const MatrixType& matrix, bool computeU)
    149       * has been called before to compute the Schur decomposition of a
    150       * matrix.
    151       *
    152       * Note that this function returns a plain square matrix. If you want to reference
    153       * only the upper triangular part, use:
    154       * \code schur.matrixT().triangularView<Upper>() \endcode
    155       *
    156       * Example: \include ComplexSchur_matrixT.cpp
    157       * Output: \verbinclude ComplexSchur_matrixT.out
    158       */
    159     const ComplexMatrixType& matrixT() const
    160     {
    161       eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
    162       return m_matT;
    163     }
    164 
    165     /** \brief Computes Schur decomposition of given matrix.
    166       *
    167       * \param[in]  matrix  Square matrix whose Schur decomposition is to be computed.
    168       * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
    169       * \returns    Reference to \c *this
    170       *
    171       * The Schur decomposition is computed by first reducing the
    172       * matrix to Hessenberg form using the class
    173       * HessenbergDecomposition. The Hessenberg matrix is then reduced
    174       * to triangular form by performing QR iterations with a single
    175       * shift. The cost of computing the Schur decomposition depends
    176       * on the number of iterations; as a rough guide, it may be taken
    177       * on the number of iterations; as a rough guide, it may be taken
    178       * to be \f$25n^3\f$ complex flops, or \f$10n^3\f$ complex flops
    179       * if \a computeU is false.
    180       *
    181       * Example: \include ComplexSchur_compute.cpp
    182       * Output: \verbinclude ComplexSchur_compute.out
    183       */
    184     ComplexSchur& compute(const MatrixType& matrix, bool computeU = true);
    185 
    186     /** \brief Reports whether previous computation was successful.
    187       *
    188       * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
    189       */
    190     ComputationInfo info() const
    191     {
    192       eigen_assert(m_isInitialized && "RealSchur is not initialized.");
    193       return m_info;
    194     }
    195 
    196     /** \brief Maximum number of iterations.
    197       *
    198       * Maximum number of iterations allowed for an eigenvalue to converge.
    199       */
    200     static const int m_maxIterations = 30;
    201 
    202   protected:
    203     ComplexMatrixType m_matT, m_matU;
    204     HessenbergDecomposition<MatrixType> m_hess;
    205     ComputationInfo m_info;
    206     bool m_isInitialized;
    207     bool m_matUisUptodate;
    208 
    209   private:
    210     bool subdiagonalEntryIsNeglegible(Index i);
    211     ComplexScalar computeShift(Index iu, Index iter);
    212     void reduceToTriangularForm(bool computeU);
    213     friend struct internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>;
    214 };
    215 
    216 /** If m_matT(i+1,i) is neglegible in floating point arithmetic
    217   * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and
    218   * return true, else return false. */
    219 template<typename MatrixType>
    220 inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
    221 {
    222   RealScalar d = internal::norm1(m_matT.coeff(i,i)) + internal::norm1(m_matT.coeff(i+1,i+1));
    223   RealScalar sd = internal::norm1(m_matT.coeff(i+1,i));
    224   if (internal::isMuchSmallerThan(sd, d, NumTraits<RealScalar>::epsilon()))
    225   {
    226     m_matT.coeffRef(i+1,i) = ComplexScalar(0);
    227     return true;
    228   }
    229   return false;
    230 }
    231 
    232 
    233 /** Compute the shift in the current QR iteration. */
    234 template<typename MatrixType>
    235 typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
    236 {
    237   if (iter == 10 || iter == 20)
    238   {
    239     // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
    240     return internal::abs(internal::real(m_matT.coeff(iu,iu-1))) + internal::abs(internal::real(m_matT.coeff(iu-1,iu-2)));
    241   }
    242 
    243   // compute the shift as one of the eigenvalues of t, the 2x2
    244   // diagonal block on the bottom of the active submatrix
    245   Matrix<ComplexScalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1);
    246   RealScalar normt = t.cwiseAbs().sum();
    247   t /= normt;     // the normalization by sf is to avoid under/overflow
    248 
    249   ComplexScalar b = t.coeff(0,1) * t.coeff(1,0);
    250   ComplexScalar c = t.coeff(0,0) - t.coeff(1,1);
    251   ComplexScalar disc = sqrt(c*c + RealScalar(4)*b);
    252   ComplexScalar det = t.coeff(0,0) * t.coeff(1,1) - b;
    253   ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1);
    254   ComplexScalar eival1 = (trace + disc) / RealScalar(2);
    255   ComplexScalar eival2 = (trace - disc) / RealScalar(2);
    256 
    257   if(internal::norm1(eival1) > internal::norm1(eival2))
    258     eival2 = det / eival1;
    259   else
    260     eival1 = det / eival2;
    261 
    262   // choose the eigenvalue closest to the bottom entry of the diagonal
    263   if(internal::norm1(eival1-t.coeff(1,1)) < internal::norm1(eival2-t.coeff(1,1)))
    264     return normt * eival1;
    265   else
    266     return normt * eival2;
    267 }
    268 
    269 
    270 template<typename MatrixType>
    271 ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool computeU)
    272 {
    273   m_matUisUptodate = false;
    274   eigen_assert(matrix.cols() == matrix.rows());
    275 
    276   if(matrix.cols() == 1)
    277   {
    278     m_matT = matrix.template cast<ComplexScalar>();
    279     if(computeU)  m_matU = ComplexMatrixType::Identity(1,1);
    280     m_info = Success;
    281     m_isInitialized = true;
    282     m_matUisUptodate = computeU;
    283     return *this;
    284   }
    285 
    286   internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix, computeU);
    287   reduceToTriangularForm(computeU);
    288   return *this;
    289 }
    290 
    291 namespace internal {
    292 
    293 /* Reduce given matrix to Hessenberg form */
    294 template<typename MatrixType, bool IsComplex>
    295 struct complex_schur_reduce_to_hessenberg
    296 {
    297   // this is the implementation for the case IsComplex = true
    298   static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
    299   {
    300     _this.m_hess.compute(matrix);
    301     _this.m_matT = _this.m_hess.matrixH();
    302     if(computeU)  _this.m_matU = _this.m_hess.matrixQ();
    303   }
    304 };
    305 
    306 template<typename MatrixType>
    307 struct complex_schur_reduce_to_hessenberg<MatrixType, false>
    308 {
    309   static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
    310   {
    311     typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;
    312     typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType;
    313 
    314     // Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar
    315     _this.m_hess.compute(matrix);
    316     _this.m_matT = _this.m_hess.matrixH().template cast<ComplexScalar>();
    317     if(computeU)
    318     {
    319       // This may cause an allocation which seems to be avoidable
    320       MatrixType Q = _this.m_hess.matrixQ();
    321       _this.m_matU = Q.template cast<ComplexScalar>();
    322     }
    323   }
    324 };
    325 
    326 } // end namespace internal
    327 
    328 // Reduce the Hessenberg matrix m_matT to triangular form by QR iteration.
    329 template<typename MatrixType>
    330 void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
    331 {
    332   // The matrix m_matT is divided in three parts.
    333   // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
    334   // Rows il,...,iu is the part we are working on (the active submatrix).
    335   // Rows iu+1,...,end are already brought in triangular form.
    336   Index iu = m_matT.cols() - 1;
    337   Index il;
    338   Index iter = 0; // number of iterations we are working on the (iu,iu) element
    339 
    340   while(true)
    341   {
    342     // find iu, the bottom row of the active submatrix
    343     while(iu > 0)
    344     {
    345       if(!subdiagonalEntryIsNeglegible(iu-1)) break;
    346       iter = 0;
    347       --iu;
    348     }
    349 
    350     // if iu is zero then we are done; the whole matrix is triangularized
    351     if(iu==0) break;
    352 
    353     // if we spent too many iterations on the current element, we give up
    354     iter++;
    355     if(iter > m_maxIterations * m_matT.cols()) break;
    356 
    357     // find il, the top row of the active submatrix
    358     il = iu-1;
    359     while(il > 0 && !subdiagonalEntryIsNeglegible(il-1))
    360     {
    361       --il;
    362     }
    363 
    364     /* perform the QR step using Givens rotations. The first rotation
    365        creates a bulge; the (il+2,il) element becomes nonzero. This
    366        bulge is chased down to the bottom of the active submatrix. */
    367 
    368     ComplexScalar shift = computeShift(iu, iter);
    369     JacobiRotation<ComplexScalar> rot;
    370     rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il));
    371     m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint());
    372     m_matT.topRows((std::min)(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
    373     if(computeU) m_matU.applyOnTheRight(il, il+1, rot);
    374 
    375     for(Index i=il+1 ; i<iu ; i++)
    376     {
    377       rot.makeGivens(m_matT.coeffRef(i,i-1), m_matT.coeffRef(i+1,i-1), &m_matT.coeffRef(i,i-1));
    378       m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
    379       m_matT.rightCols(m_matT.cols()-i).applyOnTheLeft(i, i+1, rot.adjoint());
    380       m_matT.topRows((std::min)(i+2,iu)+1).applyOnTheRight(i, i+1, rot);
    381       if(computeU) m_matU.applyOnTheRight(i, i+1, rot);
    382     }
    383   }
    384 
    385   if(iter <= m_maxIterations * m_matT.cols())
    386     m_info = Success;
    387   else
    388     m_info = NoConvergence;
    389 
    390   m_isInitialized = true;
    391   m_matUisUptodate = computeU;
    392 }
    393 
    394 } // end namespace Eigen
    395 
    396 #endif // EIGEN_COMPLEX_SCHUR_H
    397