Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Eigen::EigenSolver< _MatrixType > Class Template Reference

Computes eigenvalues and eigenvectors of general matrices. More...

#include <src/eigen/Eigen/src/Eigenvalues/EigenSolver.h>

+ Collaboration diagram for Eigen::EigenSolver< _MatrixType >:

Public Types

enum  {
  RowsAtCompileTime = MatrixType::RowsAtCompileTime , ColsAtCompileTime = MatrixType::ColsAtCompileTime , Options = MatrixType::Options , MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime ,
  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
}
 
typedef _MatrixType MatrixType
 Synonym for the template parameter _MatrixType.
 
typedef MatrixType::Scalar Scalar
 Scalar type for matrices of type MatrixType.
 
typedef NumTraits< Scalar >::Real RealScalar
 
typedef Eigen::Index Index
 
typedef std::complex< RealScalarComplexScalar
 Complex scalar type for MatrixType.
 
typedef Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > EigenvalueType
 Type for vector of eigenvalues as returned by eigenvalues().
 
typedef Matrix< ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTimeEigenvectorsType
 Type for matrix of eigenvectors as returned by eigenvectors().
 

Public Member Functions

 EigenSolver ()
 Default constructor.
 
 EigenSolver (Index size)
 Default constructor with memory preallocation.
 
