Eigen::RealSchur< MatrixType_ > Class Template Reference

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

#include <RealSchur.h>

Public Types

enum  {
  RowsAtCompileTime = MatrixType::RowsAtCompileTime , ColsAtCompileTime = MatrixType::ColsAtCompileTime , Options = internal::traits<MatrixType>::Options , MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime ,
  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
}
 
typedef MatrixType_ MatrixType
 
typedef MatrixType::Scalar Scalar
 
typedef std::complex< typename NumTraits< Scalar >::RealComplexScalar
 
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. More...
 
template<typename InputType >
 RealSchur (const EigenBase< InputType > &matrix, bool computeU=true)
 Constructor; computes real Schur decomposition of given matrix. More...
 
const MatrixTypematrixU () const
 Returns the orthogonal matrix in the Schur decomposition. More...
 
const MatrixTypematrixT () const
 Returns the quasi-triangular matrix in the Schur decomposition. More...
 
template<typename InputType >
RealSchurcompute (const EigenBase< InputType > &matrix, bool computeU=true)
 Computes Schur decomposition of given matrix. More...
 
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. More...
 
ComputationInfo info () const
 Reports whether previous computation was successful. More...
 
RealSchursetMaxIterations (Index maxIters)
 Sets the maximum number of iterations allowed. More...
 
Index getMaxIterations ()
 Returns the maximum number of iterations. More...
 
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. More...
 

Private Types

typedef Matrix< Scalar, 3, 1 > Vector3s
 

Private Member Functions

Scalar computeNormOfT ()
 
Index findSmallSubdiagEntry (Index iu, const Scalar &considerAsZero)
 
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
MatrixType_the 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
Deprecated:
since Eigen 3.3

◆ 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 
61  {
62  RowsAtCompileTime = MatrixType::RowsAtCompileTime,
63  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
64  Options = internal::traits<MatrixType>::Options,
65  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
66  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
67  };
@ RowsAtCompileTime
Definition: RealSchur.h:62
@ ColsAtCompileTime
Definition: RealSchur.h:63
@ MaxRowsAtCompileTime
Definition: RealSchur.h:65
@ MaxColsAtCompileTime
Definition: RealSchur.h:66
@ Options
Definition: RealSchur.h:64

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.
87  : m_matT(size, size),
88  m_matU(size, size),
90  m_hess(size),
91  m_isInitialized(false),
92  m_matUisUptodate(false),
93  m_maxIters(-1) {}
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
bool m_matUisUptodate
Definition: RealSchur.h:226
MatrixType m_matU
Definition: RealSchur.h:221
ColumnVectorType m_workspaceVector
Definition: RealSchur.h:222
MatrixType m_matT
Definition: RealSchur.h:220
Index m_maxIters
Definition: RealSchur.h:227
HessenbergDecomposition< MatrixType > m_hess
Definition: RealSchur.h:223
bool m_isInitialized
Definition: RealSchur.h:225

◆ 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:

MatrixXd A = MatrixXd::Random(6, 6);
cout << "Here is a random 6x6 matrix, A:" << endl << A << endl << endl;
RealSchur<MatrixXd> schur(A);
cout << "The orthogonal matrix U is:" << endl << schur.matrixU() << endl;
cout << "The quasi-triangular matrix T is:" << endl << schur.matrixT() << endl << endl;
MatrixXd U = schur.matrixU();
MatrixXd T = schur.matrixT();
cout << "U * T * U^T = " << endl << U * T * U.transpose() << endl;
ComplexSchur< MatrixXcf > schur(4)
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53

Output:

 
107  : m_matT(matrix.rows(), matrix.cols()),
108  m_matU(matrix.rows(), matrix.cols()),
109  m_workspaceVector(matrix.rows()),
110  m_hess(matrix.rows()),
111  m_isInitialized(false),
112  m_matUisUptodate(false),
113  m_maxIters(-1) {
114  compute(matrix.derived(), computeU);
115  }
RealSchur & compute(const EigenBase< InputType > &matrix, bool computeU=true)
Computes Schur decomposition of given matrix.
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85

References Eigen::RealSchur< MatrixType_ >::compute(), and matrix().

Member Function Documentation

◆ compute() [1/2]

