11 #ifndef EIGEN_SELFADJOINTEIGENSOLVER_H
12 #define EIGEN_SELFADJOINTEIGENSOLVER_H
18 template<
typename _MatrixType>
19 class GeneralizedSelfAdjointEigenSolver;
23 template<
typename MatrixType,
typename DiagType,
typename SubDiagType>
76 Size = MatrixType::RowsAtCompileTime,
160 template<
typename InputType>
201 template<
typename InputType>
391 template<
int StorageOrder,
typename RealScalar,
typename Scalar,
typename Index>
396 template<
typename MatrixType>
397 template<
typename InputType>
402 check_template_parameters();
410 &&
"invalid option parameter");
413 m_eivalues.resize(
n,1);
418 m_eivalues.coeffRef(0,0) =
numext::real(m_eivec.coeff(0,0));
419 if(computeEigenvectors)
420 m_eivec.setOnes(
n,
n);
422 m_isInitialized =
true;
423 m_eigenvectorsOk = computeEigenvectors;
436 m_subdiag.resize(
n-1);
444 m_isInitialized =
true;
445 m_eigenvectorsOk = computeEigenvectors;
449 template<
typename MatrixType>
458 if (computeEigenvectors)
460 m_eivec.setIdentity(diag.size(), diag.size());
464 m_isInitialized =
true;
465 m_eigenvectorsOk = computeEigenvectors;
481 template<
typename MatrixType,
typename DiagType,
typename SubDiagType>
500 for (
Index i = start; i<end; ++i)
505 while (end>0 && subdiag[end-1]==
RealScalar(0))
514 if(iter > maxIterations *
n)
break;
517 while (start>0 && subdiag[start-1]!=0)
520 internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), subdiag.data(), start, end, computeEigenvectors ? eivec.data() : (
Scalar*)0,
n);
522 if (iter <= maxIterations *
n)
532 for (
Index i = 0; i <
n-1; ++i)
535 diag.segment(i,
n-i).minCoeff(&k);
539 if(computeEigenvectors)
540 eivec.col(i).swap(eivec.col(k+i));
547 template<
typename SolverType,
int Size,
bool IsComplex>
struct direct_selfadjoint_eigenvalues
551 {
eig.compute(
A,options); }
569 EIGEN_USING_STD_MATH(
sqrt)
570 EIGEN_USING_STD_MATH(
atan2)
571 EIGEN_USING_STD_MATH(
cos)
572 EIGEN_USING_STD_MATH(
sin)
579 Scalar c0 = m(0,0)*m(1,1)*m(2,2) +
Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0);
580 Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1);
581 Scalar c2 = m(0,0) + m(1,1) + m(2,2);
585 Scalar c2_over_3 = c2*s_inv3;
586 Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3;
591 Scalar q = a_over_3*a_over_3*a_over_3 - half_b*half_b;
600 roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta);
601 roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta);
602 roots(2) = c2_over_3 +
Scalar(2)*rho*cos_theta;
611 mat.diagonal().cwiseAbs().maxCoeff(&i0);
614 representative =
mat.col(i0);
617 n0 = (c0 = representative.cross(
mat.col((i0+1)%3))).squaredNorm();
618 n1 = (c1 = representative.cross(
mat.col((i0+2)%3))).squaredNorm();
631 &&
"invalid option parameter");
640 MatrixType scaledMat =
mat.template selfadjointView<Lower>();
641 scaledMat.diagonal().array() -= shift;
642 Scalar scale = scaledMat.cwiseAbs().maxCoeff();
643 if(scale > 0) scaledMat /= scale;
646 computeRoots(scaledMat,eivals);
649 if(computeEigenvectors)
654 eivecs.setIdentity();
662 Scalar d0 = eivals(2) - eivals(1);
663 Scalar d1 = eivals(1) - eivals(0);
673 tmp.diagonal().array () -= eivals(k);
675 extract_kernel(tmp, eivecs.col(k), eivecs.col(l));
683 eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l);
684 eivecs.col(l).normalize();
689 tmp.diagonal().array () -= eivals(l);
692 extract_kernel(tmp, eivecs.col(l), dummy);
696 eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized();
702 eivals.array() += shift;
705 solver.m_isInitialized =
true;
706 solver.m_eigenvectorsOk = computeEigenvectors;
711 template<
typename SolverType>
732 EIGEN_USING_STD_MATH(
sqrt);
733 EIGEN_USING_STD_MATH(
abs);
738 &&
"invalid option parameter");
747 scaledMat.coeffRef(0,1) =
mat.coeff(1,0);
748 scaledMat.diagonal().array() -= shift;
749 Scalar scale = scaledMat.cwiseAbs().maxCoeff();
754 computeRoots(scaledMat,eivals);
757 if(computeEigenvectors)
761 eivecs.setIdentity();
765 scaledMat.diagonal().array () -= eivals(1);
771 eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
772 eivecs.col(1) /=
sqrt(a2+b2);
776 eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);
777 eivecs.col(1) /=
sqrt(c2+b2);
780 eivecs.col(0) << eivecs.col(1).unitOrthogonal();
786 eivals.array() += shift;
789 solver.m_isInitialized =
true;
790 solver.m_eigenvectorsOk = computeEigenvectors;
796 template<
typename MatrixType>
806 template<
int StorageOrder,
typename RealScalar,
typename Scalar,
typename Index>
826 else mu -= e2 / (td + (td>
RealScalar(0) ? h : -h));
831 for (
Index k = start; k < end; ++k)
834 rot.makeGivens(
x, z);
840 diag[k] =
rot.c() * (
rot.c() * diag[k] -
rot.s() * subdiag[k]) -
rot.s() * (
rot.c() * subdiag[k] -
rot.s() * diag[k+1]);
841 diag[k+1] =
rot.s() * sdk +
rot.c() * dkp1;
842 subdiag[k] =
rot.c() * sdk -
rot.s() * dkp1;
846 subdiag[k - 1] =
rot.c() * subdiag[k-1] -
rot.s() * z;
852 z = -
rot.s() * subdiag[k+1];
853 subdiag[k + 1] =
rot.c() * subdiag[k+1];
861 q.applyOnTheRight(k,k+1,
rot);
870 #endif // EIGEN_SELFADJOINTEIGENSOLVER_H