template<typename InputType >
 EigenSolver (const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
 Constructor; computes eigendecomposition of given matrix.
 
EigenvectorsType eigenvectors () const
 Returns the eigenvectors of given matrix.
 
const MatrixTypepseudoEigenvectors () const
 Returns the pseudo-eigenvectors of given matrix.
 
MatrixType pseudoEigenvalueMatrix () const
 Returns the block-diagonal matrix in the pseudo-eigendecomposition.
 
const EigenvalueTypeeigenvalues () const
 Returns the eigenvalues of given matrix.
 
template<typename InputType >
EigenSolvercompute (const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
 Computes eigendecomposition of given matrix.
 
ComputationInfo info () const
 
EigenSolversetMaxIterations (Index maxIters)
 Sets the maximum number of iterations allowed.
 
Index getMaxIterations ()
 Returns the maximum number of iterations.
 
template<typename InputType >
EigenSolver< MatrixType > & compute (const EigenBase< InputType > &matrix, bool computeEigenvectors)
 

Protected Types

typedef Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ColumnVectorType
 

Static Protected Member Functions

static void check_template_parameters ()
 

Protected Attributes

MatrixType m_eivec
 
EigenvalueType m_eivalues
 
bool m_isInitialized
 
bool m_eigenvectorsOk
 
ComputationInfo m_info
 
RealSchur< MatrixTypem_realSchur
 
MatrixType m_matT
 
ColumnVectorType m_tmp
 

Private Member Functions

void doComputeEigenvectors ()
 

Detailed Description

template<typename _MatrixType>
class Eigen::EigenSolver< _MatrixType >

Computes eigenvalues and eigenvectors of general matrices.

\eigenvalues_module

Template Parameters
_MatrixTypethe type of the matrix of which we are computing the eigendecomposition; this is expected to be an instantiation of the Matrix class template. Currently, only real matrices are supported.

The eigenvalues and eigenvectors of a matrix $ A $ are scalars $ \lambda $ and vectors $ v $ such that $ Av = \lambda v $. If $ D $ is a diagonal matrix with the eigenvalues on the diagonal, and $ V $ is a matrix with the eigenvectors as its columns, then $ A V =
V D $. The matrix $ V $ is almost always invertible, in which case we have $ A = V D V^{-1} $. This is called the eigendecomposition.

The eigenvalues and eigenvectors of a matrix may be complex, even when the matrix is real. However, we can choose real matrices $ V $ and $ D
$ satisfying $ A V = V D $, just like the eigendecomposition, if the matrix $ D $ is not required to be diagonal, but if it is allowed to have blocks of the form

\[ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \]

(where $ u $ and $ v $ are real numbers) on the diagonal. These blocks correspond to complex eigenvalue pairs $ u \pm iv $. We call this variant of the eigendecomposition the pseudo-eigendecomposition.

Call the function compute() to compute the eigenvalues and eigenvectors of a given matrix. Alternatively, you can use the EigenSolver(const MatrixType&, bool) constructor which computes the eigenvalues and eigenvectors at construction time. Once the eigenvalue and eigenvectors are computed, they can be retrieved with the eigenvalues() and eigenvectors() functions. The pseudoEigenvalueMatrix() and pseudoEigenvectors() methods allow the construction of the pseudo-eigendecomposition.

The documentation for EigenSolver(const MatrixType&, bool) contains an example of the typical use of this class.

Note
The implementation is adapted from JAMA (public domain). Their code is based on EISPACK.
See also
MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver

Member Typedef Documentation

◆ ColumnVectorType

template<typename _MatrixType >
typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> Eigen::EigenSolver< _MatrixType >::ColumnVectorType
protected

◆ ComplexScalar

template<typename _MatrixType >
typedef std::complex<RealScalar> Eigen::EigenSolver< _MatrixType >::ComplexScalar

Complex scalar type for MatrixType.

This is std::complex<Scalar> if Scalar is real (e.g., float or double) and just Scalar if Scalar is complex.

◆ EigenvalueType

template<typename _MatrixType >
typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> Eigen::EigenSolver< _MatrixType >::EigenvalueType

Type for vector of eigenvalues as returned by eigenvalues().

This is a column vector with entries of type ComplexScalar. The length of the vector is the size of MatrixType.

◆ EigenvectorsType

template<typename _MatrixType >
typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> Eigen::EigenSolver< _MatrixType >::EigenvectorsType

Type for matrix of eigenvectors as returned by eigenvectors().

This is a square matrix with entries of type ComplexScalar. The size is the same as the size of MatrixType.

◆ Index

template<typename _MatrixType >
typedef Eigen::Index Eigen::EigenSolver< _MatrixType >::Index

◆ MatrixType

template<typename _MatrixType >
typedef _MatrixType Eigen::EigenSolver< _MatrixType >::MatrixType

Synonym for the template parameter _MatrixType.

◆ RealScalar

template<typename _MatrixType >
typedef NumTraits<Scalar>::Real Eigen::EigenSolver< _MatrixType >::RealScalar

◆ Scalar

template<typename _MatrixType >
typedef MatrixType::Scalar Eigen::EigenSolver< _MatrixType >::Scalar

Scalar type for matrices of type MatrixType.

Member Enumeration Documentation

◆ anonymous enum

template<typename _MatrixType >
anonymous enum
Enumerator
RowsAtCompileTime 
ColsAtCompileTime 
Options 
MaxRowsAtCompileTime 
MaxColsAtCompileTime 
71 {
72 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
73 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
74 Options = MatrixType::Options,
75 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
76 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
77 };
@ Options
Definition EigenSolver.h:74
@ RowsAtCompileTime
Definition EigenSolver.h:72
@ ColsAtCompileTime
Definition EigenSolver.h:73
@ MaxRowsAtCompileTime
Definition EigenSolver.h:75
@ MaxColsAtCompileTime
Definition EigenSolver.h:76

Constructor & Destructor Documentation

◆ EigenSolver() [1/3]

template<typename _MatrixType >
Eigen::EigenSolver< _MatrixType >::EigenSolver ( )
inline

Default constructor.

The default constructor is useful in cases in which the user intends to perform decompositions via EigenSolver::compute(const MatrixType&, bool).

See also
compute() for an example.
113: m_eivec(), m_eivalues(), m_isInitialized(false), m_realSchur(), m_matT(), m_tmp() {}
ColumnVectorType m_tmp
Definition EigenSolver.h:320
bool m_isInitialized
Definition EigenSolver.h:313
RealSchur< MatrixType > m_realSchur
Definition EigenSolver.h:316
EigenvalueType m_eivalues
Definition EigenSolver.h:312
MatrixType m_matT
Definition EigenSolver.h:317
MatrixType m_eivec
Definition EigenSolver.h:311

◆ EigenSolver() [2/3]

template<typename _MatrixType >
Eigen::EigenSolver< _MatrixType >::EigenSolver ( Index  size)
inlineexplicit

Default constructor with memory preallocation.

Like the default constructor but with preallocation of the internal data according to the specified problem size.

See also
EigenSolver()
122 : m_eivec(size, size),
123 m_eivalues(size),
124 m_isInitialized(false),
125 m_eigenvectorsOk(false),
126 m_realSchur(size),
127 m_matT(size, size),
128 m_tmp(size)
129 {}
bool m_eigenvectorsOk
Definition EigenSolver.h:314

◆ EigenSolver() [3/3]

template<typename _MatrixType >
template<typename InputType >
Eigen::EigenSolver< _MatrixType >::EigenSolver ( const EigenBase< InputType > &  matrix,
bool  computeEigenvectors = true 
)
inlineexplicit

Constructor; computes eigendecomposition of given matrix.

Parameters
[in]matrixSquare matrix whose eigendecomposition is to be computed.
[in]computeEigenvectorsIf true, both the eigenvectors and the eigenvalues are computed; if false, only the eigenvalues are computed.

This constructor calls compute() to compute the eigenvalues and eigenvectors.

Example:

Output:

See also
compute()
148 : m_eivec(matrix.rows(), matrix.cols()),
149 m_eivalues(matrix.cols()),
150 m_isInitialized(false),
151 m_eigenvectorsOk(false),
152 m_realSchur(matrix.cols()),
153 m_matT(matrix.rows(), matrix.cols()),
154 m_tmp(matrix.cols())
155 {
156 compute(matrix.derived(), computeEigenvectors);
157 }
EigenSolver & compute(const EigenBase< InputType > &matrix, bool computeEigenvectors=true)
Computes eigendecomposition of given matrix.

References Eigen::EigenSolver< _MatrixType >::compute(), and Eigen::EigenBase< Derived >::derived().

+ Here is the call graph for this function:

Member Function Documentation

◆ check_template_parameters()

template<typename _MatrixType >
static void Eigen::EigenSolver< _MatrixType >::check_template_parameters ( )
inlinestaticprotected
306 {
308 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
309 }
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition StaticAssert.h:184
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition StaticAssert.h:124
MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType.
Definition EigenSolver.h:80

References EIGEN_STATIC_ASSERT, and EIGEN_STATIC_ASSERT_NON_INTEGER.

◆ compute() [1/2]

template<typename _MatrixType >
template<typename InputType >
EigenSolver< MatrixType > & Eigen::EigenSolver< _MatrixType >::compute ( const EigenBase< InputType > &  matrix,
bool  computeEigenvectors 
)
380{
382
383 using std::sqrt;
384 using std::abs;
385 using numext::isfinite;
386 eigen_assert(matrix.cols() == matrix.rows());
387
388 // Reduce to real Schur form.
389 m_realSchur.compute(matrix.derived(), computeEigenvectors);
390
392
393 if (m_info == Success)
394 {
396 if (computeEigenvectors)
398
399 // Compute eigenvalues from matT
400 m_eivalues.resize(matrix.cols());
401 Index i = 0;
402 while (i < matrix.cols())
403 {
404 if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0))
405 {
406 m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
407 if(!(isfinite)(m_eivalues.coeffRef(i)))
408 {
409 m_isInitialized = true;
410 m_eigenvectorsOk = false;
412 return *this;
413 }
414 ++i;
415 }
416 else
417 {
418 Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1));
419 Scalar z;
420 // Compute z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
421 // without overflow
422 {
423 Scalar t0 = m_matT.coeff(i+1, i);
424 Scalar t1 = m_matT.coeff(i, i+1);
425 Scalar maxval = numext::maxi<Scalar>(abs(p),numext::maxi<Scalar>(abs(t0),abs(t1)));
426 t0 /= maxval;
427 t1 /= maxval;
428 Scalar p0 = p/maxval;
429 z = maxval * sqrt(abs(p0 * p0 + t0 * t1));
430 }
431
432 m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
433 m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
434 if(!((isfinite)(m_eivalues.coeffRef(i)) && (isfinite)(m_eivalues.coeffRef(i+1))))
435 {
436 m_isInitialized = true;
437 m_eigenvectorsOk = false;
439 return *this;
440 }
441 i += 2;
442 }
443 }
444
445 // Compute eigenvectors.
446 if (computeEigenvectors)
448 }
449
450 m_isInitialized = true;
451 m_eigenvectorsOk = computeEigenvectors;
452
453 return *this;
454}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
#define eigen_assert(x)
Definition Macros.h:579
void doComputeEigenvectors()
Definition EigenSolver.h:458
std::complex< RealScalar > ComplexScalar
Complex scalar type for MatrixType.
Definition EigenSolver.h:90
ComputationInfo m_info
Definition EigenSolver.h:315
Eigen::Index Index
Definition EigenSolver.h:82
static void check_template_parameters()
Definition EigenSolver.h:305
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:183
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition PlainObjectBase.h:279
RealSchur & compute(const EigenBase< InputType > &matrix, bool computeU=true)
Computes Schur decomposition of given matrix.
ComputationInfo info() const
Reports whether previous computation was successful.
Definition RealSchur.h:195
const MatrixType & matrixU() const
Returns the orthogonal matrix in the Schur decomposition.
Definition RealSchur.h:127
const MatrixType & matrixT() const
Returns the quasi-triangular matrix in the Schur decomposition.
Definition RealSchur.h:144
@ NumericalIssue
Definition Constants.h:434
@ Success
Definition Constants.h:432
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half &a)
Definition Half.h:445
EIGEN_DEVICE_FUNC bool() isfinite(const T &x)
Definition MathFunctions.h:957