template<typename MatrixType_ >
template<typename InputType >
RealSchur<MatrixType>& Eigen::RealSchur< MatrixType_ >::compute ( const EigenBase< InputType > &  matrix,
bool  computeU 
)
242  {
243  const Scalar considerAsZero = (std::numeric_limits<Scalar>::min)();
244 
245  eigen_assert(matrix.cols() == matrix.rows());
246  Index maxIters = m_maxIters;
247  if (maxIters == -1) maxIters = m_maxIterationsPerRow * matrix.rows();
248 
249  Scalar scale = matrix.derived().cwiseAbs().maxCoeff();
250  if (scale < considerAsZero) {
251  m_matT.setZero(matrix.rows(), matrix.cols());
252  if (computeU) m_matU.setIdentity(matrix.rows(), matrix.cols());
253  m_info = Success;
254  m_isInitialized = true;
255  m_matUisUptodate = computeU;
256  return *this;
257  }
258 
259  // Step 1. Reduce to Hessenberg form
260  m_hess.compute(matrix.derived() / scale);
261 
262  // Step 2. Reduce to real Schur form
263  // Note: we copy m_hess.matrixQ() into m_matU here and not in computeFromHessenberg
264  // to be able to pass our working-space buffer for the Householder to Dense evaluation.
266  if (computeU) m_hess.matrixQ().evalTo(m_matU, m_workspaceVector);
268 
269  m_matT *= scale;
270 
271  return *this;
272 }
#define eigen_assert(x)
Definition: Macros.h:910
SCALAR Scalar
Definition: bench_gemm.cpp:45
HessenbergDecomposition & compute(const EigenBase< InputType > &matrix)
Computes Hessenberg decomposition of given matrix.
Definition: HessenbergDecomposition.h:147
MatrixHReturnType matrixH() const
Constructs the Hessenberg matrix H in the decomposition.
Definition: HessenbergDecomposition.h:250
HouseholderSequenceType matrixQ() const
Reconstructs the orthogonal matrix Q in the decomposition.
Definition: HessenbergDecomposition.h:225
EIGEN_DEVICE_FUNC void evalTo(DestType &dst) const
Definition: HouseholderSequence.h:253
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
RealSchur & computeFromHessenberg(const HessMatrixType &matrixH, const OrthMatrixType &matrixQ, bool computeU)
Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T.
static const int m_maxIterationsPerRow
Maximum number of iterations per row.
Definition: RealSchur.h:217
ComputationInfo m_info
Definition: RealSchur.h:224
Eigen::Index Index
Definition: RealSchur.h:70
#define min(a, b)
Definition: datatypes.h:22
@ Success
Definition: Constants.h:440

References eigen_assert, matrix(), min, and Eigen::Success.

◆ 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:

MatrixXf A = MatrixXf::Random(4, 4);
RealSchur<MatrixXf> schur(4);
schur.compute(A, /* computeU = */ false);
cout << "The matrix T in the decomposition of A is:" << endl << schur.matrixT() << endl;
schur.compute(A.inverse(), /* computeU = */ false);
cout << "The matrix T in the decomposition of A^(-1) is:" << endl << schur.matrixT() << endl;

Output:

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

Referenced by Eigen::RealSchur< MatrixType_ >::RealSchur(), and schur().

◆ 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 
)
276  {
277  using std::abs;
278 
279  m_matT = matrixH;
281  if (computeU && !internal::is_same_dense(m_matU, matrixQ)) m_matU = matrixQ;
282 
283  Index maxIters = m_maxIters;
284  if (maxIters == -1) maxIters = m_maxIterationsPerRow * matrixH.rows();
285  Scalar* workspace = &m_workspaceVector.coeffRef(0);
286 
287  // The matrix m_matT is divided in three parts.
288  // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
289  // Rows il,...,iu is the part we are working on (the active window).
290  // Rows iu+1,...,end are already brought in triangular form.
291  Index iu = m_matT.cols() - 1;
292  Index iter = 0; // iteration count for current eigenvalue
293  Index totalIter = 0; // iteration count for whole matrix
294  Scalar exshift(0); // sum of exceptional shifts
295  Scalar norm = computeNormOfT();
296  // sub-diagonal entries smaller than considerAsZero will be treated as zero.
297  // We use eps^2 to enable more precision in small eigenvalues.
298  Scalar considerAsZero =
299  numext::maxi<Scalar>(norm * numext::abs2(NumTraits<Scalar>::epsilon()), (std::numeric_limits<Scalar>::min)());
300 
301  if (!numext::is_exactly_zero(norm)) {
302  while (iu >= 0) {
303  Index il = findSmallSubdiagEntry(iu, considerAsZero);
304 
305  // Check for convergence
306  if (il == iu) // One root found
307  {
308  m_matT.coeffRef(iu, iu) = m_matT.coeff(iu, iu) + exshift;
309  if (iu > 0) m_matT.coeffRef(iu, iu - 1) = Scalar(0);
310  iu--;
311  iter = 0;
312  } else if (il == iu - 1) // Two roots found
313  {
314  splitOffTwoRows(iu, computeU, exshift);
315  iu -= 2;
316  iter = 0;
317  } else // No convergence yet
318  {
319  // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1
320  // -Wall -DNDEBUG )
321  Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo;
322  computeShift(iu, iter, exshift, shiftInfo);
323  iter = iter + 1;
324  totalIter = totalIter + 1;
325  if (totalIter > maxIters) break;
326  Index im;
327  initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
328  performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
329  }
330  }
331  }
332  if (totalIter <= maxIters)
333  m_info = Success;
334  else
336 
337  m_isInitialized = true;
338  m_matUisUptodate = computeU;
339  return *this;
340 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
Matrix< Scalar, 3, 1 > Vector3s
Definition: RealSchur.h:229
void initFrancisQRStep(Index il, Index iu, const Vector3s &shiftInfo, Index &im, Vector3s &firstHouseholderVector)
Definition: RealSchur.h:440
void computeShift(Index iu, Index iter, Scalar &exshift, Vector3s &shiftInfo)
Definition: RealSchur.h:404
void splitOffTwoRows(Index iu, bool computeU, const Scalar &exshift)
Definition: RealSchur.h:372
MatrixType::Scalar Scalar
Definition: RealSchur.h:68
Scalar computeNormOfT()
Definition: RealSchur.h:344
Index findSmallSubdiagEntry(Index iu, const Scalar &considerAsZero)
Definition: RealSchur.h:356
void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s &firstHouseholderVector, Scalar *workspace)
Definition: RealSchur.h:463
@ NoConvergence
Definition: Constants.h:444
EIGEN_DEVICE_FUNC bool is_same_dense(const T1 &mat1, const T2 &mat2, std::enable_if_t< possibly_same_dense< T1, T2 >::value > *=0)
Definition: XprHelper.h:869
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1102
double Zero
Definition: pseudosolid_node_update_elements.cc:35
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43

References abs(), Eigen::numext::abs2(), Eigen::numext::is_exactly_zero(), Eigen::internal::is_same_dense(), min, Eigen::NoConvergence, Eigen::Success, and oomph::PseudoSolidHelper::Zero.

◆ computeNormOfT()

template<typename MatrixType >
MatrixType::Scalar Eigen::RealSchur< MatrixType >::computeNormOfT
inlineprivate

Computes and returns vector L1 norm of T

344  {
345  const Index size = m_matT.cols();
346  // FIXME to be efficient the following would requires a triangular reduxion code
347  // Scalar norm = m_matT.upper().cwiseAbs().sum()
348  // + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
349  Scalar norm(0);
350  for (Index j = 0; j < size; ++j) norm += m_matT.col(j).segment(0, (std::min)(size, j + 2)).cwiseAbs().sum();
351  return norm;
352 }
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References j, min, and size.

◆ computeShift()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::computeShift ( Index  iu,
Index  iter,
Scalar exshift,
Vector3s shiftInfo 
)
inlineprivate

Form shift in shiftInfo, and update exshift if an exceptional shift is performed.

404  {
405  using std::abs;
406  using std::sqrt;
407  shiftInfo.coeffRef(0) = m_matT.coeff(iu, iu);
408  shiftInfo.coeffRef(1) = m_matT.coeff(iu - 1, iu - 1);
409  shiftInfo.coeffRef(2) = m_matT.coeff(iu, iu - 1) * m_matT.coeff(iu - 1, iu);
410 
411  // Alternate exceptional shifting strategy every 16 iterations.
412  if (iter % 16 == 0) {
413  // Wilkinson's original ad hoc shift
414  if (iter % 32 != 0) {
415  exshift += shiftInfo.coeff(0);
416  for (Index i = 0; i <= iu; ++i) m_matT.coeffRef(i, i) -= shiftInfo.coeff(0);
417  Scalar s = abs(m_matT.coeff(iu, iu - 1)) + abs(m_matT.coeff(iu - 1, iu - 2));
418  shiftInfo.coeffRef(0) = Scalar(0.75) * s;
419  shiftInfo.coeffRef(1) = Scalar(0.75) * s;
420  shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
421  } else {
422  // MATLAB's new ad hoc shift
423  Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
424  s = s * s + shiftInfo.coeff(2);
425  if (s > Scalar(0)) {
426  s = sqrt(s);
427  if (shiftInfo.coeff(1) < shiftInfo.coeff(0)) s = -s;
428  s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
429  s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
430  exshift += s;
431  for (Index i = 0; i <= iu; ++i) m_matT.coeffRef(i, i) -= s;
432  shiftInfo.setConstant(Scalar(0.964));
433  }
434  }
435  }
436 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
RealScalar s
Definition: level1_cplx_impl.h:130

References abs(), Eigen::PlainObjectBase< Derived >::coeff(), Eigen::Matrix< Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_ >::coeffRef(), i, s, Eigen::PlainObjectBase< Derived >::setConstant(), and sqrt().

◆ findSmallSubdiagEntry()

template<typename MatrixType >
Index Eigen::RealSchur< MatrixType >::findSmallSubdiagEntry ( Index  iu,
const Scalar considerAsZero 
)
inlineprivate

Look for single small sub-diagonal element and returns its index

356  {
357  using std::abs;
358  Index res = iu;
359  while (res > 0) {
360  Scalar s = abs(m_matT.coeff(res - 1, res - 1)) + abs(m_matT.coeff(res, res));
361 
362  s = numext::maxi<Scalar>(s * NumTraits<Scalar>::epsilon(), considerAsZero);
363 
364  if (abs(m_matT.coeff(res, res - 1)) <= s) break;
365  res--;
366  }
367  return res;
368 }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3

References abs(), res, and s.

◆ getMaxIterations()

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

Returns the maximum number of iterations.

210 { return m_maxIters; }

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

Referenced by Eigen::EigenSolver< MatrixType_ >::getMaxIterations(), and schur().

◆ info()

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

Reports whether previous computation was successful.

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

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

Referenced by schur().

◆ initFrancisQRStep()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::initFrancisQRStep ( Index  il,
Index  iu,
const Vector3s shiftInfo,
Index im,
Vector3s firstHouseholderVector 
)
inlineprivate

Compute index im at which Francis QR step starts and the first Householder vector.

441  {
442  using std::abs;
443  Vector3s& v = firstHouseholderVector; // alias to save typing
444 
445  for (im = iu - 2; im >= il; --im) {
446  const Scalar Tmm = m_matT.coeff(im, im);
447  const Scalar r = shiftInfo.coeff(0) - Tmm;
448  const Scalar s = shiftInfo.coeff(1) - Tmm;
449  v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im + 1, im) + m_matT.coeff(im, im + 1);
450  v.coeffRef(1) = m_matT.coeff(im + 1, im + 1) - Tmm - r - s;
451  v.coeffRef(2) = m_matT.coeff(im + 2, im + 1);
452  if (im == il) {
453  break;
454  }
455  const Scalar lhs = m_matT.coeff(im, im - 1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
456  const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im - 1, im - 1)) + abs(Tmm) + abs(m_matT.coeff(im + 1, im + 1)));
457  if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs) break;
458  }
459 }
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
r
Definition: UniformPSDSelfTest.py:20

References abs(), Eigen::PlainObjectBase< Derived >::coeff(), oomph::SarahBL::epsilon, UniformPSDSelfTest::r, s, and v.

◆ 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
144  {
145  eigen_assert(m_isInitialized && "RealSchur is not initialized.");
146  return m_matT;
147  }

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

Referenced by schur(), and Eigen::DGMRES< MatrixType_, Preconditioner_ >::schurValues().

◆ 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.

Referenced by schur().

◆ performFrancisQRStep()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::performFrancisQRStep ( Index  il,
Index  im,
Index  iu,
bool  computeU,
const Vector3s firstHouseholderVector,
Scalar workspace 
)
inlineprivate

Perform a Francis QR step involving rows il:iu and columns im:iu.

464  {
465  eigen_assert(im >= il);
466  eigen_assert(im <= iu - 2);
467 
468  const Index size = m_matT.cols();
469 
470  for (Index k = im; k <= iu - 2; ++k) {
471  bool firstIteration = (k == im);
472 
473  Vector3s v;
474  if (firstIteration)
475  v = firstHouseholderVector;
476  else
477  v = m_matT.template block<3, 1>(k, k - 1);
478 
479  Scalar tau, beta;
480  Matrix<Scalar, 2, 1> ess;
481  v.makeHouseholder(ess, tau, beta);
482 
483  if (!numext::is_exactly_zero(beta)) // if v is not zero
484  {
485  if (firstIteration && k > il)
486  m_matT.coeffRef(k, k - 1) = -m_matT.coeff(k, k - 1);
487  else if (!firstIteration)
488  m_matT.coeffRef(k, k - 1) = beta;
489 
490  // These Householder transformations form the O(n^3) part of the algorithm
491  m_matT.block(k, k, 3, size - k).applyHouseholderOnTheLeft(ess, tau, workspace);
492  m_matT.block(0, k, (std::min)(iu, k + 3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace);
493  if (computeU) m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
494  }
495  }
496 
497  Matrix<Scalar, 2, 1> v = m_matT.template block<2, 1>(iu - 1, iu - 2);
498  Scalar tau, beta;
499  Matrix<Scalar, 1, 1> ess;
500  v.makeHouseholder(ess, tau, beta);
501 
502  if (!numext::is_exactly_zero(beta)) // if v is not zero
503  {
504  m_matT.coeffRef(iu - 1, iu - 2) = beta;
505  m_matT.block(iu - 1, iu - 1, 2, size - iu + 1).applyHouseholderOnTheLeft(ess, tau, workspace);
506  m_matT.block(0, iu - 1, iu + 1, 2).applyHouseholderOnTheRight(ess, tau, workspace);
507  if (computeU) m_matU.block(0, iu - 1, size, 2).applyHouseholderOnTheRight(ess, tau, workspace);
508  }
509 
510  // clean up pollution due to round-off errors
511  for (Index i = im + 2; i <= iu; ++i) {
512  m_matT.coeffRef(i, i - 2) = Scalar(0);
513  if (i > im + 2) m_matT.coeffRef(i, i - 3) = Scalar(0);
514  }
515 }
Scalar beta
Definition: level2_cplx_impl.h:36
char char char int int * k
Definition: level2_impl.h:374
float ess
Definition: calibrate.py:183

References beta, eigen_assert, calibrate::ess, i, Eigen::numext::is_exactly_zero(), k, min, size, and v.

◆ 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.

204  {
205  m_maxIters = maxIters;
206  return *this;
207  }

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

Referenced by schur(), and Eigen::EigenSolver< MatrixType_ >::setMaxIterations().

◆ splitOffTwoRows()

template<typename MatrixType >
void Eigen::RealSchur< MatrixType >::splitOffTwoRows ( Index  iu,
bool  computeU,
const Scalar exshift 
)
inlineprivate

Update T given that rows iu-1 and iu decouple from the rest.

372  {
373  using std::abs;
374  using std::sqrt;
375  const Index size = m_matT.cols();
376 
377  // The eigenvalues of the 2x2 matrix [a b; c d] are
378  // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
379  Scalar p = Scalar(0.5) * (m_matT.coeff(iu - 1, iu - 1) - m_matT.coeff(iu, iu));
380  Scalar q = p * p + m_matT.coeff(iu, iu - 1) * m_matT.coeff(iu - 1, iu); // q = tr^2 / 4 - det = discr/4
381  m_matT.coeffRef(iu, iu) += exshift;
382  m_matT.coeffRef(iu - 1, iu - 1) += exshift;
383 
384  if (q >= Scalar(0)) // Two real eigenvalues
385  {
386  Scalar z = sqrt(abs(q));
387  JacobiRotation<Scalar> rot;
388  if (p >= Scalar(0))
389  rot.makeGivens(p + z, m_matT.coeff(iu, iu - 1));
390  else
391  rot.makeGivens(p - z, m_matT.coeff(iu, iu - 1));
392 
393  m_matT.rightCols(size - iu + 1).applyOnTheLeft(iu - 1, iu, rot.adjoint());
394  m_matT.topRows(iu + 1).applyOnTheRight(iu - 1, iu, rot);
395  m_matT.coeffRef(iu, iu - 1) = Scalar(0);
396  if (computeU) m_matU.applyOnTheRight(iu - 1, iu, rot);
397  }
398 
399  if (iu > 1) m_matT.coeffRef(iu - 1, iu - 2) = Scalar(0);
400 }
float * p
Definition: Tutorial_Map_using.cpp:9
EIGEN_BLAS_FUNC() rot(int *n, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pc, Scalar *ps)
Definition: level1_real_impl.h:88
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019

References abs(), p, Eigen::numext::q, rot(), size, and sqrt().

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: