From 9bba0e7ba123155d7a639d7c1bd5675dce91ae6f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 24 Sep 2011 17:15:37 +0200 Subject: [PATCH] clean sparse LU tests --- unsupported/test/CMakeLists.txt | 13 ++- unsupported/test/sparse_lu.h | 86 +++++++++++++++++++ .../{sparse_lu.cpp => sparse_lu_legacy.cpp} | 34 ++------ unsupported/test/superlu_support.cpp | 39 +++++++++ unsupported/test/umfpack_support.cpp | 39 +++++++++ 5 files changed, 182 insertions(+), 29 deletions(-) create mode 100644 unsupported/test/sparse_lu.h rename unsupported/test/{sparse_lu.cpp => sparse_lu_legacy.cpp} (81%) create mode 100644 unsupported/test/superlu_support.cpp create mode 100644 unsupported/test/umfpack_support.cpp diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index c84cccc52..117725c04 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -25,6 +25,7 @@ if(UMFPACK_FOUND AND BLAS_FOUND) add_definitions("-DEIGEN_UMFPACK_SUPPORT") include_directories(${UMFPACK_INCLUDES}) set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES}) + set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES}) ei_add_property(EIGEN_TESTED_BACKENDS "UmfPack, ") else() ei_add_property(EIGEN_MISSING_BACKENDS "UmfPack, ") @@ -35,6 +36,7 @@ if(SUPERLU_FOUND AND BLAS_FOUND) add_definitions("-DEIGEN_SUPERLU_SUPPORT") include_directories(${SUPERLU_INCLUDES}) set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES}) + set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES}) ei_add_property(EIGEN_TESTED_BACKENDS "SuperLU, ") else() ei_add_property(EIGEN_MISSING_BACKENDS "SuperLU, ") @@ -88,7 +90,16 @@ endif() ei_add_test(sparse_llt "" "${SPARSE_LIBS}") ei_add_test(sparse_ldlt "" "${SPARSE_LIBS}") -ei_add_test(sparse_lu "" "${SPARSE_LIBS}") +ei_add_test(sparse_lu_legacy "" "${SPARSE_LIBS}") + +if(UMFPACK_FOUND) + ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}") +endif() + +if(SUPERLU_FOUND) + ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}") +endif() + ei_add_test(sparse_extra "" "") find_package(FFTW) diff --git a/unsupported/test/sparse_lu.h b/unsupported/test/sparse_lu.h new file mode 100644 index 000000000..49bb6f305 --- /dev/null +++ b/unsupported/test/sparse_lu.h @@ -0,0 +1,86 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "sparse.h" +#include + +template +void check_slu(LUSolver& lu, const typename LUSolver::MatrixType& A, const Rhs& b, const DenseMat& dA, const DenseRhs& db) +{ + typedef typename LUSolver::MatrixType Mat; + typedef typename Mat::Scalar Scalar; + + DenseRhs refX = dA.lu().solve(db); + Scalar refDet = dA.determinant(); + + Rhs x(b.rows(), b.cols()); + Rhs oldb = b; + + lu.compute(A); + if (lu.info() != Success) + { + std::cerr << "sparse LU: factorization failed\n"; + return; + } + x = lu.solve(b); + if (lu.info() != Success) + { + std::cerr << "sparse LU: solving failed\n"; + return; + } + VERIFY(oldb.isApprox(b) && "sparse LU: the rhs should not be modified!"); + + VERIFY(refX.isApprox(x,test_precision())); + + if(A.cols()<30) + { + //std::cout << refDet << " == " << lu.determinant() << "\n"; + VERIFY_IS_APPROX(refDet,lu.determinant()); + } +} + +template void sparse_lu(LUSolver& lu) +{ + typedef typename LUSolver::MatrixType Mat; + typedef typename Mat::Scalar Scalar; + typedef Matrix DenseMatrix; + typedef Matrix DenseVector; + + std::vector zeroCoords; + std::vector nonzeroCoords; + + int size = internal::random(1,300); + double density = (std::max)(8./(size*size), 0.01); + //int rhsSize = internal::random(1,10); + + Mat m2(size, size); + DenseMatrix refMat2(size, size); + + DenseVector b = DenseVector::Random(size); + DenseVector refX(size), x(size); + + initSparse(density, refMat2, m2, ForceNonZeroDiag, &zeroCoords, &nonzeroCoords); + + check_slu(lu, m2, b, refMat2, b); +} diff --git a/unsupported/test/sparse_lu.cpp b/unsupported/test/sparse_lu_legacy.cpp similarity index 81% rename from unsupported/test/sparse_lu.cpp rename to unsupported/test/sparse_lu_legacy.cpp index 8c115eebf..e7fae0682 100644 --- a/unsupported/test/sparse_lu.cpp +++ b/unsupported/test/sparse_lu_legacy.cpp @@ -33,7 +33,8 @@ #include #endif -template void sparse_lu(int rows, int cols) + +template void sparse_lu_legacy(int rows, int cols) { double density = (std::max)(8./(rows*cols), 0.01); typedef Matrix DenseMatrix; @@ -110,39 +111,16 @@ template void sparse_lu(int rows, int cols) else std::cerr << "super lu factorize failed\n"; } - - // New API - { - x.setZero(); - SuperLU > slu(m2); - if (slu.info() == Success) - { - DenseVector oldb = b; - x = slu.solve(b); - VERIFY(oldb.isApprox(b) && "the rhs should not be modified!"); - if (slu.info() == Success) { - VERIFY(refX.isApprox(x,test_precision()) && "SuperLU"); - } - else - std::cerr << "super lu solving failed\n"; - - if (!NumTraits::IsComplex) { - VERIFY_IS_APPROX(refDet,slu.determinant()); // FIXME det is not very stable for complex - } - } - else - std::cerr << "super lu factorize failed\n"; - } #endif } -void test_sparse_lu() +void test_sparse_lu_legacy() { for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST_1(sparse_lu(8, 8) ); + CALL_SUBTEST_1(sparse_lu_legacy(8, 8) ); int s = internal::random(1,300); - CALL_SUBTEST_2(sparse_lu >(s,s) ); - CALL_SUBTEST_1(sparse_lu(s,s) ); + CALL_SUBTEST_1(sparse_lu_legacy >(s,s) ); + CALL_SUBTEST_1(sparse_lu_legacy(s,s) ); } } diff --git a/unsupported/test/superlu_support.cpp b/unsupported/test/superlu_support.cpp new file mode 100644 index 000000000..31d623614 --- /dev/null +++ b/unsupported/test/superlu_support.cpp @@ -0,0 +1,39 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "sparse_lu.h" + +#ifdef EIGEN_SUPERLU_SUPPORT +#include +#endif + +void test_superlu_support() +{ + for(int i = 0; i < g_repeat; i++) { + SuperLU > superlu_double_colmajor; + SuperLU > > superlu_cplxdouble_colmajor; + CALL_SUBTEST_1(sparse_lu(superlu_double_colmajor)); + CALL_SUBTEST_1(sparse_lu(superlu_cplxdouble_colmajor)); + } +} diff --git a/unsupported/test/umfpack_support.cpp b/unsupported/test/umfpack_support.cpp new file mode 100644 index 000000000..a2dde2196 --- /dev/null +++ b/unsupported/test/umfpack_support.cpp @@ -0,0 +1,39 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "sparse_lu.h" + +#ifdef EIGEN_UMFPACK_SUPPORT +#include +#endif + +void test_umfpack_support() +{ + for(int i = 0; i < g_repeat; i++) { + UmfPackLU > umfpack_double_colmajor; + UmfPackLU > > umfpack_cplxdouble_colmajor; + CALL_SUBTEST_1(sparse_lu(umfpack_double_colmajor)); + CALL_SUBTEST_1(sparse_lu(umfpack_cplxdouble_colmajor)); + } +}