References Eigen::EigenBase< Derived >::cols(), Eigen::EigenBase< Derived >::derived(), eigen_assert, Eigen::numext::isfinite(), Eigen::NumericalIssue, Eigen::EigenBase< Derived >::rows(), sqrt(), and Eigen::Success.

+ Here is the call graph for this function:

◆ compute() [2/2]

template<typename _MatrixType >
template<typename InputType >
EigenSolver & Eigen::EigenSolver< _MatrixType >::compute ( const EigenBase< InputType > &  matrix,
bool  computeEigenvectors = true 
)

Computes eigendecomposition of given matrix.

Parameters
[in]matrixSquare matrix whose eigendecomposition is to be computed.
[in]computeEigenvectorsIf true, both the eigenvectors and the eigenvalues are computed; if false, only the eigenvalues are computed.
Returns
Reference to *this

This function computes the eigenvalues of the real matrix matrix. The eigenvalues() function can be used to retrieve them. If computeEigenvectors is true, then the eigenvectors are also computed and can be retrieved by calling eigenvectors().

The matrix is first reduced to real Schur form using the RealSchur class. The Schur decomposition is then used to compute the eigenvalues and eigenvectors.

The cost of the computation is dominated by the cost of the Schur decomposition, which is very approximately $ 25n^3 $ (where $ n $ is the size of the matrix) if computeEigenvectors is true, and $ 10n^3 $ if computeEigenvectors is false.

