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

Performs a real Schur decomposition of a square matrix. More...

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

+ Inheritance diagram for Eigen::RealSchur< _MatrixType >:
+ Collaboration diagram for Eigen::RealSchur< _MatrixType >:

Public Types

enum  {
  RowsAtCompileTime = MatrixType::RowsAtCompileTime , ColsAtCompileTime = MatrixType::ColsAtCompileTime , Options = MatrixType::Options , MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime ,
  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
}
 
typedef _MatrixType MatrixType
 
typedef MatrixType::Scalar Scalar
 
typedef std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
 
typedef Eigen::Index Index
 
typedef Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > EigenvalueType
 
typedef Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ColumnVectorType
 

Public Member Functions

 RealSchur (Index size=RowsAtCompileTime==Dynamic ? 1 :RowsAtCompileTime)
 Default constructor.
 
template<typename InputType >
 RealSchur (const EigenBase< InputType > &matrix, bool computeU=true)
 Constructor; computes real Schur decomposition of given matrix.
 
const MatrixTypematrixU () const
 Returns the orthogonal matrix in the Schur decomposition.
 
const MatrixTypematrixT () const
 Returns the quasi-triangular matrix in the Schur decomposition.
 
template<typename InputType >
RealSchurcompute (const EigenBase< InputType > &matrix, bool computeU=true)
 Computes Schur decomposition of given matrix.
 
template<typename HessMatrixType , typename OrthMatrixType >
RealSchurcomputeFromHessenberg (const HessMatrixType &matrixH, const OrthMatrixType &matrixQ, bool computeU)
 Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T.
 
ComputationInfo info () const
 Reports whether previous computation was successful.
 
RealSchursetMaxIterations (Index maxIters)
 Sets the maximum number of iterations allowed.
 
Index getMaxIterations ()
 Returns the maximum number of iterations.
 
template<typename InputType >
RealSchur< MatrixType > & compute (const EigenBase< InputType > &matrix, bool computeU)
 
template<typename HessMatrixType , typename OrthMatrixType >
RealSchur< MatrixType > & computeFromHessenberg (const HessMatrixType &matrixH, const OrthMatrixType &matrixQ, bool computeU)
 

Static Public Attributes

static const int m_maxIterationsPerRow = 40
 Maximum number of iterations per row.
 

Private Types

typedef Matrix< Scalar, 3, 1 > Vector3s
 

Private Member Functions

Scalar computeNormOfT ()
 
Index findSmallSubdiagEntry (Index iu)
 
void splitOffTwoRows (Index iu, bool computeU, const Scalar &exshift)
 
void computeShift (Index iu, Index iter, Scalar &exshift, Vector3s &shiftInfo)
 
void initFrancisQRStep (Index il, Index iu, const Vector3s &shiftInfo, Index &im, Vector3s &firstHouseholderVector)
 
void performFrancisQRStep (Index il, Index im, Index iu, bool computeU, const Vector3s &firstHouseholderVector, Scalar *workspace)
 

Private Attributes

MatrixType m_matT
 
MatrixType m_matU
 
ColumnVectorType m_workspaceVector
 
HessenbergDecomposition< MatrixTypem_hess
 
ComputationInfo m_info
 
bool m_isInitialized
 
bool m_matUisUptodate
 
Index m_maxIters
 

Detailed Description

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

Performs a real Schur decomposition of a square matrix.

\eigenvalues_module

Template Parameters
_MatrixTypethe type of the matrix of which we are computing the real Schur decomposition; this is expected to be an instantiation of the Matrix class template.

Given a real square matrix A, this class computes the real Schur decomposition: $ A = U T U^T $ where U is a real orthogonal matrix and T is a real quasi-triangular matrix. An orthogonal matrix is a matrix whose inverse is equal to its transpose, $ U^{-1} = U^T $. A quasi-triangular matrix is a block-triangular matrix whose diagonal consists of 1-by-1 blocks and 2-by-2 blocks with complex eigenvalues. The eigenvalues of the blocks on the diagonal of T are the same as the eigenvalues of the matrix A, and thus the real Schur decomposition is used in EigenSolver to compute the eigendecomposition of a matrix.

Call the function compute() to compute the real Schur decomposition of a given matrix. Alternatively, you can use the RealSchur(const MatrixType&, bool) constructor which computes the real Schur decomposition at construction time. Once the decomposition is computed, you can use the matrixU() and matrixT() functions to retrieve the matrices U and T in the decomposition.

