1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2010 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_SELFADJOINTEIGENSOLVER_H 12 #define EIGEN_SELFADJOINTEIGENSOLVER_H 13 14 #include "./Tridiagonalization.h" 15 16 namespace Eigen { 17 18 template<typename _MatrixType> 19 class GeneralizedSelfAdjointEigenSolver; 20 21 namespace internal { 22 template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues; 23 } 24 25 /** \eigenvalues_module \ingroup Eigenvalues_Module 26 * 27 * 28 * \class SelfAdjointEigenSolver 29 * 30 * \brief Computes eigenvalues and eigenvectors of selfadjoint matrices 31 * 32 * \tparam _MatrixType the type of the matrix of which we are computing the 33 * eigendecomposition; this is expected to be an instantiation of the Matrix 34 * class template. 35 * 36 * A matrix \f$ A \f$ is selfadjoint if it equals its adjoint. For real 37 * matrices, this means that the matrix is symmetric: it equals its 38 * transpose. This class computes the eigenvalues and eigenvectors of a 39 * selfadjoint matrix. These are the scalars \f$ \lambda \f$ and vectors 40 * \f$ v \f$ such that \f$ Av = \lambda v \f$. The eigenvalues of a 41 * selfadjoint matrix are always real. If \f$ D \f$ is a diagonal matrix with 42 * the eigenvalues on the diagonal, and \f$ V \f$ is a matrix with the 43 * eigenvectors as its columns, then \f$ A = V D V^{-1} \f$ (for selfadjoint 44 * matrices, the matrix \f$ V \f$ is always invertible). This is called the 45 * eigendecomposition. 46 * 47 * The algorithm exploits the fact that the matrix is selfadjoint, making it 48 * faster and more accurate than the general purpose eigenvalue algorithms 49 * implemented in EigenSolver and ComplexEigenSolver. 50 * 51 * Only the \b lower \b triangular \b part of the input matrix is referenced. 52 * 53 * Call the function compute() to compute the eigenvalues and eigenvectors of 54 * a given matrix. Alternatively, you can use the 55 * SelfAdjointEigenSolver(const MatrixType&, int) constructor which computes 56 * the eigenvalues and eigenvectors at construction time. Once the eigenvalue 57 * and eigenvectors are computed, they can be retrieved with the eigenvalues() 58 * and eigenvectors() functions. 59 * 60 * The documentation for SelfAdjointEigenSolver(const MatrixType&, int) 61 * contains an example of the typical use of this class. 62 * 63 * To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and 64 * the likes, see the class GeneralizedSelfAdjointEigenSolver. 65 * 66 * \sa MatrixBase::eigenvalues(), class EigenSolver, class ComplexEigenSolver 67 */ 68 template<typename _MatrixType> class SelfAdjointEigenSolver 69 { 70 public: 71 72 typedef _MatrixType MatrixType; 73 enum { 74 Size = MatrixType::RowsAtCompileTime, 75 ColsAtCompileTime = MatrixType::ColsAtCompileTime, 76 Options = MatrixType::Options, 77 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime 78 }; 79 80 /** \brief Scalar type for matrices of type \p _MatrixType. */ 81 typedef typename MatrixType::Scalar Scalar; 82 typedef typename MatrixType::Index Index; 83 84 /** \brief Real scalar type for \p _MatrixType. 85 * 86 * This is just \c Scalar if #Scalar is real (e.g., \c float or 87 * \c double), and the type of the real part of \c Scalar if #Scalar is 88 * complex. 89 */ 90 typedef typename NumTraits<Scalar>::Real RealScalar; 91 92 friend struct internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>; 93 94 /** \brief Type for vector of eigenvalues as returned by eigenvalues(). 95 * 96 * This is a column vector with entries of type #RealScalar. 97 * The length of the vector is the size of \p _MatrixType. 98 */ 99 typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVectorType; 100 typedef Tridiagonalization<MatrixType> TridiagonalizationType; 101 102 /** \brief Default constructor for fixed-size matrices. 103 * 104 * The default constructor is useful in cases in which the user intends to 105 * perform decompositions via compute(). This constructor 106 * can only be used if \p _MatrixType is a fixed-size matrix; use 107 * SelfAdjointEigenSolver(Index) for dynamic-size matrices. 108 * 109 * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp 110 * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out 111 */ 112 SelfAdjointEigenSolver() 113 : m_eivec(), 114 m_eivalues(), 115 m_subdiag(), 116 m_isInitialized(false) 117 { } 118 119 /** \brief Constructor, pre-allocates memory for dynamic-size matrices. 120 * 121 * \param [in] size Positive integer, size of the matrix whose 122 * eigenvalues and eigenvectors will be computed. 123 * 124 * This constructor is useful for dynamic-size matrices, when the user 125 * intends to perform decompositions via compute(). The \p size 126 * parameter is only used as a hint. It is not an error to give a wrong 127 * \p size, but it may impair performance. 128 * 129 * \sa compute() for an example 130 */ 131 SelfAdjointEigenSolver(Index size) 132 : m_eivec(size, size), 133 m_eivalues(size), 134 m_subdiag(size > 1 ? size - 1 : 1), 135 m_isInitialized(false) 136 {} 137 138 /** \brief Constructor; computes eigendecomposition of given matrix. 139 * 140 * \param[in] matrix Selfadjoint matrix whose eigendecomposition is to 141 * be computed. Only the lower triangular part of the matrix is referenced. 142 * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly. 143 * 144 * This constructor calls compute(const MatrixType&, int) to compute the 145 * eigenvalues of the matrix \p matrix. The eigenvectors are computed if 146 * \p options equals #ComputeEigenvectors. 147 * 148 * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp 149 * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out 150 * 151 * \sa compute(const MatrixType&, int) 152 */ 153 SelfAdjointEigenSolver(const MatrixType& matrix, int options = ComputeEigenvectors) 154 : m_eivec(matrix.rows(), matrix.cols()), 155 m_eivalues(matrix.cols()), 156 m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1), 157 m_isInitialized(false) 158 { 159 compute(matrix, options); 160 } 161 162 /** \brief Computes eigendecomposition of given matrix. 163 * 164 * \param[in] matrix Selfadjoint matrix whose eigendecomposition is to 165 * be computed. Only the lower triangular part of the matrix is referenced. 166 * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly. 167 * \returns Reference to \c *this 168 * 169 * This function computes the eigenvalues of \p matrix. The eigenvalues() 170 * function can be used to retrieve them. If \p options equals #ComputeEigenvectors, 171 * then the eigenvectors are also computed and can be retrieved by 172 * calling eigenvectors(). 173 * 174 * This implementation uses a symmetric QR algorithm. The matrix is first 175 * reduced to tridiagonal form using the Tridiagonalization class. The 176 * tridiagonal matrix is then brought to diagonal form with implicit 177 * symmetric QR steps with Wilkinson shift. Details can be found in 178 * Section 8.3 of Golub \& Van Loan, <i>%Matrix Computations</i>. 179 * 180 * The cost of the computation is about \f$ 9n^3 \f$ if the eigenvectors 181 * are required and \f$ 4n^3/3 \f$ if they are not required. 182 * 183 * This method reuses the memory in the SelfAdjointEigenSolver object that 184 * was allocated when the object was constructed, if the size of the 185 * matrix does not change. 186 * 187 * Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp 188 * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out 189 * 190 * \sa SelfAdjointEigenSolver(const MatrixType&, int) 191 */ 192 SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors); 193 194 /** \brief Computes eigendecomposition of given matrix using a direct algorithm 195 * 196 * This is a variant of compute(const MatrixType&, int options) which 197 * directly solves the underlying polynomial equation. 198 * 199 * Currently only 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d). 200 * 201 * This method is usually significantly faster than the QR algorithm 202 * but it might also be less accurate. It is also worth noting that 203 * for 3x3 matrices it involves trigonometric operations which are 204 * not necessarily available for all scalar types. 205 * 206 * \sa compute(const MatrixType&, int options) 207 */ 208 SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors); 209 210 /** \brief Returns the eigenvectors of given matrix. 211 * 212 * \returns A const reference to the matrix whose columns are the eigenvectors. 213 * 214 * \pre The eigenvectors have been computed before. 215 * 216 * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding 217 * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The 218 * eigenvectors are normalized to have (Euclidean) norm equal to one. If 219 * this object was used to solve the eigenproblem for the selfadjoint 220 * matrix \f$ A \f$, then the matrix returned by this function is the 221 * matrix \f$ V \f$ in the eigendecomposition \f$ A = V D V^{-1} \f$. 222 * 223 * Example: \include SelfAdjointEigenSolver_eigenvectors.cpp 224 * Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out 225 * 226 * \sa eigenvalues() 227 */ 228 const MatrixType& eigenvectors() const 229 { 230 eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); 231 eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); 232 return m_eivec; 233 } 234 235 /** \brief Returns the eigenvalues of given matrix. 236 * 237 * \returns A const reference to the column vector containing the eigenvalues. 238 * 239 * \pre The eigenvalues have been computed before. 240 * 241 * The eigenvalues are repeated according to their algebraic multiplicity, 242 * so there are as many eigenvalues as rows in the matrix. The eigenvalues 243 * are sorted in increasing order. 244 * 245 * Example: \include SelfAdjointEigenSolver_eigenvalues.cpp 246 * Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out 247 * 248 * \sa eigenvectors(), MatrixBase::eigenvalues() 249 */ 250 const RealVectorType& eigenvalues() const 251 { 252 eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); 253 return m_eivalues; 254 } 255 256 /** \brief Computes the positive-definite square root of the matrix. 257 * 258 * \returns the positive-definite square root of the matrix 259 * 260 * \pre The eigenvalues and eigenvectors of a positive-definite matrix 261 * have been computed before. 262 * 263 * The square root of a positive-definite matrix \f$ A \f$ is the 264 * positive-definite matrix whose square equals \f$ A \f$. This function 265 * uses the eigendecomposition \f$ A = V D V^{-1} \f$ to compute the 266 * square root as \f$ A^{1/2} = V D^{1/2} V^{-1} \f$. 267 * 268 * Example: \include SelfAdjointEigenSolver_operatorSqrt.cpp 269 * Output: \verbinclude SelfAdjointEigenSolver_operatorSqrt.out 270 * 271 * \sa operatorInverseSqrt(), 272 * \ref MatrixFunctions_Module "MatrixFunctions Module" 273 */ 274 MatrixType operatorSqrt() const 275 { 276 eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); 277 eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); 278 return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint(); 279 } 280 281 /** \brief Computes the inverse square root of the matrix. 282 * 283 * \returns the inverse positive-definite square root of the matrix 284 * 285 * \pre The eigenvalues and eigenvectors of a positive-definite matrix 286 * have been computed before. 287 * 288 * This function uses the eigendecomposition \f$ A = V D V^{-1} \f$ to 289 * compute the inverse square root as \f$ V D^{-1/2} V^{-1} \f$. This is 290 * cheaper than first computing the square root with operatorSqrt() and 291 * then its inverse with MatrixBase::inverse(). 292 * 293 * Example: \include SelfAdjointEigenSolver_operatorInverseSqrt.cpp 294 * Output: \verbinclude SelfAdjointEigenSolver_operatorInverseSqrt.out 295 * 296 * \sa operatorSqrt(), MatrixBase::inverse(), 297 * \ref MatrixFunctions_Module "MatrixFunctions Module" 298 */ 299 MatrixType operatorInverseSqrt() const 300 { 301 eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); 302 eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); 303 return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint(); 304 } 305 306 /** \brief Reports whether previous computation was successful. 307 * 308 * \returns \c Success if computation was succesful, \c NoConvergence otherwise. 309 */ 310 ComputationInfo info() const 311 { 312 eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); 313 return m_info; 314 } 315 316 /** \brief Maximum number of iterations. 317 * 318 * The algorithm terminates if it does not converge within m_maxIterations * n iterations, where n 319 * denotes the size of the matrix. This value is currently set to 30 (copied from LAPACK). 320 */ 321 static const int m_maxIterations = 30; 322 323 #ifdef EIGEN2_SUPPORT 324 SelfAdjointEigenSolver(const MatrixType& matrix, bool computeEigenvectors) 325 : m_eivec(matrix.rows(), matrix.cols()), 326 m_eivalues(matrix.cols()), 327 m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1), 328 m_isInitialized(false) 329 { 330 compute(matrix, computeEigenvectors); 331 } 332 333 SelfAdjointEigenSolver(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true) 334 : m_eivec(matA.cols(), matA.cols()), 335 m_eivalues(matA.cols()), 336 m_subdiag(matA.cols() > 1 ? matA.cols() - 1 : 1), 337 m_isInitialized(false) 338 { 339 static_cast<GeneralizedSelfAdjointEigenSolver<MatrixType>*>(this)->compute(matA, matB, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); 340 } 341 342 void compute(const MatrixType& matrix, bool computeEigenvectors) 343 { 344 compute(matrix, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); 345 } 346 347 void compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors = true) 348 { 349 compute(matA, matB, computeEigenvectors ? ComputeEigenvectors : EigenvaluesOnly); 350 } 351 #endif // EIGEN2_SUPPORT 352 353 protected: 354 MatrixType m_eivec; 355 RealVectorType m_eivalues; 356 typename TridiagonalizationType::SubDiagonalType m_subdiag; 357 ComputationInfo m_info; 358 bool m_isInitialized; 359 bool m_eigenvectorsOk; 360 }; 361 362 /** \internal 363 * 364 * \eigenvalues_module \ingroup Eigenvalues_Module 365 * 366 * Performs a QR step on a tridiagonal symmetric matrix represented as a 367 * pair of two vectors \a diag and \a subdiag. 368 * 369 * \param matA the input selfadjoint matrix 370 * \param hCoeffs returned Householder coefficients 371 * 372 * For compilation efficiency reasons, this procedure does not use eigen expression 373 * for its arguments. 374 * 375 * Implemented from Golub's "Matrix Computations", algorithm 8.3.2: 376 * "implicit symmetric QR step with Wilkinson shift" 377 */ 378 namespace internal { 379 template<int StorageOrder,typename RealScalar, typename Scalar, typename Index> 380 static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n); 381 } 382 383 template<typename MatrixType> 384 SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> 385 ::compute(const MatrixType& matrix, int options) 386 { 387 eigen_assert(matrix.cols() == matrix.rows()); 388 eigen_assert((options&~(EigVecMask|GenEigMask))==0 389 && (options&EigVecMask)!=EigVecMask 390 && "invalid option parameter"); 391 bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; 392 Index n = matrix.cols(); 393 m_eivalues.resize(n,1); 394 395 if(n==1) 396 { 397 m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0)); 398 if(computeEigenvectors) 399 m_eivec.setOnes(n,n); 400 m_info = Success; 401 m_isInitialized = true; 402 m_eigenvectorsOk = computeEigenvectors; 403 return *this; 404 } 405 406 // declare some aliases 407 RealVectorType& diag = m_eivalues; 408 MatrixType& mat = m_eivec; 409 410 // map the matrix coefficients to [-1:1] to avoid over- and underflow. 411 RealScalar scale = matrix.cwiseAbs().maxCoeff(); 412 if(scale==RealScalar(0)) scale = RealScalar(1); 413 mat = matrix / scale; 414 m_subdiag.resize(n-1); 415 internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors); 416 417 Index end = n-1; 418 Index start = 0; 419 Index iter = 0; // total number of iterations 420 421 while (end>0) 422 { 423 for (Index i = start; i<end; ++i) 424 if (internal::isMuchSmallerThan(internal::abs(m_subdiag[i]),(internal::abs(diag[i])+internal::abs(diag[i+1])))) 425 m_subdiag[i] = 0; 426 427 // find the largest unreduced block 428 while (end>0 && m_subdiag[end-1]==0) 429 { 430 end--; 431 } 432 if (end<=0) 433 break; 434 435 // if we spent too many iterations, we give up 436 iter++; 437 if(iter > m_maxIterations * n) break; 438 439 start = end - 1; 440 while (start>0 && m_subdiag[start-1]!=0) 441 start--; 442 443 internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); 444 } 445 446 if (iter <= m_maxIterations * n) 447 m_info = Success; 448 else 449 m_info = NoConvergence; 450 451 // Sort eigenvalues and corresponding vectors. 452 // TODO make the sort optional ? 453 // TODO use a better sort algorithm !! 454 if (m_info == Success) 455 { 456 for (Index i = 0; i < n-1; ++i) 457 { 458 Index k; 459 m_eivalues.segment(i,n-i).minCoeff(&k); 460 if (k > 0) 461 { 462 std::swap(m_eivalues[i], m_eivalues[k+i]); 463 if(computeEigenvectors) 464 m_eivec.col(i).swap(m_eivec.col(k+i)); 465 } 466 } 467 } 468 469 // scale back the eigen values 470 m_eivalues *= scale; 471 472 m_isInitialized = true; 473 m_eigenvectorsOk = computeEigenvectors; 474 return *this; 475 } 476 477 478 namespace internal { 479 480 template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues 481 { 482 static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) 483 { eig.compute(A,options); } 484 }; 485 486 template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3,false> 487 { 488 typedef typename SolverType::MatrixType MatrixType; 489 typedef typename SolverType::RealVectorType VectorType; 490 typedef typename SolverType::Scalar Scalar; 491 492 static inline void computeRoots(const MatrixType& m, VectorType& roots) 493 { 494 using std::sqrt; 495 using std::atan2; 496 using std::cos; 497 using std::sin; 498 const Scalar s_inv3 = Scalar(1.0)/Scalar(3.0); 499 const Scalar s_sqrt3 = sqrt(Scalar(3.0)); 500 501 // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The 502 // eigenvalues are the roots to this equation, all guaranteed to be 503 // real-valued, because the matrix is symmetric. 504 Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0); 505 Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1); 506 Scalar c2 = m(0,0) + m(1,1) + m(2,2); 507 508 // Construct the parameters used in classifying the roots of the equation 509 // and in solving the equation for the roots in closed form. 510 Scalar c2_over_3 = c2*s_inv3; 511 Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3; 512 if (a_over_3 > Scalar(0)) 513 a_over_3 = Scalar(0); 514 515 Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1)); 516 517 Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3; 518 if (q > Scalar(0)) 519 q = Scalar(0); 520 521 // Compute the eigenvalues by solving for the roots of the polynomial. 522 Scalar rho = sqrt(-a_over_3); 523 Scalar theta = atan2(sqrt(-q),half_b)*s_inv3; 524 Scalar cos_theta = cos(theta); 525 Scalar sin_theta = sin(theta); 526 roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta; 527 roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); 528 roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); 529 530 // Sort in increasing order. 531 if (roots(0) >= roots(1)) 532 std::swap(roots(0),roots(1)); 533 if (roots(1) >= roots(2)) 534 { 535 std::swap(roots(1),roots(2)); 536 if (roots(0) >= roots(1)) 537 std::swap(roots(0),roots(1)); 538 } 539 } 540 541 static inline void run(SolverType& solver, const MatrixType& mat, int options) 542 { 543 using std::sqrt; 544 eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); 545 eigen_assert((options&~(EigVecMask|GenEigMask))==0 546 && (options&EigVecMask)!=EigVecMask 547 && "invalid option parameter"); 548 bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; 549 550 MatrixType& eivecs = solver.m_eivec; 551 VectorType& eivals = solver.m_eivalues; 552 553 // map the matrix coefficients to [-1:1] to avoid over- and underflow. 554 Scalar scale = mat.cwiseAbs().maxCoeff(); 555 MatrixType scaledMat = mat / scale; 556 557 // compute the eigenvalues 558 computeRoots(scaledMat,eivals); 559 560 // compute the eigen vectors 561 if(computeEigenvectors) 562 { 563 Scalar safeNorm2 = Eigen::NumTraits<Scalar>::epsilon(); 564 safeNorm2 *= safeNorm2; 565 if((eivals(2)-eivals(0))<=Eigen::NumTraits<Scalar>::epsilon()) 566 { 567 eivecs.setIdentity(); 568 } 569 else 570 { 571 scaledMat = scaledMat.template selfadjointView<Lower>(); 572 MatrixType tmp; 573 tmp = scaledMat; 574 575 Scalar d0 = eivals(2) - eivals(1); 576 Scalar d1 = eivals(1) - eivals(0); 577 int k = d0 > d1 ? 2 : 0; 578 d0 = d0 > d1 ? d1 : d0; 579 580 tmp.diagonal().array () -= eivals(k); 581 VectorType cross; 582 Scalar n; 583 n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm(); 584 585 if(n>safeNorm2) 586 eivecs.col(k) = cross / sqrt(n); 587 else 588 { 589 n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm(); 590 591 if(n>safeNorm2) 592 eivecs.col(k) = cross / sqrt(n); 593 else 594 { 595 n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm(); 596 597 if(n>safeNorm2) 598 eivecs.col(k) = cross / sqrt(n); 599 else 600 { 601 // the input matrix and/or the eigenvaues probably contains some inf/NaN, 602 // => exit 603 // scale back to the original size. 604 eivals *= scale; 605 606 solver.m_info = NumericalIssue; 607 solver.m_isInitialized = true; 608 solver.m_eigenvectorsOk = computeEigenvectors; 609 return; 610 } 611 } 612 } 613 614 tmp = scaledMat; 615 tmp.diagonal().array() -= eivals(1); 616 617 if(d0<=Eigen::NumTraits<Scalar>::epsilon()) 618 eivecs.col(1) = eivecs.col(k).unitOrthogonal(); 619 else 620 { 621 n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm(); 622 if(n>safeNorm2) 623 eivecs.col(1) = cross / sqrt(n); 624 else 625 { 626 n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm(); 627 if(n>safeNorm2) 628 eivecs.col(1) = cross / sqrt(n); 629 else 630 { 631 n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm(); 632 if(n>safeNorm2) 633 eivecs.col(1) = cross / sqrt(n); 634 else 635 { 636 // we should never reach this point, 637 // if so the last two eigenvalues are likely to ve very closed to each other 638 eivecs.col(1) = eivecs.col(k).unitOrthogonal(); 639 } 640 } 641 } 642 643 // make sure that eivecs[1] is orthogonal to eivecs[2] 644 Scalar d = eivecs.col(1).dot(eivecs.col(k)); 645 eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized(); 646 } 647 648 eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized(); 649 } 650 } 651 // Rescale back to the original size. 652 eivals *= scale; 653 654 solver.m_info = Success; 655 solver.m_isInitialized = true; 656 solver.m_eigenvectorsOk = computeEigenvectors; 657 } 658 }; 659 660 // 2x2 direct eigenvalues decomposition, code from Hauke Heibel 661 template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2,false> 662 { 663 typedef typename SolverType::MatrixType MatrixType; 664 typedef typename SolverType::RealVectorType VectorType; 665 typedef typename SolverType::Scalar Scalar; 666 667 static inline void computeRoots(const MatrixType& m, VectorType& roots) 668 { 669 using std::sqrt; 670 const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0)); 671 const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1)); 672 roots(0) = t1 - t0; 673 roots(1) = t1 + t0; 674 } 675 676 static inline void run(SolverType& solver, const MatrixType& mat, int options) 677 { 678 eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows()); 679 eigen_assert((options&~(EigVecMask|GenEigMask))==0 680 && (options&EigVecMask)!=EigVecMask 681 && "invalid option parameter"); 682 bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; 683 684 MatrixType& eivecs = solver.m_eivec; 685 VectorType& eivals = solver.m_eivalues; 686 687 // map the matrix coefficients to [-1:1] to avoid over- and underflow. 688 Scalar scale = mat.cwiseAbs().maxCoeff(); 689 scale = (std::max)(scale,Scalar(1)); 690 MatrixType scaledMat = mat / scale; 691 692 // Compute the eigenvalues 693 computeRoots(scaledMat,eivals); 694 695 // compute the eigen vectors 696 if(computeEigenvectors) 697 { 698 scaledMat.diagonal().array () -= eivals(1); 699 Scalar a2 = abs2(scaledMat(0,0)); 700 Scalar c2 = abs2(scaledMat(1,1)); 701 Scalar b2 = abs2(scaledMat(1,0)); 702 if(a2>c2) 703 { 704 eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); 705 eivecs.col(1) /= sqrt(a2+b2); 706 } 707 else 708 { 709 eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); 710 eivecs.col(1) /= sqrt(c2+b2); 711 } 712 713 eivecs.col(0) << eivecs.col(1).unitOrthogonal(); 714 } 715 716 // Rescale back to the original size. 717 eivals *= scale; 718 719 solver.m_info = Success; 720 solver.m_isInitialized = true; 721 solver.m_eigenvectorsOk = computeEigenvectors; 722 } 723 }; 724 725 } 726 727 template<typename MatrixType> 728 SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> 729 ::computeDirect(const MatrixType& matrix, int options) 730 { 731 internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>::run(*this,matrix,options); 732 return *this; 733 } 734 735 namespace internal { 736 template<int StorageOrder,typename RealScalar, typename Scalar, typename Index> 737 static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) 738 { 739 RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); 740 RealScalar e = subdiag[end-1]; 741 // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still 742 // underflow thus leading to inf/NaN values when using the following commented code: 743 // RealScalar e2 = abs2(subdiag[end-1]); 744 // RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); 745 // This explain the following, somewhat more complicated, version: 746 RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e)); 747 748 RealScalar x = diag[start] - mu; 749 RealScalar z = subdiag[start]; 750 for (Index k = start; k < end; ++k) 751 { 752 JacobiRotation<RealScalar> rot; 753 rot.makeGivens(x, z); 754 755 // do T = G' T G 756 RealScalar sdk = rot.s() * diag[k] + rot.c() * subdiag[k]; 757 RealScalar dkp1 = rot.s() * subdiag[k] + rot.c() * diag[k+1]; 758 759 diag[k] = rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k+1]); 760 diag[k+1] = rot.s() * sdk + rot.c() * dkp1; 761 subdiag[k] = rot.c() * sdk - rot.s() * dkp1; 762 763 764 if (k > start) 765 subdiag[k - 1] = rot.c() * subdiag[k-1] - rot.s() * z; 766 767 x = subdiag[k]; 768 769 if (k < end - 1) 770 { 771 z = -rot.s() * subdiag[k+1]; 772 subdiag[k + 1] = rot.c() * subdiag[k+1]; 773 } 774 775 // apply the givens rotation to the unit matrix Q = Q * G 776 if (matrixQ) 777 { 778 // FIXME if StorageOrder == RowMajor this operation is not very efficient 779 Map<Matrix<Scalar,Dynamic,Dynamic,StorageOrder> > q(matrixQ,n,n); 780 q.applyOnTheRight(k,k+1,rot); 781 } 782 } 783 } 784 785 } // end namespace internal 786 787 } // end namespace Eigen 788 789 #endif // EIGEN_SELFADJOINTEIGENSOLVER_H 790