Classes

struct  Eigen::internal::HessenbergDecompositionMatrixHReturnType< MatrixType >
 Expression type for return value of HessenbergDecomposition::matrixH() More...
 
struct  Eigen::internal::TridiagonalizationMatrixTReturnType< MatrixType >
 Expression type for return value of Tridiagonalization::matrixT() More...
 
class  Eigen::ComplexEigenSolver< MatrixType_ >
 Computes eigenvalues and eigenvectors of general complex matrices. More...
 
class  Eigen::ComplexSchur< MatrixType_ >
 Performs a complex Schur decomposition of a real or complex square matrix. More...
 
class  Eigen::EigenSolver< MatrixType_ >
 Computes eigenvalues and eigenvectors of general matrices. More...
 
class  Eigen::GeneralizedEigenSolver< MatrixType_ >
 Computes the generalized eigenvalues and eigenvectors of a pair of general matrices. More...
 
class  Eigen::GeneralizedSelfAdjointEigenSolver< MatrixType_ >
 Computes eigenvalues and eigenvectors of the generalized selfadjoint eigen problem. More...
 
class  Eigen::HessenbergDecomposition< MatrixType_ >
 Reduces a square matrix to Hessenberg form by an orthogonal similarity transformation. More...
 
class  Eigen::RealQZ< MatrixType_ >
 Performs a real QZ decomposition of a pair of square matrices. More...
 
class  Eigen::RealSchur< MatrixType_ >
 Performs a real Schur decomposition of a square matrix. More...
 
class  Eigen::SelfAdjointEigenSolver< MatrixType_ >
 Computes eigenvalues and eigenvectors of selfadjoint matrices. More...
 
class  Eigen::Tridiagonalization< MatrixType_ >
 Tridiagonal decomposition of a selfadjoint matrix. More...
 

Functions

template<int StorageOrder, typename RealScalar , typename Scalar , typename Index >
static EIGEN_DEVICE_FUNC void Eigen::internal::tridiagonal_qr_step (RealScalar *diag, RealScalar *subdiag, Index start, Index end, Scalar *matrixQ, Index n)
 

Detailed Description

Function Documentation

◆ tridiagonal_qr_step()

template<int StorageOrder, typename RealScalar , typename Scalar , typename Index >
static EIGEN_DEVICE_FUNC void Eigen::internal::tridiagonal_qr_step ( RealScalar diag,
RealScalar subdiag,
Index  start,
Index  end,
Scalar matrixQ,
Index  n 
)
static

\eigenvalues_module

Performs a QR step on a tridiagonal symmetric matrix represented as a pair of two vectors diag and subdiag.

Parameters
diagthe diagonal part of the input selfadjoint tridiagonal matrix
subdiagthe sub-diagonal part of the input selfadjoint tridiagonal matrix
startstarting index of the submatrix to work on
endlast+1 index of the submatrix to work on
matrixQpointer to the column-major matrix holding the eigenvectors, can be 0
nsize of the input matrix

For compilation efficiency reasons, this procedure does not use eigen expression for its arguments.

Implemented from Golub's "Matrix Computations", algorithm 8.3.2: "implicit symmetric QR step with Wilkinson shift"

789  {
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) {
816  JacobiRotation<RealScalar> rot;
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
840  Map<Matrix<Scalar, Dynamic, Dynamic, StorageOrder> > q(matrixQ, n, n);
841  q.applyOnTheRight(k, k + 1, rot);
842  }
843  }
844 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
EIGEN_BLAS_FUNC() rot(int *n, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pc, Scalar *ps)
Definition: level1_real_impl.h:88
const char const char const char * diag
Definition: level2_impl.h:86
char char char int int * k
Definition: level2_impl.h:374
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
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
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243
list x
Definition: plotDoE.py:28

References Eigen::numext::abs(), Eigen::numext::abs2(), diag, e(), Eigen::placeholders::end, Eigen::numext::is_exactly_zero(), k, Global_Parameters::mu, n, Eigen::numext::q, rot(), oomph::CumulativeTimings::start(), and plotDoE::x.