The documentation of RealSchur(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
class ComplexSchur, class EigenSolver, class ComplexEigenSolver

Member Typedef Documentation

◆ ColumnVectorType

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

◆ ComplexScalar

template<typename _MatrixType >
typedef std::complex<typename NumTraits<Scalar>::Real> Eigen::RealSchur< _MatrixType >::ComplexScalar

◆ EigenvalueType

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

◆ Index

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

◆ MatrixType

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

◆ Scalar

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

◆ Vector3s

template<typename _MatrixType >
typedef Matrix<Scalar,3,1> Eigen::RealSchur< _MatrixType >::Vector3s
private

Member Enumeration Documentation

◆ anonymous enum

template<typename _MatrixType >
anonymous enum
Enumerator
RowsAtCompileTime 
ColsAtCompileTime 
Options 
MaxRowsAtCompileTime 
MaxColsAtCompileTime 
58 {
59 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
60 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
61 Options = MatrixType::Options,
62 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
63 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
64 };
@ MaxColsAtCompileTime
Definition RealSchur.h:63
@ MaxRowsAtCompileTime
Definition RealSchur.h:62
@ ColsAtCompileTime
Definition RealSchur.h:60
@ Options
Definition RealSchur.h:61
@ RowsAtCompileTime
Definition RealSchur.h:59

Constructor & Destructor Documentation

◆ RealSchur() [1/2]

template<typename _MatrixType >
Eigen::RealSchur< _MatrixType >::RealSchur ( Index  size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
inlineexplicit

Default constructor.

Parameters
[in]sizePositive integer, size of the matrix whose Schur decomposition will be computed.

The default constructor is useful in cases in which the user intends to perform decompositions via compute(). The size parameter is only used as a hint. It is not an error to give a wrong size, but it may impair performance.

See also
compute() for an example.
84 : m_matT(size, size),
87 m_hess(size),
88 m_isInitialized(false),
89 m_matUisUptodate(false),
90 m_maxIters(-1)
91 { }
Index m_maxIters
Definition RealSchur.h:234
ColumnVectorType m_workspaceVector
Definition RealSchur.h:229
MatrixType m_matT
Definition RealSchur.h:227
MatrixType m_matU
Definition RealSchur.h:228
HessenbergDecomposition< MatrixType > m_hess
Definition RealSchur.h:230
bool m_isInitialized
Definition RealSchur.h:232
bool m_matUisUptodate
Definition RealSchur.h:233
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183

◆ RealSchur() [2/2]

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

Constructor; computes real Schur decomposition of given matrix.

Parameters
[in]matrixSquare matrix whose Schur decomposition is to be computed.
[in]computeUIf true, both T and U are computed; if false, only T is computed.

This constructor calls compute() to compute the Schur decomposition.

Example:

Output:

 
105 : m_matT(matrix.rows(),matrix.cols()),
106 m_matU(matrix.rows(),matrix.cols()),
107 m_workspaceVector(matrix.rows()),
108 m_hess(matrix.rows()),
109 m_isInitialized(false),
110 m_matUisUptodate(false),
111 m_maxIters(-1)
112 {
113 compute(matrix.derived(), computeU);
114 }
RealSchur & compute(const EigenBase< InputType > &matrix, bool computeU=true)
Computes Schur decomposition of given matrix.

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

+ Here is the call graph for this function:

Member Function Documentation

◆ compute() [1/2]

template<typename _MatrixType >
template<typename InputType >
RealSchur< MatrixType > & Eigen::RealSchur< _MatrixType >::compute ( const EigenBase< InputType > &  matrix,
bool  computeU 
)
250{
251 const Scalar considerAsZero = (std::numeric_limits<Scalar>::min)();
252
253 eigen_assert(matrix.cols() == matrix.rows());
254 Index maxIters = m_maxIters;
255 if (maxIters == -1)
256 maxIters = m_maxIterationsPerRow * matrix.rows();
257
258 Scalar scale = matrix.derived().cwiseAbs().maxCoeff();
259 if(scale<considerAsZero)
260 {
261 m_matT.setZero(matrix.rows(),matrix.cols());
262 if(computeU)
263 m_matU.setIdentity(matrix.rows(),matrix.cols());
264 m_info = Success;
265 m_isInitialized = true;
266 m_matUisUptodate = computeU;
267 return *this;
268 }
269
270 // Step 1. Reduce to Hessenberg form
271 m_hess.compute(matrix.derived()/scale);
272
273 // Step 2. Reduce to real Schur form
275
276 m_matT *= scale;
277
278 return *this;
279}
#define eigen_assert(x)
Definition Macros.h:579
int scale(const int val)
Definition WipeTowerDialog.cpp:14
HessenbergDecomposition & compute(const EigenBase< InputType > &matrix)
Computes Hessenberg decomposition of given matrix.
Definition HessenbergDecomposition.h:152
HouseholderSequenceType matrixQ() const
Reconstructs the orthogonal matrix Q in the decomposition.
Definition HessenbergDecomposition.h:234
MatrixHReturnType matrixH() const
Constructs the Hessenberg matrix H in the decomposition.
Definition HessenbergDecomposition.h:262
static const int m_maxIterationsPerRow
Maximum number of iterations per row.
Definition RealSchur.h:223
Eigen::Index Index
Definition RealSchur.h:67
MatrixType::Scalar Scalar
Definition RealSchur.h:65
RealSchur & computeFromHessenberg(const HessMatrixType &matrixH, const OrthMatrixType &matrixQ, bool computeU)
Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T.
ComputationInfo m_info
Definition RealSchur.h:231
@ Success
Definition Constants.h:432

References Eigen::EigenBase< Derived >::cols(), Eigen::EigenBase< Derived >::derived(), eigen_assert, Eigen::EigenBase< Derived >::rows(), scale(), and Eigen::Success.

+ Here is the call graph for this function:

◆ compute() [2/2]

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

Computes Schur decomposition of given matrix.

Parameters
[in]matrixSquare matrix whose Schur decomposition is to be computed.
[in]computeUIf true, both T and U are computed; if false, only T is computed.
Returns
Reference to *this

The Schur decomposition is computed by first reducing the matrix to Hessenberg form using the class HessenbergDecomposition. The Hessenberg matrix is then reduced to triangular form by performing Francis QR iterations with implicit double shift. The cost of computing the Schur decomposition depends on the number of iterations; as a rough guide, it may be taken to be $25n^3$ flops if computeU is true and $10n^3$ flops if computeU is false.

Example:

Output:

See also
compute(const MatrixType&, bool, Index)

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

+ Here is the caller graph for this function:

◆ computeFromHessenberg() [1/2]

template<typename _MatrixType >
template<typename HessMatrixType , typename OrthMatrixType >
RealSchur & Eigen::RealSchur< _MatrixType >::computeFromHessenberg ( const HessMatrixType &  matrixH,
const OrthMatrixType &  matrixQ,
bool  computeU 
)

Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T.

Parameters
[in]matrixHMatrix in Hessenberg form H
[in]matrixQorthogonal matrix Q that transform a matrix A to H : A = Q H Q^T
computeUComputes the matriX U of the Schur vectors
Returns
Reference to *this

This routine assumes that the matrix is already reduced in Hessenberg form matrixH using either the class HessenbergDecomposition or another mean. It computes the upper quasi-triangular matrix T of the Schur decomposition of H When computeU is true, this routine computes the matrix U such that A = U T U^T = (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix

NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix is not available, the user should give an identity matrix (Q.setIdentity())

See also
compute(const MatrixType&, bool)

◆ computeFromHessenberg() [2/2]

template<typename _MatrixType >
template<typename HessMatrixType , typename OrthMatrixType >
RealSchur< MatrixType > & Eigen::RealSchur< _MatrixType >::computeFromHessenberg ( const HessMatrixType &  matrixH,
const OrthMatrixType &  matrixQ,
bool  computeU 
)
283{
284 using std::abs;
285
286 m_matT = matrixH;
287 if(computeU)
288 m_matU = matrixQ;
289
290 Index maxIters = m_maxIters;
291 if (maxIters == -1)
292 maxIters = m_maxIterationsPerRow * matrixH.rows();
294 Scalar* workspace = &m_workspaceVector.coeffRef(0);
295
296 // The matrix m_matT is divided in three parts.
297 // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
298 // Rows il,...,iu is the part we are working on (the active window).
299 // Rows iu+1,...,end are already brought in triangular form.
300 Index iu = m_matT.cols() - 1;
301 Index iter = 0; // iteration count for current eigenvalue
302 Index totalIter = 0; // iteration count for whole matrix
303 Scalar exshift(0); // sum of exceptional shifts
304 Scalar norm = computeNormOfT();
305
306 if(norm!=Scalar(0))
307 {
308 while (iu >= 0)
309 {
311
312 // Check for convergence
313 if (il == iu) // One root found
314 {
315 m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
316 if (iu > 0)
317 m_matT.coeffRef(iu, iu-1) = Scalar(0);
318 iu--;
319 iter = 0;
320 }
321 else if (il == iu-1) // Two roots found
322 {
323 splitOffTwoRows(iu, computeU, exshift);
324 iu -= 2;
325 iter = 0;
326 }
327 else // No convergence yet
328 {
329 // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
330 Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo;
331 computeShift(iu, iter, exshift, shiftInfo);
332 iter = iter + 1;
333 totalIter = totalIter + 1;
334 if (totalIter > maxIters) break;
335 Index im;
336 initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
337 performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
338 }
339 }
340 }
341 if(totalIter <= maxIters)
342 m_info = Success;
343 else
345
346 m_isInitialized = true;
347 m_matUisUptodate = computeU;
348 return *this;
349}
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
void initFrancisQRStep(Index il, Index iu, const Vector3s &shiftInfo, Index &im, Vector3s &firstHouseholderVector)
Definition RealSchur.h:460
void computeShift(Index iu, Index iter, Scalar &exshift, Vector3s &shiftInfo)
Definition RealSchur.h:418
void splitOffTwoRows(Index iu, bool computeU, const Scalar &exshift)
Definition RealSchur.h:383
Index findSmallSubdiagEntry(Index iu)
Definition RealSchur.h:367
Scalar computeNormOfT()
Definition RealSchur.h:353
Matrix< Scalar, 3, 1 > Vector3s
Definition RealSchur.h:236
void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s &firstHouseholderVector, Scalar *workspace)
Definition RealSchur.h:485
@ NoConvergence
Definition Constants.h:436

References Eigen::NoConvergence, and Eigen::Success.

◆ computeNormOfT()

template<typename MatrixType >
MatrixType::Scalar Eigen::RealSchur< MatrixType >::computeNormOfT
inlineprivate
354{
355 const Index size = m_matT.cols();
356 // FIXME to be efficient the following would requires a triangular reduxion code
357 // Scalar norm = m_matT.upper().cwiseAbs().sum()
358 // + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
359 Scalar norm(0);
360 for (Index j = 0; j < size; ++j)
361 norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
362 return norm;
363}

◆ computeShift()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::computeShift ( Index  iu,
Index  iter,
Scalar exshift,
Vector3s shiftInfo 
)
inlineprivate
419{
420 using std::sqrt;
421 using std::abs;
422 shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
423 shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
424 shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);
425
426 // Wilkinson's original ad hoc shift
427 if (iter == 10)
428 {
429 exshift += shiftInfo.coeff(0);
430 for (Index i = 0; i <= iu; ++i)
431 m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
432 Scalar s = abs(m_matT.coeff(iu,iu-1)) + abs(m_matT.coeff(iu-1,iu-2));
433 shiftInfo.coeffRef(0) = Scalar(0.75) * s;
434 shiftInfo.coeffRef(1) = Scalar(0.75) * s;
435 shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
436 }
437
438 // MATLAB's new ad hoc shift
439 if (iter == 30)
440 {
441 Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
442 s = s * s + shiftInfo.coeff(2);
443 if (s > Scalar(0))
444 {
445 s = sqrt(s);
446 if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
447 s = -s;
448 s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
449 s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
450 exshift += s;
451 for (Index i = 0; i <= iu; ++i)
452 m_matT.coeffRef(i,i) -= s;
453 shiftInfo.setConstant(Scalar(0.964));
454 }
455 }
456}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half &a)
Definition Half.h:445