This method reuses of the allocated data in the EigenSolver object.

Example:

Output:

 

Referenced by Eigen::EigenSolver< _MatrixType >::EigenSolver().

+ Here is the caller graph for this function:

◆ doComputeEigenvectors()

template<typename MatrixType >
void Eigen::EigenSolver< MatrixType >::doComputeEigenvectors
private
459{
460 using std::abs;
461 const Index size = m_eivec.cols();
462 const Scalar eps = NumTraits<Scalar>::epsilon();
463
464 // inefficient! this is already computed in RealSchur
465 Scalar norm(0);
466 for (Index j = 0; j < size; ++j)
467 {
468 norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
469 }
470
471 // Backsubstitute to find vectors of upper triangular form
472 if (norm == Scalar(0))
473 {
474 return;
475 }
476
477 for (Index n = size-1; n >= 0; n--)
478 {
479 Scalar p = m_eivalues.coeff(n).real();
480 Scalar q = m_eivalues.coeff(n).imag();
481
482 // Scalar vector
483 if (q == Scalar(0))
484 {
485 Scalar lastr(0), lastw(0);
486 Index l = n;
487
488 m_matT.coeffRef(n,n) = Scalar(1);
489 for (Index i = n-1; i >= 0; i--)
490 {
491 Scalar w = m_matT.coeff(i,i) - p;
492 Scalar r = m_matT.row(i).segment(l,n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
493
494 if (m_eivalues.coeff(i).imag() < Scalar(0))
495 {
496 lastw = w;
497 lastr = r;
498 }
499 else
500 {
501 l = i;
502 if (m_eivalues.coeff(i).imag() == Scalar(0))
503 {
504 if (w != Scalar(0))
505 m_matT.coeffRef(i,n) = -r / w;
506 else
507 m_matT.coeffRef(i,n) = -r / (eps * norm);
508 }
509 else // Solve real equations
510 {
511 Scalar x = m_matT.coeff(i,i+1);
512 Scalar y = m_matT.coeff(i+1,i);
513 Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
514 Scalar t = (x * lastr - lastw * r) / denom;
515 m_matT.coeffRef(i,n) = t;
516 if (abs(x) > abs(lastw))
517 m_matT.coeffRef(i+1,n) = (-r - w * t) / x;
518 else
519 m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw;
520 }
521
522 // Overflow control
523 Scalar t = abs(m_matT.coeff(i,n));
524 if ((eps * t) * t > Scalar(1))
525 m_matT.col(n).tail(size-i) /= t;
526 }
527 }
528 }
529 else if (q < Scalar(0) && n > 0) // Complex vector
530 {
531 Scalar lastra(0), lastsa(0), lastw(0);
532 Index l = n-1;
533
534 // Last vector component imaginary so matrix is triangular
535 if (abs(m_matT.coeff(n,n-1)) > abs(m_matT.coeff(n-1,n)))
536 {
537 m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1);
538 m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1);
539 }
540 else
541 {
542 ComplexScalar cc = ComplexScalar(Scalar(0),-m_matT.coeff(n-1,n)) / ComplexScalar(m_matT.coeff(n-1,n-1)-p,q);
543 m_matT.coeffRef(n-1,n-1) = numext::real(cc);
544 m_matT.coeffRef(n-1,n) = numext::imag(cc);
545 }
546 m_matT.coeffRef(n,n-1) = Scalar(0);
547 m_matT.coeffRef(n,n) = Scalar(1);
548 for (Index i = n-2; i >= 0; i--)
549 {
550 Scalar ra = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n-1).segment(l, n-l+1));
551 Scalar sa = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
552 Scalar w = m_matT.coeff(i,i) - p;
553
554 if (m_eivalues.coeff(i).imag() < Scalar(0))
555 {
556 lastw = w;
557 lastra = ra;
558 lastsa = sa;
559 }
560 else
561 {
562 l = i;
563 if (m_eivalues.coeff(i).imag() == RealScalar(0))
564 {
565 ComplexScalar cc = ComplexScalar(-ra,-sa) / ComplexScalar(w,q);
566 m_matT.coeffRef(i,n-1) = numext::real(cc);
567 m_matT.coeffRef(i,n) = numext::imag(cc);
568 }
569 else
570 {
571 // Solve complex equations
572 Scalar x = m_matT.coeff(i,i+1);
573 Scalar y = m_matT.coeff(i+1,i);
574 Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
575 Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
576 if ((vr == Scalar(0)) && (vi == Scalar(0)))
577 vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));
578
579 ComplexScalar cc = ComplexScalar(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra) / ComplexScalar(vr,vi);
580 m_matT.coeffRef(i,n-1) = numext::real(cc);
581 m_matT.coeffRef(i,n) = numext::imag(cc);
582 if (abs(x) > (abs(lastw) + abs(q)))
583 {
584 m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
585 m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x;
586 }
587 else
588 {
589 cc = ComplexScalar(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n)) / ComplexScalar(lastw,q);
590 m_matT.coeffRef(i+1,n-1) = numext::real(cc);
591 m_matT.coeffRef(i+1,n) = numext::imag(cc);
592 }
593 }
594
595 // Overflow control
596 Scalar t = numext::maxi<Scalar>(abs(m_matT.coeff(i,n-1)),abs(m_matT.coeff(i,n)));
597 if ((eps * t) * t > Scalar(1))
598 m_matT.block(i, n-1, size-i, 2) /= t;
599
600 }
601 }
602
603 // We handled a pair of complex conjugate eigenvalues, so need to skip them both
604 n--;
605 }
606 else
607 {
608 eigen_assert(0 && "Internal bug in EigenSolver (INF or NaN has not been detected)"); // this should not happen
609 }
610 }
611
612 // Back transformation to get eigenvectors of original matrix
613 for (Index j = size-1; j >= 0; j--)
614 {
615 m_tmp.noalias() = m_eivec.leftCols(j+1) * m_matT.col(j).segment(0, j+1);
616 m_eivec.col(j) = m_tmp;
617 }
618}
NumTraits< Scalar >::Real RealScalar
Definition EigenSolver.h:81
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition PlainObjectBase.h:160
const Scalar & y
Definition MathFunctions.h:552
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297

