SelfAdjointEigenSolver.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_SELFADJOINTEIGENSOLVER_H
12 #define EIGEN_SELFADJOINTEIGENSOLVER_H
13 
14 #include "./Tridiagonalization.h"
15 
16 // IWYU pragma: private
17 #include "./InternalHeaderCheck.h"
18 
19 namespace Eigen {
20 
21 template <typename MatrixType_>
22 class GeneralizedSelfAdjointEigenSolver;
23 
24 namespace internal {
25 template <typename SolverType, int Size, bool IsComplex>
26 struct direct_selfadjoint_eigenvalues;
27 
28 template <typename MatrixType, typename DiagType, typename SubDiagType>
30  const Index maxIterations, bool computeEigenvectors,
31  MatrixType& eivec);
32 } // namespace internal
33 
81 template <typename MatrixType_>
83  public:
84  typedef MatrixType_ MatrixType;
85  enum {
86  Size = MatrixType::RowsAtCompileTime,
87  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
89  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
90  };
91 
93  typedef typename MatrixType::Scalar Scalar;
94  typedef Eigen::Index Index;
95 
97 
105 
107 
113  typedef typename internal::plain_col_type<MatrixType, Scalar>::type VectorType;
114  typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVectorType;
117 
129  : m_eivec(),
130  m_workspace(),
131  m_eivalues(),
132  m_subdiag(),
133  m_hcoeffs(),
134  m_info(InvalidInput),
135  m_isInitialized(false),
136  m_eigenvectorsOk(false) {}
137 
151  : m_eivec(size, size),
152  m_workspace(size),
153  m_eivalues(size),
154  m_subdiag(size > 1 ? size - 1 : 1),
155  m_hcoeffs(size > 1 ? size - 1 : 1),
156  m_isInitialized(false),
157  m_eigenvectorsOk(false) {}
158 
174  template <typename InputType>
176  int options = ComputeEigenvectors)
177  : m_eivec(matrix.rows(), matrix.cols()),
180  m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1),
181  m_hcoeffs(matrix.cols() > 1 ? matrix.cols() - 1 : 1),
182  m_isInitialized(false),
183  m_eigenvectorsOk(false) {
184  compute(matrix.derived(), options);
185  }
186 
217  template <typename InputType>
219  int options = ComputeEigenvectors);
220 
240 
254  int options = ComputeEigenvectors);
255 
280  eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
281  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
282  return m_eivec;
283  }
284 
301  eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
302  return m_eivalues;
303  }
304 
323  eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
324  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
325  return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint();
326  }
327 
347  eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
348  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
349  return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint();
350  }
351 
357  eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
358  return m_info;
359  }
360 
366  static const int m_maxIterations = 30;
367 
368  protected:
370 
375  typename TridiagonalizationType::CoeffVectorType m_hcoeffs;
379 };
380 
381 namespace internal {
402 template <int StorageOrder, typename RealScalar, typename Scalar, typename Index>
404  Scalar* matrixQ, Index n);
405 } // namespace internal
406 
407 template <typename MatrixType>
408 template <typename InputType>
410  const EigenBase<InputType>& a_matrix, int options) {
411  const InputType& matrix(a_matrix.derived());
412 
414  eigen_assert(matrix.cols() == matrix.rows());
415  eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
416  "invalid option parameter");
417  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;
418  Index n = matrix.cols();
419  m_eivalues.resize(n, 1);
420 
421  if (n == 1) {
422  m_eivec = matrix;
423  m_eivalues.coeffRef(0, 0) = numext::real(m_eivec.coeff(0, 0));
424  if (computeEigenvectors) m_eivec.setOnes(n, n);
425  m_info = Success;
426  m_isInitialized = true;
427  m_eigenvectorsOk = computeEigenvectors;
428  return *this;
429  }
430 
431  // declare some aliases
434 
435  // map the matrix coefficients to [-1:1] to avoid over- and underflow.
436  mat = matrix.template triangularView<Lower>();
437  RealScalar scale = mat.cwiseAbs().maxCoeff();
438  if (numext::is_exactly_zero(scale)) scale = RealScalar(1);
439  mat.template triangularView<Lower>() /= scale;
440  m_subdiag.resize(n - 1);
441  m_hcoeffs.resize(n - 1);
443 
445 
446  // scale back the eigen values
447  m_eivalues *= scale;
448 
449  m_isInitialized = true;
450  m_eigenvectorsOk = computeEigenvectors;
451  return *this;
452 }
453 
454 template <typename MatrixType>
456  const RealVectorType& diag, const SubDiagonalType& subdiag, int options) {
457  // TODO : Add an option to scale the values beforehand
458  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;
459 
460  m_eivalues = diag;
461  m_subdiag = subdiag;
462  if (computeEigenvectors) {
463  m_eivec.setIdentity(diag.size(), diag.size());
464  }
466 
467  m_isInitialized = true;
468  m_eigenvectorsOk = computeEigenvectors;
469  return *this;
470 }
471 
472 namespace internal {
484 template <typename MatrixType, typename DiagType, typename SubDiagType>
486  const Index maxIterations, bool computeEigenvectors,
487  MatrixType& eivec) {
489  typedef typename MatrixType::Scalar Scalar;
490 
491  Index n = diag.size();
492  Index end = n - 1;
493  Index start = 0;
494  Index iter = 0; // total number of iterations
495 
496  typedef typename DiagType::RealScalar RealScalar;
497  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
498  const RealScalar precision_inv = RealScalar(1) / NumTraits<RealScalar>::epsilon();
499  while (end > 0) {
500  for (Index i = start; i < end; ++i) {
501  if (numext::abs(subdiag[i]) < considerAsZero) {
502  subdiag[i] = RealScalar(0);
503  } else {
504  // abs(subdiag[i]) <= epsilon * sqrt(abs(diag[i]) + abs(diag[i+1]))
505  // Scaled to prevent underflows.
506  const RealScalar scaled_subdiag = precision_inv * subdiag[i];
507  if (scaled_subdiag * scaled_subdiag <= (numext::abs(diag[i]) + numext::abs(diag[i + 1]))) {
508  subdiag[i] = RealScalar(0);
509  }
510  }
511  }
512 
513  // find the largest unreduced block at the end of the matrix.
514  while (end > 0 && numext::is_exactly_zero(subdiag[end - 1])) {
515  end--;
516  }
517  if (end <= 0) break;
518 
519  // if we spent too many iterations, we give up
520  iter++;
521  if (iter > maxIterations * n) break;
522 
523  start = end - 1;
524  while (start > 0 && !numext::is_exactly_zero(subdiag[start - 1])) start--;
525 
526  internal::tridiagonal_qr_step<MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor>(
527  diag.data(), subdiag.data(), start, end, computeEigenvectors ? eivec.data() : (Scalar*)0, n);
528  }
529  if (iter <= maxIterations * n)
530  info = Success;
531  else
533 
534  // Sort eigenvalues and corresponding vectors.
535  // TODO make the sort optional ?
536  // TODO use a better sort algorithm !!
537  if (info == Success) {
538  for (Index i = 0; i < n - 1; ++i) {
539  Index k;
540  diag.segment(i, n - i).minCoeff(&k);
541  if (k > 0) {
542  numext::swap(diag[i], diag[k + i]);
543  if (computeEigenvectors) eivec.col(i).swap(eivec.col(k + i));
544  }
545  }
546  }
547  return info;
548 }
549 
550 template <typename SolverType, int Size, bool IsComplex>
552  EIGEN_DEVICE_FUNC static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) {
553  eig.compute(A, options);
554  }
555 };
556 
557 template <typename SolverType>
558 struct direct_selfadjoint_eigenvalues<SolverType, 3, false> {
560  typedef typename SolverType::RealVectorType VectorType;
561  typedef typename SolverType::Scalar Scalar;
562  typedef typename SolverType::EigenvectorsType EigenvectorsType;
563 
568  EIGEN_DEVICE_FUNC static inline void computeRoots(const MatrixType& m, VectorType& roots) {
573  const Scalar s_inv3 = Scalar(1) / Scalar(3);
574  const Scalar s_sqrt3 = sqrt(Scalar(3));
575 
576  // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The
577  // eigenvalues are the roots to this equation, all guaranteed to be
578  // real-valued, because the matrix is symmetric.
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) -
580  m(1, 1) * m(2, 0) * m(2, 0) - m(2, 2) * m(1, 0) * m(1, 0);
581  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) -
582  m(2, 1) * m(2, 1);
583  Scalar c2 = m(0, 0) + m(1, 1) + m(2, 2);
584 
585  // Construct the parameters used in classifying the roots of the equation
586  // and in solving the equation for the roots in closed form.
587  Scalar c2_over_3 = c2 * s_inv3;
588  Scalar a_over_3 = (c2 * c2_over_3 - c1) * s_inv3;
589  a_over_3 = numext::maxi(a_over_3, Scalar(0));
590 
591  Scalar half_b = Scalar(0.5) * (c0 + c2_over_3 * (Scalar(2) * c2_over_3 * c2_over_3 - c1));
592 
593  Scalar q = a_over_3 * a_over_3 * a_over_3 - half_b * half_b;
594  q = numext::maxi(q, Scalar(0));
595 
596  // Compute the eigenvalues by solving for the roots of the polynomial.
597  Scalar rho = sqrt(a_over_3);
598  Scalar theta = atan2(sqrt(q), half_b) * s_inv3; // since sqrt(q) > 0, atan2 is in [0, pi] and theta is in [0, pi/3]
599  Scalar cos_theta = cos(theta);
600  Scalar sin_theta = sin(theta);
601  // roots are already sorted, since cos is monotonically decreasing on [0, pi]
602  roots(0) = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta); // == 2*rho*cos(theta+2pi/3)
603  roots(1) = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta); // == 2*rho*cos(theta+ pi/3)
604  roots(2) = c2_over_3 + Scalar(2) * rho * cos_theta;
605  }
606 
608  Ref<VectorType> representative) {
611  Index i0;
612  // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal):
613  mat.diagonal().cwiseAbs().maxCoeff(&i0);
614  // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector,
615  // so let's save it:
616  representative = mat.col(i0);
617  Scalar n0, n1;
618  VectorType c0, c1;
619  n0 = (c0 = representative.cross(mat.col((i0 + 1) % 3))).squaredNorm();
620  n1 = (c1 = representative.cross(mat.col((i0 + 2) % 3))).squaredNorm();
621  if (n0 > n1)
622  res = c0 / sqrt(n0);
623  else
624  res = c1 / sqrt(n1);
625 
626  return true;
627  }
628 
629  EIGEN_DEVICE_FUNC static inline void run(SolverType& solver, const MatrixType& mat, int options) {
630  eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows());
631  eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
632  "invalid option parameter");
633  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;
634 
635  EigenvectorsType& eivecs = solver.m_eivec;
636  VectorType& eivals = solver.m_eivalues;
637 
638  // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
639  Scalar shift = mat.trace() / Scalar(3);
640  // TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for
641  // computing the eigenvectors later
642  MatrixType scaledMat = mat.template selfadjointView<Lower>();
643  scaledMat.diagonal().array() -= shift;
644  Scalar scale = scaledMat.cwiseAbs().maxCoeff();
645  if (scale > 0) scaledMat /= scale; // TODO for scale==0 we could save the remaining operations
646 
647  // compute the eigenvalues
648  computeRoots(scaledMat, eivals);
649 
650  // compute the eigenvectors
651  if (computeEigenvectors) {
652  if ((eivals(2) - eivals(0)) <= Eigen::NumTraits<Scalar>::epsilon()) {
653  // All three eigenvalues are numerically the same
654  eivecs.setIdentity();
655  } else {
656  MatrixType tmp;
657  tmp = scaledMat;
658 
659  // Compute the eigenvector of the most distinct eigenvalue
660  Scalar d0 = eivals(2) - eivals(1);
661  Scalar d1 = eivals(1) - eivals(0);
662  Index k(0), l(2);
663  if (d0 > d1) {
664  numext::swap(k, l);
665  d0 = d1;
666  }
667 
668  // Compute the eigenvector of index k
669  {
670  tmp.diagonal().array() -= eivals(k);
671  // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector.
672  extract_kernel(tmp, eivecs.col(k), eivecs.col(l));
673  }
674 
675  // Compute eigenvector of index l
676  if (d0 <= 2 * Eigen::NumTraits<Scalar>::epsilon() * d1) {
677  // If d0 is too small, then the two other eigenvalues are numerically the same,
678  // and thus we only have to ortho-normalize the near orthogonal vector we saved above.
679  eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l)) * eivecs.col(l);
680  eivecs.col(l).normalize();
681  } else {
682  tmp = scaledMat;
683  tmp.diagonal().array() -= eivals(l);
684 
685  VectorType dummy;
686  extract_kernel(tmp, eivecs.col(l), dummy);
687  }
688 
689  // Compute last eigenvector from the other two
690  eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized();
691  }
692  }
693 
694  // Rescale back to the original size.
695  eivals *= scale;
696  eivals.array() += shift;
697 
698  solver.m_info = Success;
699  solver.m_isInitialized = true;
700  solver.m_eigenvectorsOk = computeEigenvectors;
701  }
702 };
703 
704 // 2x2 direct eigenvalues decomposition, code from Hauke Heibel
705 template <typename SolverType>
706 struct direct_selfadjoint_eigenvalues<SolverType, 2, false> {
708  typedef typename SolverType::RealVectorType VectorType;
709  typedef typename SolverType::Scalar Scalar;
710  typedef typename SolverType::EigenvectorsType EigenvectorsType;
711 
712  EIGEN_DEVICE_FUNC static inline void computeRoots(const MatrixType& m, VectorType& roots) {
714  const Scalar t0 = Scalar(0.5) * sqrt(numext::abs2(m(0, 0) - m(1, 1)) + Scalar(4) * numext::abs2(m(1, 0)));
715  const Scalar t1 = Scalar(0.5) * (m(0, 0) + m(1, 1));
716  roots(0) = t1 - t0;
717  roots(1) = t1 + t0;
718  }
719 
720  EIGEN_DEVICE_FUNC static inline void run(SolverType& solver, const MatrixType& mat, int options) {
723 
724  eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
725  eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
726  "invalid option parameter");
727  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;
728 
729  EigenvectorsType& eivecs = solver.m_eivec;
730  VectorType& eivals = solver.m_eivalues;
731 
732  // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
733  Scalar shift = mat.trace() / Scalar(2);
734  MatrixType scaledMat = mat;
735  scaledMat.coeffRef(0, 1) = mat.coeff(1, 0);
736  scaledMat.diagonal().array() -= shift;
737  Scalar scale = scaledMat.cwiseAbs().maxCoeff();
738  if (scale > Scalar(0)) scaledMat /= scale;
739 
740  // Compute the eigenvalues
741  computeRoots(scaledMat, eivals);
742 
743  // compute the eigen vectors
744  if (computeEigenvectors) {
745  if ((eivals(1) - eivals(0)) <= abs(eivals(1)) * Eigen::NumTraits<Scalar>::epsilon()) {
746  eivecs.setIdentity();
747  } else {
748  scaledMat.diagonal().array() -= eivals(1);
749  Scalar a2 = numext::abs2(scaledMat(0, 0));
750  Scalar c2 = numext::abs2(scaledMat(1, 1));
751  Scalar b2 = numext::abs2(scaledMat(1, 0));
752  if (a2 > c2) {
753  eivecs.col(1) << -scaledMat(1, 0), scaledMat(0, 0);
754  eivecs.col(1) /= sqrt(a2 + b2);
755  } else {
756  eivecs.col(1) << -scaledMat(1, 1), scaledMat(1, 0);
757  eivecs.col(1) /= sqrt(c2 + b2);
758  }
759 
760  eivecs.col(0) << eivecs.col(1).unitOrthogonal();
761  }
762  }
763 
764  // Rescale back to the original size.
765  eivals *= scale;
766  eivals.array() += shift;
767 
768  solver.m_info = Success;
769  solver.m_isInitialized = true;
770  solver.m_eigenvectorsOk = computeEigenvectors;
771  }
772 };
773 
774 } // namespace internal
775 
776 template <typename MatrixType>
778  const MatrixType& matrix, int options) {
780  *this, matrix, options);
781  return *this;
782 }
783 
784 namespace internal {
785 
786 // Francis implicit QR step.
787 template <int StorageOrder, typename RealScalar, typename Scalar, typename Index>
789  Scalar* matrixQ, Index n) {
790  // Wilkinson Shift.
791  RealScalar td = (diag[end - 1] - diag[end]) * RealScalar(0.5);
792  RealScalar e = subdiag[end - 1];
793  // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
794  // underflow thus leading to inf/NaN values when using the following commented code:
795  // RealScalar e2 = numext::abs2(subdiag[end-1]);
796  // RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
797  // This explain the following, somewhat more complicated, version:
798  RealScalar mu = diag[end];
799  if (numext::is_exactly_zero(td)) {
800  mu -= numext::abs(e);
801  } else if (!numext::is_exactly_zero(e)) {
802  const RealScalar e2 = numext::abs2(e);
803  const RealScalar h = numext::hypot(td, e);
804  if (numext::is_exactly_zero(e2)) {
805  mu -= e / ((td + (td > RealScalar(0) ? h : -h)) / e);
806  } else {
807  mu -= e2 / (td + (td > RealScalar(0) ? h : -h));
808  }
809  }
810 
811  RealScalar x = diag[start] - mu;
812  RealScalar z = subdiag[start];
813  // If z ever becomes zero, the Givens rotation will be the identity and
814  // z will stay zero for all future iterations.
815  for (Index k = start; k < end && !numext::is_exactly_zero(z); ++k) {
817  rot.makeGivens(x, z);
818 
819  // do T = G' T G
820  RealScalar sdk = rot.s() * diag[k] + rot.c() * subdiag[k];
821  RealScalar dkp1 = rot.s() * subdiag[k] + rot.c() * diag[k + 1];
822 
823  diag[k] =
824  rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k + 1]);
825  diag[k + 1] = rot.s() * sdk + rot.c() * dkp1;
826  subdiag[k] = rot.c() * sdk - rot.s() * dkp1;
827 
828  if (k > start) subdiag[k - 1] = rot.c() * subdiag[k - 1] - rot.s() * z;
829 
830  // "Chasing the bulge" to return to triangular form.
831  x = subdiag[k];
832  if (k < end - 1) {
833  z = -rot.s() * subdiag[k + 1];
834  subdiag[k + 1] = rot.c() * subdiag[k + 1];
835  }
836 
837  // apply the givens rotation to the unit matrix Q = Q * G
838  if (matrixQ) {
839  // FIXME if StorageOrder == RowMajor this operation is not very efficient
841  q.applyOnTheRight(k, k + 1, rot);
842  }
843  }
844 }
845 
846 } // end namespace internal
847 
848 } // end namespace Eigen
849 
850 #endif // EIGEN_SELFADJOINTEIGENSOLVER_H
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
BiCGSTAB< SparseMatrix< double > > solver
Definition: BiCGSTAB_simple.cpp:5
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1090
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
VectorXcd eivals
Definition: MatrixBase_eigenvalues.cpp:2
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition: StaticAssert.h:74
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
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Rotation given by a cosine-sine pair.
Definition: Jacobi.h:38
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
EIGEN_DEVICE_FUNC Derived & setOnes(Index size)
Definition: CwiseNullaryOp.h:708
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:198
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:264
Computes eigenvalues and eigenvectors of selfadjoint matrices.
Definition: SelfAdjointEigenSolver.h:82
EIGEN_DEVICE_FUNC ComputationInfo info() const
Reports whether previous computation was successful.
Definition: SelfAdjointEigenSolver.h:356
TridiagonalizationType::CoeffVectorType m_hcoeffs
Definition: SelfAdjointEigenSolver.h:375
VectorType m_workspace
Definition: SelfAdjointEigenSolver.h:372
internal::plain_col_type< MatrixType, RealScalar >::type RealVectorType
Definition: SelfAdjointEigenSolver.h:114
TridiagonalizationType::SubDiagonalType m_subdiag
Definition: SelfAdjointEigenSolver.h:374
MatrixType_ MatrixType
Definition: SelfAdjointEigenSolver.h:84
RealVectorType m_eivalues
Definition: SelfAdjointEigenSolver.h:373
SelfAdjointEigenSolver & computeFromTridiagonal(const RealVectorType &diag, const SubDiagonalType &subdiag, int options=ComputeEigenvectors)
Computes the eigen decomposition from a tridiagonal symmetric matrix.
Definition: SelfAdjointEigenSolver.h:455
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver(const EigenBase< InputType > &matrix, int options=ComputeEigenvectors)
Constructor; computes eigendecomposition of given matrix.
Definition: SelfAdjointEigenSolver.h:175
ComputationInfo m_info
Definition: SelfAdjointEigenSolver.h:376
NumTraits< Scalar >::Real RealScalar
Real scalar type for MatrixType_.
Definition: SelfAdjointEigenSolver.h:104
bool m_eigenvectorsOk
Definition: SelfAdjointEigenSolver.h:378
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver & computeDirect(const MatrixType &matrix, int options=ComputeEigenvectors)
Computes eigendecomposition of given matrix using a closed-form algorithm.
Definition: SelfAdjointEigenSolver.h:777
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver & compute(const EigenBase< InputType > &matrix, int options=ComputeEigenvectors)
Computes eigendecomposition of given matrix.
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver(Index size)
Constructor, pre-allocates memory for dynamic-size matrices.
Definition: SelfAdjointEigenSolver.h:150
EIGEN_DEVICE_FUNC MatrixType operatorSqrt() const
Computes the positive-definite square root of the matrix.
Definition: SelfAdjointEigenSolver.h:322
Eigen::Index Index
Definition: SelfAdjointEigenSolver.h:94
MatrixType::Scalar Scalar
Scalar type for matrices of type MatrixType_.
Definition: SelfAdjointEigenSolver.h:93
@ ColsAtCompileTime
Definition: SelfAdjointEigenSolver.h:87
@ Options
Definition: SelfAdjointEigenSolver.h:88
@ MaxColsAtCompileTime
Definition: SelfAdjointEigenSolver.h:89
@ Size
Definition: SelfAdjointEigenSolver.h:86
EIGEN_DEVICE_FUNC const EigenvectorsType & eigenvectors() const
Returns the eigenvectors of given matrix.
Definition: SelfAdjointEigenSolver.h:279
bool m_isInitialized
Definition: SelfAdjointEigenSolver.h:377
EIGEN_DEVICE_FUNC MatrixType operatorInverseSqrt() const
Computes the inverse square root of the matrix.
Definition: SelfAdjointEigenSolver.h:346
EigenvectorsType m_eivec
Definition: SelfAdjointEigenSolver.h:371
Matrix< Scalar, Size, Size, ColMajor, MaxColsAtCompileTime, MaxColsAtCompileTime > EigenvectorsType
Definition: SelfAdjointEigenSolver.h:96
EIGEN_DEVICE_FUNC const RealVectorType & eigenvalues() const
Returns the eigenvalues of given matrix.
Definition: SelfAdjointEigenSolver.h:300
static const int m_maxIterations
Maximum number of iterations.
Definition: SelfAdjointEigenSolver.h:366
internal::plain_col_type< MatrixType, Scalar >::type VectorType
Type for vector of eigenvalues as returned by eigenvalues().
Definition: SelfAdjointEigenSolver.h:113
Scalar coeff(Index row, Index col) const
Definition: SparseMatrix.h:211
const ConstDiagonalReturnType diagonal() const
Definition: SparseMatrix.h:757
Index cols() const
Definition: SparseMatrix.h:161
Scalar & coeffRef(Index row, Index col)
Definition: SparseMatrix.h:275
Index rows() const
Definition: SparseMatrix.h:159
Tridiagonal decomposition of a selfadjoint matrix.
Definition: Tridiagonalization.h:66
@ IsComplex
Definition: common.h:73
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
float real
Definition: datatypes.h:10
#define min(a, b)
Definition: datatypes.h:22
void computeRoots(const Matrix &m, Roots &roots)
Definition: eig33.cpp:49
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
static EIGEN_DEVICE_FUNC void tridiagonal_qr_step(RealScalar *diag, RealScalar *subdiag, Index start, Index end, Scalar *matrixQ, Index n)
Definition: SelfAdjointEigenSolver.h:788
ComputationInfo
Definition: Constants.h:438
@ Success
Definition: Constants.h:440
@ NoConvergence
Definition: Constants.h:444
@ GenEigMask
Definition: Constants.h:414
@ EigVecMask
Definition: Constants.h:403
@ ComputeEigenvectors
Definition: Constants.h:401
EIGEN_BLAS_FUNC() rot(int *n, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pc, Scalar *ps)
Definition: level1_real_impl.h:88
int * m
Definition: level2_cplx_impl.h:294
const char const char const char * diag
Definition: level2_impl.h:86
char char char int int * k
Definition: level2_impl.h:374
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
double theta
Definition: two_d_biharmonic.cc:236
EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType &matA, CoeffVectorType &hCoeffs)
Definition: Tridiagonalization.h:332
EIGEN_DEVICE_FUNC ComputationInfo computeFromTridiagonal_impl(DiagType &diag, SubDiagType &subdiag, const Index maxIterations, bool computeEigenvectors, MatrixType &eivec)
Compute the eigendecomposition from a tridiagonal matrix.
Definition: SelfAdjointEigenSolver.h:485
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Definition: MathFunctions.h:926
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
Definition: MathFunctions.h:1355
EIGEN_STRONG_INLINE void swap(T &a, T &b)
Definition: Meta.h:536
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
auto run(Kernel kernel, Args &&... args) -> decltype(kernel(args...))
Definition: gpu_test_helper.h:414
AutoDiffScalar< Matrix< typename internal::traits< internal::remove_all_t< DerTypeA > >::Scalar, Dynamic, 1 > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
Definition: AutoDiffScalar.h:558
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
std::complex< double > mu
Definition: time_harmonic_fourier_decomposed_linear_elasticity/cylinder/cylinder.cc:52
type
Definition: compute_granudrum_aor.py:141
Definition: Eigen_Colamd.h:49
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
list x
Definition: plotDoE.py:28
Definition: EigenBase.h:33
constexpr EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:49
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
static EIGEN_DEVICE_FUNC void computeRoots(const MatrixType &m, VectorType &roots)
Definition: SelfAdjointEigenSolver.h:712
SolverType::Scalar Scalar
Definition: SelfAdjointEigenSolver.h:709
SolverType::RealVectorType VectorType
Definition: SelfAdjointEigenSolver.h:708
SolverType::EigenvectorsType EigenvectorsType
Definition: SelfAdjointEigenSolver.h:710
SolverType::MatrixType MatrixType
Definition: SelfAdjointEigenSolver.h:707
static EIGEN_DEVICE_FUNC void run(SolverType &solver, const MatrixType &mat, int options)
Definition: SelfAdjointEigenSolver.h:720
SolverType::RealVectorType VectorType
Definition: SelfAdjointEigenSolver.h:560
SolverType::Scalar Scalar
Definition: SelfAdjointEigenSolver.h:561
SolverType::EigenvectorsType EigenvectorsType
Definition: SelfAdjointEigenSolver.h:562
SolverType::MatrixType MatrixType
Definition: SelfAdjointEigenSolver.h:559
static EIGEN_DEVICE_FUNC void run(SolverType &solver, const MatrixType &mat, int options)
Definition: SelfAdjointEigenSolver.h:629
static EIGEN_DEVICE_FUNC void computeRoots(const MatrixType &m, VectorType &roots)
Definition: SelfAdjointEigenSolver.h:568
static EIGEN_DEVICE_FUNC bool extract_kernel(MatrixType &mat, Ref< VectorType > res, Ref< VectorType > representative)
Definition: SelfAdjointEigenSolver.h:607
Definition: SelfAdjointEigenSolver.h:551
static EIGEN_DEVICE_FUNC void run(SolverType &eig, const typename SolverType::MatrixType &A, int options)
Definition: SelfAdjointEigenSolver.h:552
Definition: XprHelper.h:772
Definition: ForwardDeclarations.h:21
Definition: fft_test_shared.h:66