References Eigen::PlainObjectBase< Derived >::coeff(), Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols >::coeffRef(), Eigen::PlainObjectBase< Derived >::setConstant(), and sqrt().

+ Here is the call graph for this function:

◆ findSmallSubdiagEntry()

template<typename MatrixType >
Index Eigen::RealSchur< MatrixType >::findSmallSubdiagEntry ( Index  iu)
inlineprivate
368{
369 using std::abs;
370 Index res = iu;
371 while (res > 0)
372 {
373 Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));
374 if (abs(m_matT.coeff(res,res-1)) <= NumTraits<Scalar>::epsilon() * s)
375 break;
376 res--;
377 }
378 return res;
379}

◆ getMaxIterations()

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

Returns the maximum number of iterations.

214 {
215 return m_maxIters;
216 }

References Eigen::RealSchur< _MatrixType >::m_maxIters.

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

+ Here is the caller graph for this function:

◆ info()

template<typename _MatrixType >
ComputationInfo Eigen::RealSchur< _MatrixType >::info ( ) const
inline

Reports whether previous computation was successful.

Returns
Success if computation was succesful, NoConvergence otherwise.
196 {
197 eigen_assert(m_isInitialized && "RealSchur is not initialized.");
198 return m_info;
199 }

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

◆ initFrancisQRStep()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::initFrancisQRStep ( Index  il,
Index  iu,
const Vector3s shiftInfo,
Index im,
Vector3s firstHouseholderVector 
)
inlineprivate
461{
462 using std::abs;
463 Vector3s& v = firstHouseholderVector; // alias to save typing
464
465 for (im = iu-2; im >= il; --im)
466 {
467 const Scalar Tmm = m_matT.coeff(im,im);
468 const Scalar r = shiftInfo.coeff(0) - Tmm;
469 const Scalar s = shiftInfo.coeff(1) - Tmm;
470 v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im+1,im) + m_matT.coeff(im,im+1);
471 v.coeffRef(1) = m_matT.coeff(im+1,im+1) - Tmm - r - s;
472 v.coeffRef(2) = m_matT.coeff(im+2,im+1);
473 if (im == il) {
474 break;
475 }
476 const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
477 const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1)));
478 if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
479 break;
480 }
481}