References eigen_assert.

◆ eigenvalues()

template<typename _MatrixType >
const EigenvalueType & Eigen::EigenSolver< _MatrixType >::eigenvalues ( ) const
inline

Returns the eigenvalues of given matrix.

Returns
A const reference to the column vector containing the eigenvalues.
Precondition
Either the constructor EigenSolver(const MatrixType&,bool) or the member function compute(const MatrixType&, bool) has been called before.

The eigenvalues are repeated according to their algebraic multiplicity, so there are as many eigenvalues as rows in the matrix. The eigenvalues are not sorted in any particular order.

Example:

Output:

See also
eigenvectors(), pseudoEigenvalueMatrix(), MatrixBase::eigenvalues()
245 {
246 eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
247 return m_eivalues;
248 }

References eigen_assert, Eigen::EigenSolver< _MatrixType >::m_eivalues, and Eigen::EigenSolver< _MatrixType >::m_isInitialized.

Referenced by igl::PlanarizerShapeUp< DerivedV, DerivedF >::assembleP(), and Eigen::internal::eigenvalues_selector< Derived, false >::run().

+ Here is the caller graph for this function:

◆ eigenvectors()

Returns the eigenvectors of given matrix.

Returns
Matrix whose columns are the (possibly complex) eigenvectors.
Precondition
Either the constructor EigenSolver(const MatrixType&,bool) or the member function compute(const MatrixType&, bool) has been called before, and computeEigenvectors was set to true (the default).

