mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-13 16:28:06 +08:00
integrate Hauke's 2x2 direct symmetric eigenvalues solver
This commit is contained in:
parent
26d7dad138
commit
47a2bca89f
@ -500,10 +500,10 @@ template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_
|
||||
template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3,false>
|
||||
{
|
||||
typedef typename SolverType::MatrixType MatrixType;
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
|
||||
template<typename Roots>
|
||||
inline static void computeRoots(const MatrixType& m, Roots& roots)
|
||||
inline static void computeRoots(const MatrixType& m, VectorType& roots)
|
||||
{
|
||||
using std::sqrt;
|
||||
using std::atan2;
|
||||
@ -561,7 +561,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
typename SolverType::RealVectorType& eivals = solver.m_eivalues;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
Scalar scale = mat.cwiseAbs().maxCoeff();
|
||||
@ -610,6 +610,91 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
||||
}
|
||||
};
|
||||
|
||||
// 2x2 direct eigenvalues decomposition, code from Hauke Heibel
|
||||
template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2,false>
|
||||
{
|
||||
typedef typename SolverType::MatrixType MatrixType;
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
|
||||
inline static void run(SolverType& solver, const MatrixType& mat, int options)
|
||||
{
|
||||
eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
|
||||
eigen_assert((options&~(EigVecMask|GenEigMask))==0
|
||||
&& (options&EigVecMask)!=EigVecMask
|
||||
&& "invalid option parameter");
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
Scalar scale = mat.cwiseAbs().maxCoeff();
|
||||
scale = std::max(scale,Scalar(1));
|
||||
MatrixType scaledMat = mat / scale;
|
||||
|
||||
// Compute the eigenvalues
|
||||
const Scalar xx = scaledMat(0,0);
|
||||
const Scalar yy = scaledMat(1,1);
|
||||
const Scalar xy = scaledMat(1,0);
|
||||
|
||||
const Scalar root = std::sqrt((xx-yy)*(xx-yy)+Scalar(4.0)*xy*xy);
|
||||
const Scalar eig_val1 = Scalar(0.5)*(xx+yy+root);
|
||||
const Scalar eig_val2 = Scalar(0.5)*(xx+yy-root);
|
||||
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
|
||||
// compute the eigen vectors
|
||||
if(computeEigenvectors)
|
||||
{
|
||||
Scalar nx, ny;
|
||||
if (xx-yy > 0)
|
||||
{
|
||||
Scalar len(1.0);
|
||||
if (-yy+xx+root != Scalar(0.0))
|
||||
{
|
||||
ny = -Scalar(2.0)*xy/(-yy+xx+root);
|
||||
len = Scalar(1.0)/sqrt(1+ny*ny);
|
||||
ny *= len;
|
||||
}
|
||||
else
|
||||
ny = Scalar(0.0);
|
||||
nx = -len;
|
||||
}
|
||||
else
|
||||
{
|
||||
Scalar len = Scalar(1.0);
|
||||
if (-yy+xx-root != Scalar(0.0))
|
||||
{
|
||||
nx = -Scalar(2.0)*xy/(-yy+xx-root);
|
||||
len = Scalar(1.0)/sqrt(1+nx*nx);
|
||||
nx *= len;
|
||||
}
|
||||
else
|
||||
nx = Scalar(0.0);
|
||||
ny = len;
|
||||
}
|
||||
|
||||
int id0(0), id1(1);
|
||||
if(eig_val1>eig_val2)
|
||||
std::swap(id0,id1);
|
||||
|
||||
eivecs.col(id0) << nx, ny;
|
||||
eivecs.col(id1) << -ny, nx;
|
||||
eivals(id0) = eig_val1;
|
||||
eivals(id1) = eig_val2;
|
||||
}
|
||||
|
||||
// Rescale back to the original size.
|
||||
eivals *= scale;
|
||||
|
||||
solver.m_info = Success;
|
||||
solver.m_isInitialized = true;
|
||||
solver.m_eigenvectorsOk = computeEigenvectors;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
|
Loading…
x
Reference in New Issue
Block a user