References Eigen::PlainObjectBase< Derived >::coeff(), and Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols >::coeffRef().

+ Here is the call graph for this function:

◆ matrixT()

template<typename _MatrixType >
const MatrixType & Eigen::RealSchur< _MatrixType >::matrixT ( ) const
inline

Returns the quasi-triangular matrix in the Schur decomposition.

Returns
A const reference to the matrix T.
Precondition
Either the constructor RealSchur(const MatrixType&, bool) or the member function compute(const MatrixType&, bool) has been called before to compute the Schur decomposition of a matrix.
See also
RealSchur(const MatrixType&, bool) for an example
145 {
146 eigen_assert(m_isInitialized && "RealSchur is not initialized.");
147 return m_matT;
148 }

References eigen_assert, Eigen::RealSchur< _MatrixType >::m_isInitialized, and Eigen::RealSchur< _MatrixType >::m_matT.

◆ matrixU()

template<typename _MatrixType >
const MatrixType & Eigen::RealSchur< _MatrixType >::matrixU ( ) const
inline

Returns the orthogonal matrix in the Schur decomposition.

Returns
A const reference to the matrix U.
Precondition
Either the constructor RealSchur(const MatrixType&, bool) or the member function compute(const MatrixType&, bool) has been called before to compute the Schur decomposition of a matrix, and computeU was set to true (the default value).
See also
RealSchur(const MatrixType&, bool) for an example
128 {
129 eigen_assert(m_isInitialized && "RealSchur is not initialized.");
130 eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the RealSchur decomposition.");
131 return m_matU;
132 }

