11 #ifndef EIGEN_REAL_SCHUR_H
12 #define EIGEN_REAL_SCHUR_H
103 template<
typename InputType>
169 template<
typename InputType>
189 template<
typename HessMatrixType,
typename OrthMatrixType>
247 template<
typename MatrixType>
248 template<
typename InputType>
254 Index maxIters = m_maxIters;
256 maxIters = m_maxIterationsPerRow *
matrix.rows();
259 if(scale<considerAsZero)
265 m_isInitialized =
true;
266 m_matUisUptodate = computeU;
271 m_hess.compute(
matrix.derived()/scale);
274 computeFromHessenberg(m_hess.matrixH(), m_hess.matrixQ(), computeU);
280 template<
typename MatrixType>
281 template<
typename HessMatrixType,
typename OrthMatrixType>
290 Index maxIters = m_maxIters;
292 maxIters = m_maxIterationsPerRow * matrixH.rows();
293 m_workspaceVector.resize(m_matT.cols());
294 Scalar* workspace = &m_workspaceVector.coeffRef(0);
300 Index iu = m_matT.cols() - 1;
304 Scalar norm = computeNormOfT();
310 Index il = findSmallSubdiagEntry(iu);
315 m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
317 m_matT.coeffRef(iu, iu-1) =
Scalar(0);
323 splitOffTwoRows(iu, computeU, exshift);
330 Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo;
331 computeShift(iu, iter, exshift, shiftInfo);
333 totalIter = totalIter + 1;
334 if (totalIter > maxIters)
break;
336 initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
337 performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
341 if(totalIter <= maxIters)
346 m_isInitialized =
true;
347 m_matUisUptodate = computeU;
352 template<
typename MatrixType>
361 norm += m_matT.col(j).segment(0, (
std::min)(
size,j+2)).cwiseAbs().sum();
366 template<
typename MatrixType>
373 Scalar s =
abs(m_matT.coeff(res-1,res-1)) +
abs(m_matT.coeff(res,res));
382 template<
typename MatrixType>
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);
393 m_matT.coeffRef(iu,iu) += exshift;
394 m_matT.coeffRef(iu-1,iu-1) += exshift;
401 rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
403 rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
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);
409 m_matU.applyOnTheRight(iu-1, iu,
rot);
413 m_matT.coeffRef(iu-1, iu-2) =
Scalar(0);
417 template<
typename MatrixType>
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);
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));
451 for (
Index i = 0; i <= iu; ++i)
452 m_matT.coeffRef(i,i) -=
s;
459 template<
typename MatrixType>
463 Vector3s& v = firstHouseholderVector;
465 for (im = iu-2; im >= il; --im)
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);
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)));
484 template<
typename MatrixType>
492 for (
Index k = im; k <= iu-2; ++k)
494 bool firstIteration = (k == im);
498 v = firstHouseholderVector;
500 v = m_matT.template block<3,1>(k,k-1);
504 v.makeHouseholder(ess, tau, beta);
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;
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);
517 m_matU.block(0, k,
size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
524 v.makeHouseholder(ess, tau, 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);
532 m_matU.block(0, iu-1,
size, 2).applyHouseholderOnTheRight(ess, tau, workspace);
536 for (
Index i = im+2; i <= iu; ++i)
538 m_matT.coeffRef(i,i-2) =
Scalar(0);
540 m_matT.coeffRef(i,i-3) =
Scalar(0);
546 #endif // EIGEN_REAL_SCHUR_H