Column $ k $ of the returned matrix is an eigenvector corresponding to eigenvalue number $ k $ as returned by eigenvalues(). The eigenvectors are normalized to have (Euclidean) norm equal to one. The matrix returned by this function is the matrix $ V $ in the eigendecomposition $ A = V D V^{-1} $, if it exists.

Example:

Output:

See also
eigenvalues(), pseudoEigenvectors()
346{
347 eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
348 eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
349 const RealScalar precision = RealScalar(2)*NumTraits<RealScalar>::epsilon();
350 Index n = m_eivec.cols();
351 EigenvectorsType matV(n,n);
352 for (Index j=0; j<n; ++j)
353 {
354 if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(j)), numext::real(m_eivalues.coeff(j)), precision) || j+1==n)
355 {
356 // we have a real eigen value
357 matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
358 matV.col(j).normalize();
359 }
360 else
361 {
362 // we have a pair of complex eigen values
363 for (Index i=0; i<n; ++i)
364 {
365 matV.coeffRef(i,j) = ComplexScalar(m_eivec.coeff(i,j), m_eivec.coeff(i,j+1));
366 matV.coeffRef(i,j+1) = ComplexScalar(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
367 }
368 matV.col(j).normalize();
369 matV.col(j+1).normalize();
370 ++j;
371 }
372 }
373 return matV;
374}
Matrix< ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime > EigenvectorsType
Type for matrix of eigenvectors as returned by eigenvectors().
Definition EigenSolver.h:104
EIGEN_DEVICE_FUNC bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition MathFunctions.h:1354

References Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols >::coeffRef(), eigen_assert, and Eigen::internal::isMuchSmallerThan().

Referenced by igl::PlanarizerShapeUp< DerivedV, DerivedF >::assembleP().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getMaxIterations()

template<typename _MatrixType >
Index Eigen::EigenSolver< _MatrixType >::getMaxIterations ( )
inline

Returns the maximum number of iterations.

296 {
298 }
Index getMaxIterations()
Returns the maximum number of iterations.
Definition RealSchur.h:213

References Eigen::RealSchur< _MatrixType >::getMaxIterations(), and Eigen::EigenSolver< _MatrixType >::m_realSchur.

+ Here is the call graph for this function:

◆ info()

template<typename _MatrixType >
ComputationInfo Eigen::EigenSolver< _MatrixType >::info ( ) const
inline
Returns
NumericalIssue if the input contains INF or NaN values or overflow occured. Returns Success otherwise.
282 {
283 eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
284 return m_info;
285 }

References eigen_assert, Eigen::EigenSolver< _MatrixType >::m_info, and Eigen::EigenSolver< _MatrixType >::m_isInitialized.