References eigen_assert, Eigen::RealSchur< _MatrixType >::m_isInitialized, Eigen::RealSchur< _MatrixType >::m_matU, and Eigen::RealSchur< _MatrixType >::m_matUisUptodate.

◆ performFrancisQRStep()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::performFrancisQRStep ( Index  il,
Index  im,
Index  iu,
bool  computeU,
const Vector3s firstHouseholderVector,
Scalar workspace 
)
inlineprivate
486{
487 eigen_assert(im >= il);
488 eigen_assert(im <= iu-2);
489
490 const Index size = m_matT.cols();
491
492 for (Index k = im; k <= iu-2; ++k)
493 {
494 bool firstIteration = (k == im);
495
496 Vector3s v;
497 if (firstIteration)
498 v = firstHouseholderVector;
499 else
500 v = m_matT.template block<3,1>(k,k-1);
501
502 Scalar tau, beta;
503 Matrix<Scalar, 2, 1> ess;
504 v.makeHouseholder(ess, tau, beta);
505
506 if (beta != Scalar(0)) // if v is not zero
507 {
508 if (firstIteration && k > il)
509 m_matT.coeffRef(k,k-1) = -m_matT.coeff(k,k-1);
510 else if (!firstIteration)
511 m_matT.coeffRef(k,k-1) = beta;
512
513 // These Householder transformations form the O(n^3) part of the algorithm
514 m_matT.block(k, k, 3, size-k).applyHouseholderOnTheLeft(ess, tau, workspace);
515 m_matT.block(0, k, (std::min)(iu,k+3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace);
516 if (computeU)
517 m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
518 }
519 }
520
521 Matrix<Scalar, 2, 1> v = m_matT.template block<2,1>(iu-1, iu-2);
522 Scalar tau, beta;
523 Matrix<Scalar, 1, 1> ess;
524 v.makeHouseholder(ess, tau, beta);
525
526 if (beta != Scalar(0)) // if v is not zero
527 {
528 m_matT.coeffRef(iu-1, iu-2) = beta;
529 m_matT.block(iu-1, iu-1, 2, size-iu+1).applyHouseholderOnTheLeft(ess, tau, workspace);
530 m_matT.block(0, iu-1, iu+1, 2).applyHouseholderOnTheRight(ess, tau, workspace);
531 if (computeU)
532 m_matU.block(0, iu-1, size, 2).applyHouseholderOnTheRight(ess, tau, workspace);
533 }
534
535 // clean up pollution due to round-off errors
536 for (Index i = im+2; i <= iu; ++i)
537 {
538 m_matT.coeffRef(i,i-2) = Scalar(0);
539 if (i > im+2)
540 m_matT.coeffRef(i,i-3) = Scalar(0);
541 }
542}

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

+ Here is the call graph for this function:

◆ setMaxIterations()

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

Sets the maximum number of iterations allowed.

If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size of the matrix.

207 {
208 m_maxIters = maxIters;
209 return *this;
210 }

References Eigen::RealSchur< _MatrixType >::m_maxIters.

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

+ Here is the caller graph for this function:

◆ splitOffTwoRows()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::splitOffTwoRows ( Index  iu,
bool  computeU,
const Scalar exshift 
)
inlineprivate
384{
385 using std::sqrt;
386 using std::abs;
387 const Index size = m_matT.cols();
388
389 // The eigenvalues of the 2x2 matrix [a b; c d] are
390 // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
391 Scalar p = Scalar(0.5) * (m_matT.coeff(iu-1,iu-1) - m_matT.coeff(iu,iu));
392 Scalar q = p * p + m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu); // q = tr^2 / 4 - det = discr/4
393 m_matT.coeffRef(iu,iu) += exshift;
394 m_matT.coeffRef(iu-1,iu-1) += exshift;
395
396 if (q >= Scalar(0)) // Two real eigenvalues
397 {
398 Scalar z = sqrt(abs(q));
399 JacobiRotation<Scalar> rot;
400 if (p >= Scalar(0))
401 rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
402 else
403 rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
404
405 m_matT.rightCols(size-iu+1).applyOnTheLeft(iu-1, iu, rot.adjoint());
406 m_matT.topRows(iu+1).applyOnTheRight(iu-1, iu, rot);
407 m_matT.coeffRef(iu, iu-1) = Scalar(0);
408 if (computeU)
409 m_matU.applyOnTheRight(iu-1, iu, rot);
410 }
411
412 if (iu > 1)
413 m_matT.coeffRef(iu-1, iu-2) = Scalar(0);
414}

