From bc8188f6a15a924066b52767fa6e52dc6b61ac3a Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 27 Feb 2012 13:21:41 +0100 Subject: [PATCH] fix symmetric permuatation for mixed storage orders --- Eigen/src/SparseCore/SparseSelfAdjointView.h | 39 ++++++++++++++------ test/sparse_permutations.cpp | 22 ++++++++--- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/Eigen/src/SparseCore/SparseSelfAdjointView.h b/Eigen/src/SparseCore/SparseSelfAdjointView.h index 41cd36d72..7c9a6922a 100644 --- a/Eigen/src/SparseCore/SparseSelfAdjointView.h +++ b/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -309,12 +309,14 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrixj) || ( UpLo==Upper && ic) || ( UpLo==Upper && rj) || ( (UpLo&Upper)==Upper && ic) || ( (UpLo&Upper)==Upper && r -void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) +template +void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; - typedef SparseMatrix Dest; - Dest& dest(_dest.derived()); + SparseMatrix& dest(_dest.derived()); typedef Matrix VectorI; - //internal::conj_if cj; + enum { + SrcOrder = MatrixType::IsRowMajor ? RowMajor : ColMajor, + StorageOrderMatch = int(SrcOrder) == int(DstOrder), + DstUpLo = DstOrder==RowMajor ? (_DstUpLo==Upper ? Lower : Upper) : _DstUpLo, + SrcUpLo = SrcOrder==RowMajor ? (_SrcUpLo==Upper ? Lower : Upper) : _SrcUpLo + }; Index size = mat.rows(); VectorI count(size); @@ -400,18 +412,21 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrixj)) continue; + Index jp = perm ? perm[j] : j; Index ip = perm? perm[i] : i; + Index k = count[DstUpLo==Lower ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; dest.innerIndexPtr()[k] = DstUpLo==Lower ? (std::max)(ip,jp) : (std::min)(ip,jp); - if((DstUpLo==Lower && ipjp)) + if(!StorageOrderMatch) std::swap(ip,jp); + if( ((DstUpLo==Lower && ipjp))) dest.valuePtr()[k] = conj(it.value()); else dest.valuePtr()[k] = it.value(); diff --git a/test/sparse_permutations.cpp b/test/sparse_permutations.cpp index 7f47611a5..522e78f67 100644 --- a/test/sparse_permutations.cpp +++ b/test/sparse_permutations.cpp @@ -24,19 +24,22 @@ #include "sparse.h" -template void sparse_permutations(const SparseMatrixType& ref) +template void sparse_permutations(const SparseMatrixType& ref) { typedef typename SparseMatrixType::Index Index; const Index rows = ref.rows(); const Index cols = ref.cols(); typedef typename SparseMatrixType::Scalar Scalar; + typedef typename SparseMatrixType::Index Index; + typedef SparseMatrix OtherSparseMatrixType; typedef Matrix DenseMatrix; - typedef Matrix VectorI; + typedef Matrix VectorI; double density = (std::max)(8./(rows*cols), 0.01); - SparseMatrixType mat(rows, cols), up(rows,cols), lo(rows,cols), res; + SparseMatrixType mat(rows, cols), up(rows,cols), lo(rows,cols); + OtherSparseMatrixType res; DenseMatrix mat_d = DenseMatrix::Zero(rows, cols), up_sym_d, lo_sym_d, res_d; initSparse(density, mat_d, mat, 0); @@ -126,12 +129,19 @@ template void sparse_permutations(const SparseMatrixT VERIFY(res.isApprox(res_d) && "lower selfadjoint twisted to full"); } +template void sparse_permutations_all(int size) +{ + CALL_SUBTEST(( sparse_permutations(SparseMatrix(size,size)) )); + CALL_SUBTEST(( sparse_permutations(SparseMatrix(size,size)) )); + CALL_SUBTEST(( sparse_permutations(SparseMatrix(size,size)) )); + CALL_SUBTEST(( sparse_permutations(SparseMatrix(size,size)) )); +} + void test_sparse_permutations() { for(int i = 0; i < g_repeat; i++) { int s = Eigen::internal::random(1,50); - CALL_SUBTEST_1(( sparse_permutations(SparseMatrix(8, 8)) )); - CALL_SUBTEST_2(( sparse_permutations(SparseMatrix >(s, s)) )); - CALL_SUBTEST_1(( sparse_permutations(SparseMatrix(s, s)) )); + CALL_SUBTEST_1(( sparse_permutations_all(s) )); + CALL_SUBTEST_2(( sparse_permutations_all >(s) )); } }