add EigenSolver::eigenvectors() method for non symmetric matrices.

However, for matrices larger than 5, it seems there is constantly a quite large error for a very
few coefficients. I don't what's going on, but that's certainely not due to numerical issues only.
(also note that the test with the pseudo eigenvectors fails the same way)
This commit is contained in:
Gael Guennebaud
2008-10-03 13:22:54 +00:00
parent d907cd4410
commit 1fc503e3ce
2 changed files with 56 additions and 9 deletions

View File

@@ -48,6 +48,7 @@ template<typename _MatrixType> class EigenSolver
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef std::complex<RealScalar> Complex;
typedef Matrix<Complex, MatrixType::ColsAtCompileTime, 1> EigenvalueType;
typedef Matrix<Complex, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> EigenvectorType;
typedef Matrix<RealScalar, MatrixType::ColsAtCompileTime, 1> RealVectorType;
typedef Matrix<RealScalar, Dynamic, 1> RealVectorTypeX;
@@ -58,8 +59,8 @@ template<typename _MatrixType> class EigenSolver
compute(matrix);
}
// TODO compute the complex eigen vectors
// MatrixType eigenvectors(void) const { return m_eivec; }
EigenvectorType eigenvectors(void) const;
/** \returns a real matrix V of pseudo eigenvectors.
*
@@ -94,10 +95,6 @@ template<typename _MatrixType> class EigenSolver
*/
const MatrixType& pseudoEigenvectors() const { return m_eivec; }
/** \returns the real block diagonal matrix D of the eigenvalues.
*
* See pseudoEigenvectors() for the details.
*/
MatrixType pseudoEigenvalueMatrix() const;
/** \returns the eigenvalues as a column vector */
@@ -115,6 +112,10 @@ template<typename _MatrixType> class EigenSolver
EigenvalueType m_eivalues;
};
/** \returns the real block diagonal matrix D of the eigenvalues.
*
* See pseudoEigenvectors() for the details.
*/
template<typename MatrixType>
MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
{
@@ -134,6 +135,38 @@ MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
return matD;
}
/** \returns the normalized complex eigenvectors as a matrix of column vectors.
*
* \sa eigenvalues(), pseudoEigenvectors()
*/
template<typename MatrixType>
typename EigenSolver<MatrixType>::EigenvectorType EigenSolver<MatrixType>::eigenvectors(void) const
{
int n = m_eivec.cols();
EigenvectorType matV(n,n);
for (int j=0; j<n; j++)
{
if (ei_isMuchSmallerThan(ei_abs(ei_imag(m_eivalues.coeff(j))), ei_abs(ei_real(m_eivalues.coeff(j)))))
{
// we have a real eigen value
matV.col(j) = m_eivec.col(j);
}
else
{
// we have a pair of complex eigen values
for (int i=0; i<n; i++)
{
matV.coeffRef(i,j) = Complex(m_eivec.coeff(i,j), m_eivec.coeff(i,j+1));
matV.coeffRef(i,j+1) = Complex(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
}
matV.col(j).normalize();
matV.col(j+1).normalize();
j++;
}
}
return matV;
}
template<typename MatrixType>
void EigenSolver<MatrixType>::compute(const MatrixType& matrix)
{