References Eigen::JacobiRotation< Scalar >::adjoint(), Eigen::JacobiRotation< Scalar >::makeGivens(), and sqrt().

+ Here is the call graph for this function:

Member Data Documentation

◆ m_hess

template<typename _MatrixType >
HessenbergDecomposition<MatrixType> Eigen::RealSchur< _MatrixType >::m_hess
private

◆ m_info

template<typename _MatrixType >
ComputationInfo Eigen::RealSchur< _MatrixType >::m_info
private

◆ m_isInitialized

template<typename _MatrixType >
bool Eigen::RealSchur< _MatrixType >::m_isInitialized
private

◆ m_matT

template<typename _MatrixType >
MatrixType Eigen::RealSchur< _MatrixType >::m_matT
private

◆ m_matU

template<typename _MatrixType >
MatrixType Eigen::RealSchur< _MatrixType >::m_matU
private

◆ m_matUisUptodate

template<typename _MatrixType >
bool Eigen::RealSchur< _MatrixType >::m_matUisUptodate
private

◆ m_maxIterationsPerRow

template<typename _MatrixType >
const int Eigen::RealSchur< _MatrixType >::m_maxIterationsPerRow = 40
static

Maximum number of iterations per row.

If not otherwise specified, the maximum number of iterations is this number times the size of the matrix. It is currently set to 40.

◆ m_maxIters

template<typename _MatrixType >
Index Eigen::RealSchur< _MatrixType >::m_maxIters
private

◆ m_workspaceVector

template<typename _MatrixType >
ColumnVectorType Eigen::RealSchur< _MatrixType >::m_workspaceVector
private

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