◆ pseudoEigenvalueMatrix()

template<typename MatrixType >
MatrixType Eigen::EigenSolver< MatrixType >::pseudoEigenvalueMatrix

Returns the block-diagonal matrix in the pseudo-eigendecomposition.

Returns
A block-diagonal matrix.
Precondition
Either the constructor EigenSolver(const MatrixType&,bool) or the member function compute(const MatrixType&, bool) has been called before.

The matrix $ D $ returned by this function is real and block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2 blocks of the form $ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} $. These blocks are not sorted in any particular order. The matrix $ D $ and the matrix $ V $ returned by pseudoEigenvectors() satisfy $ AV = VD $.

See also
pseudoEigenvectors() for an example, eigenvalues()
325{
326 eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
327 const RealScalar precision = RealScalar(2)*NumTraits<RealScalar>::epsilon();
328 Index n = m_eivalues.rows();
329 MatrixType matD = MatrixType::Zero(n,n);
330 for (Index i=0; i<n; ++i)
331 {
332 if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i)), precision))
333 matD.coeffRef(i,i) = numext::real(m_eivalues.coeff(i));
334 else
335 {
336 matD.template block<2,2>(i,i) << numext::real(m_eivalues.coeff(i)), numext::imag(m_eivalues.coeff(i)),
337 -numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i));
338 ++i;
339 }
340 }
341 return matD;
342}
_MatrixType MatrixType
Synonym for the template parameter _MatrixType.
Definition EigenSolver.h:69
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const
Definition PlainObjectBase.h:151

References eigen_assert, and Eigen::internal::isMuchSmallerThan().

+ Here is the call graph for this function:

◆ pseudoEigenvectors()

template<typename _MatrixType >
const MatrixType & Eigen::EigenSolver< _MatrixType >::pseudoEigenvectors ( ) const
inline

Returns the pseudo-eigenvectors of given matrix.

Returns
Const reference to matrix whose columns are the pseudo-eigenvectors.
Precondition
Either the constructor EigenSolver(const MatrixType&,bool) or the member function compute(const MatrixType&, bool) has been called before, and computeEigenvectors was set to true (the default).

The real matrix $ V $ returned by this function and the block-diagonal matrix $ D $ returned by pseudoEigenvalueMatrix() satisfy $ AV = VD $.

Example:

Output:

See also
pseudoEigenvalueMatrix(), eigenvectors()
200 {
201 eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
202 eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
203 return m_eivec;
204 }

References eigen_assert, Eigen::EigenSolver< _MatrixType >::m_eigenvectorsOk, Eigen::EigenSolver< _MatrixType >::m_eivec, and Eigen::EigenSolver< _MatrixType >::m_isInitialized.

◆ setMaxIterations()

template<typename _MatrixType >
EigenSolver & Eigen::EigenSolver< _MatrixType >::setMaxIterations ( Index  maxIters)
inline

Sets the maximum number of iterations allowed.

289 {
291 return *this;
292 }
RealSchur & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition RealSchur.h:206

References Eigen::EigenSolver< _MatrixType >::m_realSchur, and Eigen::RealSchur< _MatrixType >::setMaxIterations().

+ Here is the call graph for this function:

Member Data Documentation

◆ m_eigenvectorsOk

template<typename _MatrixType >
bool Eigen::EigenSolver< _MatrixType >::m_eigenvectorsOk
protected

◆ m_eivalues

template<typename _MatrixType >
EigenvalueType Eigen::EigenSolver< _MatrixType >::m_eivalues
protected

◆ m_eivec

template<typename _MatrixType >
MatrixType Eigen::EigenSolver< _MatrixType >::m_eivec
protected

◆ m_info

template<typename _MatrixType >
ComputationInfo Eigen::EigenSolver< _MatrixType >::m_info
protected

◆ m_isInitialized

◆ m_matT

template<typename _MatrixType >
MatrixType Eigen::EigenSolver< _MatrixType >::m_matT
protected

◆ m_realSchur

template<typename _MatrixType >
RealSchur<MatrixType> Eigen::EigenSolver< _MatrixType >::m_realSchur
protected

◆ m_tmp

template<typename _MatrixType >
ColumnVectorType Eigen::EigenSolver< _MatrixType >::m_tmp
protected

The documentation for this class was generated from the following file: