11 #ifndef EIGEN_REAL_SCHUR_H
12 #define EIGEN_REAL_SCHUR_H
57 template <
typename MatrixType_>
105 template <
typename InputType>
168 template <
typename InputType>
188 template <
typename HessMatrixType,
typename OrthMatrixType>
240 template <
typename MatrixType>
241 template <
typename InputType>
246 Index maxIters = m_maxIters;
247 if (maxIters == -1) maxIters = m_maxIterationsPerRow *
matrix.rows();
250 if (scale < considerAsZero) {
252 if (computeU) m_matU.setIdentity(
matrix.rows(),
matrix.cols());
254 m_isInitialized =
true;
255 m_matUisUptodate = computeU;
260 m_hess.compute(
matrix.derived() / scale);
265 m_workspaceVector.resize(
matrix.cols());
266 if (computeU) m_hess.matrixQ().evalTo(m_matU, m_workspaceVector);
267 computeFromHessenberg(m_hess.matrixH(), m_matU, computeU);
273 template <
typename MatrixType>
274 template <
typename HessMatrixType,
typename OrthMatrixType>
276 const OrthMatrixType& matrixQ,
bool computeU) {
280 m_workspaceVector.resize(m_matT.cols());
283 Index maxIters = m_maxIters;
284 if (maxIters == -1) maxIters = m_maxIterationsPerRow * matrixH.rows();
285 Scalar* workspace = &m_workspaceVector.coeffRef(0);
291 Index iu = m_matT.cols() - 1;
295 Scalar norm = computeNormOfT();
303 Index il = findSmallSubdiagEntry(iu, considerAsZero);
308 m_matT.coeffRef(iu, iu) = m_matT.coeff(iu, iu) + exshift;
309 if (iu > 0) m_matT.coeffRef(iu, iu - 1) =
Scalar(0);
312 }
else if (il == iu - 1)
314 splitOffTwoRows(iu, computeU, exshift);
322 computeShift(iu, iter, exshift, shiftInfo);
324 totalIter = totalIter + 1;
325 if (totalIter > maxIters)
break;
327 initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
328 performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
332 if (totalIter <= maxIters)
337 m_isInitialized =
true;
338 m_matUisUptodate = computeU;
343 template <
typename MatrixType>
355 template <
typename MatrixType>
364 if (
abs(m_matT.coeff(
res,
res - 1)) <=
s)
break;
371 template <
typename MatrixType>
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);
381 m_matT.coeffRef(iu, iu) += exshift;
382 m_matT.coeffRef(iu - 1, iu - 1) += exshift;
389 rot.makeGivens(
p + z, m_matT.coeff(iu, iu - 1));
391 rot.makeGivens(
p - z, m_matT.coeff(iu, iu - 1));
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);
399 if (iu > 1) m_matT.coeffRef(iu - 1, iu - 2) =
Scalar(0);
403 template <
typename MatrixType>
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);
412 if (iter % 16 == 0) {
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));
431 for (
Index i = 0;
i <= iu; ++
i) m_matT.coeffRef(
i,
i) -=
s;
439 template <
typename MatrixType>
445 for (im = iu - 2; im >= il; --im) {
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);
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)));
462 template <
typename MatrixType>
470 for (
Index k = im;
k <= iu - 2; ++
k) {
471 bool firstIteration = (
k == im);
475 v = firstHouseholderVector;
477 v = m_matT.template block<3, 1>(
k,
k - 1);
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;
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);
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);
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);
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 100 >, boost::multiprecision::et_on > Real
Definition: boostmultiprec.cpp:77
Rotation given by a cosine-sine pair.
Definition: Jacobi.h:38
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:198
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
Definition: CwiseNullaryOp.h:365
Performs a real Schur decomposition of a square matrix.
Definition: RealSchur.h:58
RealSchur & setMaxIterations(Index maxIters)
Sets the maximum number of iterations allowed.
Definition: RealSchur.h:204
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
Definition: RealSchur.h:69
const MatrixType & matrixU() const
Returns the orthogonal matrix in the Schur decomposition.
Definition: RealSchur.h:128
RealSchur & computeFromHessenberg(const HessMatrixType &matrixH, const OrthMatrixType &matrixQ, bool computeU)
Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T.
Matrix< Scalar, 3, 1 > Vector3s
Definition: RealSchur.h:229
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: RealSchur.h:194
Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > EigenvalueType
Definition: RealSchur.h:72
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
bool m_matUisUptodate
Definition: RealSchur.h:226
Index getMaxIterations()
Returns the maximum number of iterations.
Definition: RealSchur.h:210
void splitOffTwoRows(Index iu, bool computeU, const Scalar &exshift)
Definition: RealSchur.h:372
MatrixType::Scalar Scalar
Definition: RealSchur.h:68
RealSchur(Index size=RowsAtCompileTime==Dynamic ? 1 :RowsAtCompileTime)
Default constructor.
Definition: RealSchur.h:86
MatrixType m_matU
Definition: RealSchur.h:221
ColumnVectorType m_workspaceVector
Definition: RealSchur.h:222
Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ColumnVectorType
Definition: RealSchur.h:73
MatrixType m_matT
Definition: RealSchur.h:220
RealSchur(const EigenBase< InputType > &matrix, bool computeU=true)
Constructor; computes real Schur decomposition of given matrix.
Definition: RealSchur.h:106
Index m_maxIters
Definition: RealSchur.h:227
static const int m_maxIterationsPerRow
Maximum number of iterations per row.
Definition: RealSchur.h:217
const MatrixType & matrixT() const
Returns the quasi-triangular matrix in the Schur decomposition.
Definition: RealSchur.h:144
Scalar computeNormOfT()
Definition: RealSchur.h:344
ComputationInfo m_info
Definition: RealSchur.h:224
RealSchur & compute(const EigenBase< InputType > &matrix, bool computeU=true)
Computes Schur decomposition of given matrix.
HessenbergDecomposition< MatrixType > m_hess
Definition: RealSchur.h:223
Index findSmallSubdiagEntry(Index iu, const Scalar &considerAsZero)
Definition: RealSchur.h:356
bool m_isInitialized
Definition: RealSchur.h:225
MatrixType_ MatrixType
Definition: RealSchur.h:60
Eigen::Index Index
Definition: RealSchur.h:70
void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s &firstHouseholderVector, Scalar *workspace)
Definition: RealSchur.h:463
@ 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
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
#define min(a, b)
Definition: datatypes.h:22
ComputationInfo
Definition: Constants.h:438
@ Success
Definition: Constants.h:440
@ NoConvergence
Definition: Constants.h:444
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_BLAS_FUNC() rot(int *n, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pc, Scalar *ps)
Definition: level1_real_impl.h:88
Scalar beta
Definition: level2_cplx_impl.h:36
char char char int int * k
Definition: level2_impl.h:374
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 const Scalar & q
Definition: SpecialFunctionsImpl.h:2019
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1102
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const int Dynamic
Definition: Constants.h:25
float ess
Definition: calibrate.py:183
double Zero
Definition: pseudosolid_node_update_elements.cc:35
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
Definition: EigenBase.h:33
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: ForwardDeclarations.h:21
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2