aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2010-11-04 09:33:05 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2010-11-04 09:33:05 +0100
commit5a4f77716d1f925229e5656282d6d76e22ab8698 (patch)
tree9ea3258b19cc97a7fb2a314486ab2718ceb05483
parent20fcef9656301e55cb19d61c698de8fafd3cfa4c (diff)
fix bug #107: SelfAdjointEigenSolver and RowMajor (and add unit test)
-rw-r--r--Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h9
-rw-r--r--test/eigensolver_selfadjoint.cpp2
2 files changed, 7 insertions, 4 deletions
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index 7cef9e529..83d9c015c 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -336,7 +336,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
* "implicit symmetric QR step with Wilkinson shift"
*/
namespace internal {
-template<typename RealScalar, typename Scalar, typename Index>
+template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
}
@@ -398,7 +398,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
while (start>0 && m_subdiag[start-1]!=0)
start--;
- internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
+ internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
}
if (iter <= m_maxIterations)
@@ -430,7 +430,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
}
namespace internal {
-template<typename RealScalar, typename Scalar, typename Index>
+template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
{
RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
@@ -466,7 +466,8 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
// apply the givens rotation to the unit matrix Q = Q * G
if (matrixQ)
{
- Map<Matrix<Scalar,Dynamic,Dynamic> > q(matrixQ,n,n);
+ // FIXME if StorageOrder == RowMajor this operation is not very efficient
+ Map<Matrix<Scalar,Dynamic,Dynamic,StorageOrder> > q(matrixQ,n,n);
q.applyOnTheRight(k,k+1,rot);
}
}
diff --git a/test/eigensolver_selfadjoint.cpp b/test/eigensolver_selfadjoint.cpp
index dadf4bfca..806fe5831 100644
--- a/test/eigensolver_selfadjoint.cpp
+++ b/test/eigensolver_selfadjoint.cpp
@@ -173,6 +173,8 @@ void test_eigensolver_selfadjoint()
CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(10,10)) );
CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(19,19)) );
CALL_SUBTEST_5( selfadjointeigensolver(MatrixXcd(17,17)) );
+
+ CALL_SUBTEST_9( selfadjointeigensolver(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(17,17)) );
// some trivial but implementation-wise tricky cases
CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(1,1)) );