move sparse solvers from unsupported/ to main Eigen/ and remove the "not stable yet" warning

This commit is contained in:
Gael Guennebaud 2011-11-12 14:11:27 +01:00
parent dcb66d6b40
commit 53fa851724
62 changed files with 206 additions and 1336 deletions

View File

@ -1,7 +1,7 @@
#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H #ifndef EIGEN_CHOLMODSUPPORT_MODULE_H
#define EIGEN_CHOLMODSUPPORT_MODULE_H #define EIGEN_CHOLMODSUPPORT_MODULE_H
#include "SparseExtra" #include "SparseCore"
#include "../../Eigen/src/Core/util/DisableStupidWarnings.h" #include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
@ -11,7 +11,7 @@ extern "C" {
namespace Eigen { namespace Eigen {
/** \ingroup Unsupported_modules /** \ingroup Sparse_modules
* \defgroup CholmodSupport_Module CholmodSupport module * \defgroup CholmodSupport_Module CholmodSupport module
* *
* *
@ -20,9 +20,10 @@ namespace Eigen {
* \endcode * \endcode
*/ */
struct Cholmod {}; #include "src/misc/Solve.h"
#include "src/SparseExtra/CholmodSupportLegacy.h" #include "src/misc/SparseSolve.h"
#include "src/SparseExtra/CholmodSupport.h"
#include "src/CholmodSupport/CholmodSupport.h"
} // namespace Eigen } // namespace Eigen

View File

@ -1,69 +1,27 @@
#ifndef EIGEN_SPARSE_MODULE_H #ifndef EIGEN_SPARSE_MODULE_H
#define EIGEN_SPARSE_MODULE_H #define EIGEN_SPARSE_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include <vector>
#include <map>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#ifdef EIGEN2_SUPPORT
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#endif
#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token.
#endif
namespace Eigen { namespace Eigen {
/** \defgroup Sparse_Module Sparse module /** \defgroup Sparse_modules Sparse modules
* *
* * Meta-module including all related modules:
* * - SparseCore
* See the \ref TutorialSparse "Sparse tutorial" * - OrderingMethods
* - SparseCholesky
* - IterativeLinearSolvers
* *
* \code * \code
* #include <Eigen/Sparse> * #include <Eigen/Sparse>
* \endcode * \endcode
*/ */
/** The type used to identify a general sparse storage. */
struct Sparse {};
#include "src/Sparse/SparseUtil.h"
#include "src/Sparse/SparseMatrixBase.h"
#include "src/Sparse/CompressedStorage.h"
#include "src/Sparse/AmbiVector.h"
#include "src/Sparse/SparseMatrix.h"
#include "src/Sparse/MappedSparseMatrix.h"
#include "src/Sparse/SparseVector.h"
#include "src/Sparse/CoreIterators.h"
#include "src/Sparse/SparseBlock.h"
#include "src/Sparse/SparseTranspose.h"
#include "src/Sparse/SparseCwiseUnaryOp.h"
#include "src/Sparse/SparseCwiseBinaryOp.h"
#include "src/Sparse/SparseDot.h"
#include "src/Sparse/SparseAssign.h"
#include "src/Sparse/SparseRedux.h"
#include "src/Sparse/SparseFuzzy.h"
#include "src/Sparse/ConservativeSparseSparseProduct.h"
#include "src/Sparse/SparseSparseProductWithPruning.h"
#include "src/Sparse/SparseProduct.h"
#include "src/Sparse/SparseDenseProduct.h"
#include "src/Sparse/SparseDiagonalProduct.h"
#include "src/Sparse/SparseTriangularView.h"
#include "src/Sparse/SparseSelfAdjointView.h"
#include "src/Sparse/TriangularSolver.h"
#include "src/Sparse/SparseView.h"
} // namespace Eigen } // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h" #include "SparseCore"
#include "OrderingMethods"
#include "SparseCholesky"
#include "IterativeLinearSolvers"
#endif // EIGEN_SPARSE_MODULE_H #endif // EIGEN_SPARSE_MODULE_H

64
Eigen/SparseCore Normal file
View File

@ -0,0 +1,64 @@
#ifndef EIGEN_SPARSECORE_MODULE_H
#define EIGEN_SPARSECORE_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
#include <vector>
#include <map>
#include <cstdlib>
#include <cstring>
#include <algorithm>
namespace Eigen {
/** \defgroup Sparse_Module SparseCore module
*
* This module provides a sparse matrix representation, and basic associatd matrix manipulations
* and operations.
*
* See the \ref TutorialSparse "Sparse tutorial"
*
* \code
* #include <Eigen/SparseCore>
* \endcode
*
* This module depends on: Core.
*/
/** The type used to identify a general sparse storage. */
struct Sparse {};
#include "src/SparseCore/SparseUtil.h"
#include "src/SparseCore/SparseMatrixBase.h"
#include "src/SparseCore/CompressedStorage.h"
#include "src/SparseCore/AmbiVector.h"
#include "src/SparseCore/SparseMatrix.h"
#include "src/SparseCore/MappedSparseMatrix.h"
#include "src/SparseCore/SparseVector.h"
#include "src/SparseCore/CoreIterators.h"
#include "src/SparseCore/SparseBlock.h"
#include "src/SparseCore/SparseTranspose.h"
#include "src/SparseCore/SparseCwiseUnaryOp.h"
#include "src/SparseCore/SparseCwiseBinaryOp.h"
#include "src/SparseCore/SparseDot.h"
#include "src/SparseCore/SparseAssign.h"
#include "src/SparseCore/SparseRedux.h"
#include "src/SparseCore/SparseFuzzy.h"
#include "src/SparseCore/ConservativeSparseSparseProduct.h"
#include "src/SparseCore/SparseSparseProductWithPruning.h"
#include "src/SparseCore/SparseProduct.h"
#include "src/SparseCore/SparseDenseProduct.h"
#include "src/SparseCore/SparseDiagonalProduct.h"
#include "src/SparseCore/SparseTriangularView.h"
#include "src/SparseCore/SparseSelfAdjointView.h"
#include "src/SparseCore/TriangularSolver.h"
#include "src/SparseCore/SparseView.h"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SPARSECORE_MODULE_H

View File

@ -1,7 +1,7 @@
#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H #ifndef EIGEN_SUPERLUSUPPORT_MODULE_H
#define EIGEN_SUPERLUSUPPORT_MODULE_H #define EIGEN_SUPERLUSUPPORT_MODULE_H
#include "SparseExtra" #include "SparseCore"
#include "../../Eigen/src/Core/util/DisableStupidWarnings.h" #include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
@ -30,8 +30,8 @@ namespace Eigen { struct SluMatrix; }
namespace Eigen { namespace Eigen {
/** \ingroup Unsupported_modules /** \ingroup Sparse_modules
* \defgroup SuperLUSupport_Module Super LU support * \defgroup SuperLUSupport_Module SuperLUSupport module
* *
* \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting.
* *
@ -40,10 +40,11 @@ namespace Eigen {
* \endcode * \endcode
*/ */
#include "src/SparseExtra/SuperLUSupport.h" #include "src/misc/Solve.h"
#include "src/misc/SparseSolve.h"
#include "src/SuperLUSupport/SuperLUSupport.h"
struct SuperLULegacy {};
#include "src/SparseExtra/SuperLUSupportLegacy.h"
} // namespace Eigen } // namespace Eigen

View File

@ -1,7 +1,7 @@
#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H #ifndef EIGEN_UMFPACKSUPPORT_MODULE_H
#define EIGEN_UMFPACKSUPPORT_MODULE_H #define EIGEN_UMFPACKSUPPORT_MODULE_H
#include "SparseExtra" #include "SparseCore"
#include "../../Eigen/src/Core/util/DisableStupidWarnings.h" #include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
@ -11,8 +11,8 @@ extern "C" {
namespace Eigen { namespace Eigen {
/** \ingroup Unsupported_modules /** \ingroup Sparse_modules
* \defgroup UmfPackSupport_Module UmfPack support module * \defgroup UmfPackSupport_Module UmfPackSupport module
* *
* *
* *
@ -22,10 +22,10 @@ namespace Eigen {
* \endcode * \endcode
*/ */
struct UmfPack {}; #include "src/misc/Solve.h"
#include "src/misc/SparseSolve.h"
#include "src/SparseExtra/UmfPackSupport.h" #include "src/UmfPackSupport/UmfPackSupport.h"
#include "src/SparseExtra/UmfPackSupportLegacy.h"
} // namespace Eigen } // namespace Eigen

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_CholmodSupport_SRCS "*.h")
INSTALL(FILES
${Eigen_CholmodSupport_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/CholmodSupport COMPONENT Devel
)

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_IterativeLinearSolvers_SRCS "*.h")
INSTALL(FILES
${Eigen_IterativeLinearSolvers_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/IterativeLinearSolvers COMPONENT Devel
)

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_OrderingMethods_SRCS "*.h")
INSTALL(FILES
${Eigen_OrderingMethods_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/OrderingMethods COMPONENT Devel
)

View File

@ -1,6 +0,0 @@
FILE(GLOB Eigen_Sparse_SRCS "*.h")
INSTALL(FILES
${Eigen_Sparse_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Sparse COMPONENT Devel
)

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_SparseCholesky_SRCS "*.h")
INSTALL(FILES
${Eigen_SparseCholesky_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/SparseCholesky COMPONENT Devel
)

View File

@ -478,7 +478,7 @@ public:
}; };
/** \class SimplicialCholesky /** \class SimplicialCholesky
* \deprecated * \deprecated use SimplicialLDLt or class SimplicialLLt
* \sa class SimplicialLDLt, class SimplicialLLt * \sa class SimplicialLDLt, class SimplicialLLt
*/ */
template<typename _MatrixType, int _UpLo> template<typename _MatrixType, int _UpLo>
@ -498,6 +498,7 @@ public:
typedef internal::traits<SimplicialLLt<MatrixType,UpLo> > LLtTraits; typedef internal::traits<SimplicialLLt<MatrixType,UpLo> > LLtTraits;
public: public:
SimplicialCholesky() : Base(), m_LDLt(true) {} SimplicialCholesky() : Base(), m_LDLt(true) {}
SimplicialCholesky(const MatrixType& matrix) SimplicialCholesky(const MatrixType& matrix)
: Base(), m_LDLt(true) : Base(), m_LDLt(true)
{ {

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_SparseCore_SRCS "*.h")
INSTALL(FILES
${Eigen_SparseCore_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/SparseCore COMPONENT Devel
)

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_SuperLUSupport_SRCS "*.h")
INSTALL(FILES
${Eigen_SuperLUSupport_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/SuperLUSupport COMPONENT Devel
)

View File

@ -0,0 +1,6 @@
FILE(GLOB Eigen_UmfPackSupport_SRCS "*.h")
INSTALL(FILES
${Eigen_UmfPackSupport_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/UmfPackSupport COMPONENT Devel
)

View File

@ -12,6 +12,46 @@ foreach(i RANGE 1 999)
) )
endforeach() endforeach()
# configure blas/lapack (use Eigen's ones)
set(BLAS_FOUND TRUE)
set(LAPACK_FOUND TRUE)
set(BLAS_LIBRARIES eigen_blas)
set(LAPACK_LIBRARIES eigen_lapack)
set(SPARSE_LIBS " ")
find_package(Cholmod)
if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)
add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
include_directories(${CHOLMOD_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "Cholmod, ")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "Cholmod, ")
endif()
find_package(Umfpack)
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, ")
endif()
find_package(SuperLU)
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, ")
endif()
find_package(GSL) find_package(GSL)
if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9) if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9)
set(GSL_FOUND "") set(GSL_FOUND "")
@ -123,7 +163,7 @@ endif(QT4_FOUND)
ei_add_test(sparse_vector) ei_add_test(sparse_vector)
ei_add_test(sparse_basic) ei_add_test(sparse_basic)
ei_add_test(sparse_product) ei_add_test(sparse_product)
ei_add_test(sparse_solvers "" "${SPARSE_LIBS}") ei_add_test(sparse_solvers)
ei_add_test(umeyama) ei_add_test(umeyama)
ei_add_test(householder) ei_add_test(householder)
ei_add_test(swap) ei_add_test(swap)
@ -140,6 +180,20 @@ ei_add_test(sizeoverflow)
ei_add_test(prec_inverse_4x4) ei_add_test(prec_inverse_4x4)
ei_add_test(simplicial_cholesky)
ei_add_test(conjugate_gradient)
ei_add_test(bicgstab)
if(UMFPACK_FOUND)
ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")
endif()
if(SUPERLU_FOUND)
ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")
endif()
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower) string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
if(cmake_cxx_compiler_tolower MATCHES "qcc") if(cmake_cxx_compiler_tolower MATCHES "qcc")
set(CXX_IS_QCC "ON") set(CXX_IS_QCC "ON")

View File

@ -23,17 +23,19 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>. // Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "sparse_solver.h" #include "sparse_solver.h"
#include <Eigen/IterativeSolvers> #include <Eigen/IterativeLinearSolvers>
template<typename T> void test_bicgstab_T() template<typename T> void test_bicgstab_T()
{ {
BiCGSTAB<SparseMatrix<T>, DiagonalPreconditioner<T> > bicgstab_colmajor_diag; BiCGSTAB<SparseMatrix<T>, DiagonalPreconditioner<T> > bicgstab_colmajor_diag;
BiCGSTAB<SparseMatrix<T>, IdentityPreconditioner > bicgstab_colmajor_I; BiCGSTAB<SparseMatrix<T>, IdentityPreconditioner > bicgstab_colmajor_I;
BiCGSTAB<SparseMatrix<T>, IncompleteLU<T> > bicgstab_colmajor_ilu; //BiCGSTAB<SparseMatrix<T>, IncompleteLU<T> > bicgstab_colmajor_ilu;
//BiCGSTAB<SparseMatrix<T>, SSORPreconditioner<T> > bicgstab_colmajor_ssor;
CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_diag) ); CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_diag) );
CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_I) ); CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_I) );
CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ilu) ); //CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ilu) );
//CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ssor) );
} }
void test_bicgstab() void test_bicgstab()

View File

@ -23,7 +23,7 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>. // Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "sparse_solver.h" #include "sparse_solver.h"
#include <Eigen/IterativeSolvers> #include <Eigen/IterativeLinearSolvers>
template<typename T> void test_conjugate_gradient_T() template<typename T> void test_conjugate_gradient_T()
{ {

View File

@ -23,7 +23,7 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>. // Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "sparse.h" #include "sparse.h"
#include <Eigen/SparseExtra> #include <Eigen/SparseCore>
template<typename Solver, typename Rhs, typename DenseMat, typename DenseRhs> template<typename Solver, typename Rhs, typename DenseMat, typename DenseRhs>
void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b, const DenseMat& dA, const DenseRhs& db) void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b, const DenseMat& dA, const DenseRhs& db)
@ -39,7 +39,7 @@ void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A,
solver.compute(A); solver.compute(A);
if (solver.info() != Success) if (solver.info() != Success)
{ {
std::cerr << "sparse SPD: factorization failed (check_sparse_solving)\n"; std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";
exit(0); exit(0);
return; return;
} }
@ -64,7 +64,7 @@ void check_sparse_determinant(Solver& solver, const typename Solver::MatrixType&
solver.compute(A); solver.compute(A);
if (solver.info() != Success) if (solver.info() != Success)
{ {
std::cerr << "sparse SPD: factorization failed (check_sparse_determinant)\n"; std::cerr << "sparse solver testing: factorization failed (check_sparse_determinant)\n";
return; return;
} }

View File

@ -1,5 +1,5 @@
set(Eigen_HEADERS AdolcForward BVH IterativeSolvers MatrixFunctions MoreVectorization AutoDiff AlignedVector3 Polynomials set(Eigen_HEADERS AdolcForward BVH IterativeSolvers MatrixFunctions MoreVectorization AutoDiff AlignedVector3 Polynomials
CholmodSupport FFT NonLinearOptimization SparseExtra SuperLUSupport UmfPackSupport IterativeSolvers FFT NonLinearOptimization SparseExtra IterativeSolvers
NumericalDiff Skyline MPRealSupport OpenGLSupport KroneckerProduct NumericalDiff Skyline MPRealSupport OpenGLSupport KroneckerProduct
) )

View File

@ -42,15 +42,12 @@ namespace Eigen {
//@{ //@{
#include "../../Eigen/src/misc/Solve.h" #include "../../Eigen/src/misc/Solve.h"
#include "src/SparseExtra/Solve.h" #include "../../Eigen/src/misc/SparseSolve.h"
#include "src/IterativeSolvers/IterativeSolverBase.h"
#include "src/IterativeSolvers/IterationController.h" #include "src/IterativeSolvers/IterationController.h"
#include "src/IterativeSolvers/ConstrainedConjGrad.h" #include "src/IterativeSolvers/ConstrainedConjGrad.h"
#include "src/IterativeSolvers/BasicPreconditioners.h"
#include "src/IterativeSolvers/ConjugateGradient.h"
#include "src/IterativeSolvers/BiCGSTAB.h"
#include "src/IterativeSolvers/IncompleteLU.h" #include "src/IterativeSolvers/IncompleteLU.h"
#include "src/IterativeSolvers/SSORPreconditioner.h"
//@} //@}

View File

@ -54,6 +54,7 @@ enum {
}; };
#include "../../Eigen/src/misc/Solve.h" #include "../../Eigen/src/misc/Solve.h"
#include "../../Eigen/src/misc/SparseSolve.h"
#include "src/SparseExtra/DynamicSparseMatrix.h" #include "src/SparseExtra/DynamicSparseMatrix.h"
#include "src/SparseExtra/BlockOfDynamicSparseMatrix.h" #include "src/SparseExtra/BlockOfDynamicSparseMatrix.h"
@ -61,10 +62,6 @@ enum {
#include "src/SparseExtra/MarketIO.h" #include "src/SparseExtra/MarketIO.h"
#include "src/SparseExtra/Solve.h"
#include "src/SparseExtra/Amd.h"
#include "src/SparseExtra/SimplicialCholesky.h"
#include "src/SparseExtra/SparseLLT.h" #include "src/SparseExtra/SparseLLT.h"
#include "src/SparseExtra/SparseLDLTLegacy.h" #include "src/SparseExtra/SparseLDLTLegacy.h"
#include "src/SparseExtra/SparseLU.h" #include "src/SparseExtra/SparseLU.h"

View File

@ -1,520 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CHOLMODSUPPORT_LEGACY_H
#define EIGEN_CHOLMODSUPPORT_LEGACY_H
namespace internal {
template<typename Scalar, typename CholmodType>
void cholmod_configure_matrix_legacy(CholmodType& mat)
{
if (internal::is_same<Scalar,float>::value)
{
mat.xtype = CHOLMOD_REAL;
mat.dtype = CHOLMOD_SINGLE;
}
else if (internal::is_same<Scalar,double>::value)
{
mat.xtype = CHOLMOD_REAL;
mat.dtype = CHOLMOD_DOUBLE;
}
else if (internal::is_same<Scalar,std::complex<float> >::value)
{
mat.xtype = CHOLMOD_COMPLEX;
mat.dtype = CHOLMOD_SINGLE;
}
else if (internal::is_same<Scalar,std::complex<double> >::value)
{
mat.xtype = CHOLMOD_COMPLEX;
mat.dtype = CHOLMOD_DOUBLE;
}
else
{
eigen_assert(false && "Scalar type not supported by CHOLMOD");
}
}
template<typename _MatrixType>
cholmod_sparse cholmod_map_eigen_to_sparse(_MatrixType& mat)
{
typedef typename _MatrixType::Scalar Scalar;
cholmod_sparse res;
res.nzmax = mat.nonZeros();
res.nrow = mat.rows();;
res.ncol = mat.cols();
res.p = mat._outerIndexPtr();
res.i = mat._innerIndexPtr();
res.x = mat._valuePtr();
res.xtype = CHOLMOD_REAL;
res.itype = CHOLMOD_INT;
res.sorted = 1;
res.packed = 1;
res.dtype = 0;
res.stype = -1;
internal::cholmod_configure_matrix_legacy<Scalar>(res);
if (_MatrixType::Flags & SelfAdjoint)
{
if (_MatrixType::Flags & Upper)
res.stype = 1;
else if (_MatrixType::Flags & Lower)
res.stype = -1;
else
res.stype = 0;
}
else
res.stype = -1; // by default we consider the lower part
return res;
}
template<typename Derived>
cholmod_dense cholmod_map_eigen_to_dense(MatrixBase<Derived>& mat)
{
EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
typedef typename Derived::Scalar Scalar;
cholmod_dense res;
res.nrow = mat.rows();
res.ncol = mat.cols();
res.nzmax = res.nrow * res.ncol;
res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
res.x = mat.derived().data();
res.z = 0;
internal::cholmod_configure_matrix_legacy<Scalar>(res);
return res;
}
template<typename Scalar, int Flags, typename Index>
MappedSparseMatrix<Scalar,Flags,Index> map_cholmod_sparse_to_eigen(cholmod_sparse& cm)
{
return MappedSparseMatrix<Scalar,Flags,Index>
(cm.nrow, cm.ncol, reinterpret_cast<Index*>(cm.p)[cm.ncol],
reinterpret_cast<Index*>(cm.p), reinterpret_cast<Index*>(cm.i),reinterpret_cast<Scalar*>(cm.x) );
}
} // namespace internal
/** \deprecated use class SimplicialLDLT, or class SimplicialLLT, class ConjugateGradient */
template<typename _MatrixType>
class SparseLLT<_MatrixType, Cholmod> : public SparseLLT<_MatrixType>
{
protected:
typedef SparseLLT<_MatrixType> Base;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
typedef typename Base::CholMatrixType CholMatrixType;
using Base::MatrixLIsDirty;
using Base::SupernodalFactorIsDirty;
using Base::m_flags;
using Base::m_matrix;
using Base::m_status;
public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Index Index;
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLLT(int flags = 0)
: Base(flags), m_cholmodFactor(0)
{
cholmod_start(&m_cholmod);
}
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLLT(const MatrixType& matrix, int flags = 0)
: Base(flags), m_cholmodFactor(0)
{
cholmod_start(&m_cholmod);
compute(matrix);
}
~SparseLLT()
{
if (m_cholmodFactor)
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
cholmod_finish(&m_cholmod);
}
inline const CholMatrixType& matrixL() const;
template<typename Derived>
bool solveInPlace(MatrixBase<Derived> &b) const;
template<typename Rhs>
inline const internal::solve_retval<SparseLLT<MatrixType, Cholmod>, Rhs>
solve(const MatrixBase<Rhs>& b) const
{
eigen_assert(true && "SparseLLT is not initialized.");
return internal::solve_retval<SparseLLT<MatrixType, Cholmod>, Rhs>(*this, b.derived());
}
void compute(const MatrixType& matrix);
inline Index cols() const { return m_matrix.cols(); }
inline Index rows() const { return m_matrix.rows(); }
inline const cholmod_factor* cholmodFactor() const
{ return m_cholmodFactor; }
inline cholmod_common* cholmodCommon() const
{ return &m_cholmod; }
bool succeeded() const;
protected:
mutable cholmod_common m_cholmod;
cholmod_factor* m_cholmodFactor;
};
namespace internal {
template<typename _MatrixType, typename Rhs>
struct solve_retval<SparseLLT<_MatrixType, Cholmod>, Rhs>
: solve_retval_base<SparseLLT<_MatrixType, Cholmod>, Rhs>
{
typedef SparseLLT<_MatrixType, Cholmod> SpLLTDecType;
EIGEN_MAKE_SOLVE_HELPERS(SpLLTDecType,Rhs)
template<typename Dest> void evalTo(Dest& dst) const
{
//Index size = dec().cholmodFactor()->n;
eigen_assert((Index)dec().cholmodFactor()->n==rhs().rows());
cholmod_factor* cholmodFactor = const_cast<cholmod_factor*>(dec().cholmodFactor());
cholmod_common* cholmodCommon = const_cast<cholmod_common*>(dec().cholmodCommon());
// this uses Eigen's triangular sparse solver
// if (m_status & MatrixLIsDirty)
// matrixL();
// Base::solveInPlace(b);
// as long as our own triangular sparse solver is not fully optimal,
// let's use CHOLMOD's one:
cholmod_dense cdb = internal::cholmod_map_eigen_to_dense(rhs().const_cast_derived());
cholmod_dense* x = cholmod_solve(CHOLMOD_A, cholmodFactor, &cdb, cholmodCommon);
dst = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x), rhs().rows());
cholmod_free_dense(&x, cholmodCommon);
}
};
} // namespace internal
template<typename _MatrixType>
void SparseLLT<_MatrixType,Cholmod>::compute(const _MatrixType& a)
{
if (m_cholmodFactor)
{
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
m_cholmodFactor = 0;
}
cholmod_sparse A = internal::cholmod_map_eigen_to_sparse(const_cast<_MatrixType&>(a));
// m_cholmod.supernodal = CHOLMOD_AUTO;
// TODO
// if (m_flags&IncompleteFactorization)
// {
// m_cholmod.nmethods = 1;
// m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
// m_cholmod.postorder = 0;
// }
// else
// {
// m_cholmod.nmethods = 1;
// m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
// m_cholmod.postorder = 0;
// }
// m_cholmod.final_ll = 1;
m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
cholmod_factorize(&A, m_cholmodFactor, &m_cholmod);
this->m_status = (this->m_status & ~Base::SupernodalFactorIsDirty) | Base::MatrixLIsDirty;
}
// TODO
template<typename _MatrixType>
bool SparseLLT<_MatrixType,Cholmod>::succeeded() const
{ return true; }
template<typename _MatrixType>
inline const typename SparseLLT<_MatrixType,Cholmod>::CholMatrixType&
SparseLLT<_MatrixType,Cholmod>::matrixL() const
{
if (this->m_status & Base::MatrixLIsDirty)
{
eigen_assert(!(this->m_status & Base::SupernodalFactorIsDirty));
cholmod_sparse* cmRes = cholmod_factor_to_sparse(m_cholmodFactor, &m_cholmod);
const_cast<typename Base::CholMatrixType&>(this->m_matrix) =
internal::map_cholmod_sparse_to_eigen<Scalar,ColMajor,Index>(*cmRes);
free(cmRes);
this->m_status = (this->m_status & ~Base::MatrixLIsDirty);
}
return this->m_matrix;
}
template<typename _MatrixType>
template<typename Derived>
bool SparseLLT<_MatrixType,Cholmod>::solveInPlace(MatrixBase<Derived> &b) const
{
//Index size = m_cholmodFactor->n;
eigen_assert((Index)m_cholmodFactor->n==b.rows());
// this uses Eigen's triangular sparse solver
// if (m_status & MatrixLIsDirty)
// matrixL();
// Base::solveInPlace(b);
// as long as our own triangular sparse solver is not fully optimal,
// let's use CHOLMOD's one:
cholmod_dense cdb = internal::cholmod_map_eigen_to_dense(b);
cholmod_dense* x = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &cdb, &m_cholmod);
eigen_assert(x && "Eigen: cholmod_solve failed.");
b = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x),b.rows());
cholmod_free_dense(&x, &m_cholmod);
return true;
}
template<typename _MatrixType>
class SparseLDLT<_MatrixType,Cholmod> : public SparseLDLT<_MatrixType>
{
protected:
typedef SparseLDLT<_MatrixType> Base;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
using Base::MatrixLIsDirty;
using Base::SupernodalFactorIsDirty;
using Base::m_flags;
using Base::m_matrix;
using Base::m_status;
public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Index Index;
SparseLDLT(int flags = 0)
: Base(flags), m_cholmodFactor(0)
{
cholmod_start(&m_cholmod);
}
SparseLDLT(const _MatrixType& matrix, int flags = 0)
: Base(flags), m_cholmodFactor(0)
{
cholmod_start(&m_cholmod);
compute(matrix);
}
~SparseLDLT()
{
if (m_cholmodFactor)
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
cholmod_finish(&m_cholmod);
}
inline const typename Base::CholMatrixType& matrixL(void) const;
template<typename Derived>
void solveInPlace(MatrixBase<Derived> &b) const;
template<typename Rhs>
inline const internal::solve_retval<SparseLDLT<MatrixType, Cholmod>, Rhs>
solve(const MatrixBase<Rhs>& b) const
{
eigen_assert(true && "SparseLDLT is not initialized.");
return internal::solve_retval<SparseLDLT<MatrixType, Cholmod>, Rhs>(*this, b.derived());
}
void compute(const _MatrixType& matrix);
inline Index cols() const { return m_matrix.cols(); }
inline Index rows() const { return m_matrix.rows(); }
inline const cholmod_factor* cholmodFactor() const
{ return m_cholmodFactor; }
inline cholmod_common* cholmodCommon() const
{ return &m_cholmod; }
bool succeeded() const;
protected:
mutable cholmod_common m_cholmod;
cholmod_factor* m_cholmodFactor;
};
namespace internal {
template<typename _MatrixType, typename Rhs>
struct solve_retval<SparseLDLT<_MatrixType, Cholmod>, Rhs>
: solve_retval_base<SparseLDLT<_MatrixType, Cholmod>, Rhs>
{
typedef SparseLDLT<_MatrixType, Cholmod> SpLDLTDecType;
EIGEN_MAKE_SOLVE_HELPERS(SpLDLTDecType,Rhs)
template<typename Dest> void evalTo(Dest& dst) const
{
//Index size = dec().cholmodFactor()->n;
eigen_assert((Index)dec().cholmodFactor()->n==rhs().rows());
cholmod_factor* cholmodFactor = const_cast<cholmod_factor*>(dec().cholmodFactor());
cholmod_common* cholmodCommon = const_cast<cholmod_common*>(dec().cholmodCommon());
// this uses Eigen's triangular sparse solver
// if (m_status & MatrixLIsDirty)
// matrixL();
// Base::solveInPlace(b);
// as long as our own triangular sparse solver is not fully optimal,
// let's use CHOLMOD's one:
cholmod_dense cdb = internal::cholmod_map_eigen_to_dense(rhs().const_cast_derived());
cholmod_dense* x = cholmod_solve(CHOLMOD_LDLt, cholmodFactor, &cdb, cholmodCommon);
dst = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x), rhs().rows());
cholmod_free_dense(&x, cholmodCommon);
}
};
} // namespace internal
template<typename _MatrixType>
void SparseLDLT<_MatrixType,Cholmod>::compute(const _MatrixType& a)
{
if (m_cholmodFactor)
{
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
m_cholmodFactor = 0;
}
cholmod_sparse A = internal::cholmod_map_eigen_to_sparse(const_cast<_MatrixType&>(a));
//m_cholmod.supernodal = CHOLMOD_AUTO;
m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
//m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
// TODO
if (this->m_flags & IncompleteFactorization)
{
m_cholmod.nmethods = 1;
//m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
m_cholmod.method[0].ordering = CHOLMOD_COLAMD;
m_cholmod.postorder = 1;
}
else
{
m_cholmod.nmethods = 1;
m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
m_cholmod.postorder = 0;
}
m_cholmod.final_ll = 0;
m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
cholmod_factorize(&A, m_cholmodFactor, &m_cholmod);
this->m_status = (this->m_status & ~Base::SupernodalFactorIsDirty) | Base::MatrixLIsDirty;
}
// TODO
template<typename _MatrixType>
bool SparseLDLT<_MatrixType,Cholmod>::succeeded() const
{ return true; }
template<typename _MatrixType>
inline const typename SparseLDLT<_MatrixType>::CholMatrixType&
SparseLDLT<_MatrixType,Cholmod>::matrixL() const
{
if (this->m_status & Base::MatrixLIsDirty)
{
eigen_assert(!(this->m_status & Base::SupernodalFactorIsDirty));
cholmod_sparse* cmRes = cholmod_factor_to_sparse(m_cholmodFactor, &m_cholmod);
const_cast<typename Base::CholMatrixType&>(this->m_matrix) = MappedSparseMatrix<Scalar>(*cmRes);
free(cmRes);
this->m_status = (this->m_status & ~Base::MatrixLIsDirty);
}
return this->m_matrix;
}
template<typename _MatrixType>
template<typename Derived>
void SparseLDLT<_MatrixType,Cholmod>::solveInPlace(MatrixBase<Derived> &b) const
{
//Index size = m_cholmodFactor->n;
eigen_assert((Index)m_cholmodFactor->n == b.rows());
// this uses Eigen's triangular sparse solver
// if (m_status & MatrixLIsDirty)
// matrixL();
// Base::solveInPlace(b);
// as long as our own triangular sparse solver is not fully optimal,
// let's use CHOLMOD's one:
cholmod_dense cdb = internal::cholmod_map_eigen_to_dense(b);
cholmod_dense* x = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &cdb, &m_cholmod);
b = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x),b.rows());
cholmod_free_dense(&x, &m_cholmod);
}
#endif // EIGEN_CHOLMODSUPPORT_LEGACY_H

View File

@ -1,407 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_SUPERLUSUPPORT_LEGACY_H
#define EIGEN_SUPERLUSUPPORT_LEGACY_H
/** \deprecated use class BiCGSTAB, class SuperLU, or class UmfPackLU */
template<typename MatrixType>
class SparseLU<MatrixType,SuperLULegacy> : public SparseLU<MatrixType>
{
protected:
typedef SparseLU<MatrixType> Base;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
typedef Matrix<Scalar,Dynamic,1> Vector;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef SparseMatrix<Scalar,Lower|UnitDiag> LMatrixType;
typedef SparseMatrix<Scalar,Upper> UMatrixType;
using Base::m_flags;
using Base::m_status;
public:
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLU(int flags = NaturalOrdering)
: Base(flags)
{
}
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLU(const MatrixType& matrix, int flags = NaturalOrdering)
: Base(flags)
{
compute(matrix);
}
~SparseLU()
{
Destroy_SuperNode_Matrix(&m_sluL);
Destroy_CompCol_Matrix(&m_sluU);
}
inline const LMatrixType& matrixL() const
{
if (m_extractedDataAreDirty) extractData();
return m_l;
}
inline const UMatrixType& matrixU() const
{
if (m_extractedDataAreDirty) extractData();
return m_u;
}
inline const IntColVectorType& permutationP() const
{
if (m_extractedDataAreDirty) extractData();
return m_p;
}
inline const IntRowVectorType& permutationQ() const
{
if (m_extractedDataAreDirty) extractData();
return m_q;
}
Scalar determinant() const;
template<typename BDerived, typename XDerived>
bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x, const int transposed = SvNoTrans) const;
void compute(const MatrixType& matrix);
protected:
void extractData() const;
protected:
// cached data to reduce reallocation, etc.
mutable LMatrixType m_l;
mutable UMatrixType m_u;
mutable IntColVectorType m_p;
mutable IntRowVectorType m_q;
mutable SparseMatrix<Scalar> m_matrix;
mutable SluMatrix m_sluA;
mutable SuperMatrix m_sluL, m_sluU;
mutable SluMatrix m_sluB, m_sluX;
mutable SuperLUStat_t m_sluStat;
mutable superlu_options_t m_sluOptions;
mutable std::vector<int> m_sluEtree;
mutable std::vector<RealScalar> m_sluRscale, m_sluCscale;
mutable std::vector<RealScalar> m_sluFerr, m_sluBerr;
mutable char m_sluEqued;
mutable bool m_extractedDataAreDirty;
};
template<typename MatrixType>
void SparseLU<MatrixType,SuperLULegacy>::compute(const MatrixType& a)
{
const int size = a.rows();
m_matrix = a;
set_default_options(&m_sluOptions);
m_sluOptions.ColPerm = NATURAL;
m_sluOptions.PrintStat = NO;
m_sluOptions.ConditionNumber = NO;
m_sluOptions.Trans = NOTRANS;
// m_sluOptions.Equil = NO;
switch (Base::orderingMethod())
{
case NaturalOrdering : m_sluOptions.ColPerm = NATURAL; break;
case MinimumDegree_AT_PLUS_A : m_sluOptions.ColPerm = MMD_AT_PLUS_A; break;
case MinimumDegree_ATA : m_sluOptions.ColPerm = MMD_ATA; break;
case ColApproxMinimumDegree : m_sluOptions.ColPerm = COLAMD; break;
default:
//std::cerr << "Eigen: ordering method \"" << Base::orderingMethod() << "\" not supported by the SuperLU backend\n";
m_sluOptions.ColPerm = NATURAL;
};
m_sluA = internal::asSluMatrix(m_matrix);
memset(&m_sluL,0,sizeof m_sluL);
memset(&m_sluU,0,sizeof m_sluU);
m_sluEqued = 'N';
int info = 0;
m_p.resize(size);
m_q.resize(size);
m_sluRscale.resize(size);
m_sluCscale.resize(size);
m_sluEtree.resize(size);
RealScalar recip_pivot_gross, rcond;
RealScalar ferr, berr;
// set empty B and X
m_sluB.setStorageType(SLU_DN);
m_sluB.setScalarType<Scalar>();
m_sluB.Mtype = SLU_GE;
m_sluB.storage.values = 0;
m_sluB.nrow = m_sluB.ncol = 0;
m_sluB.storage.lda = size;
m_sluX = m_sluB;
StatInit(&m_sluStat);
if (m_flags&IncompleteFactorization)
{
#ifdef EIGEN_SUPERLU_HAS_ILU
ilu_set_default_options(&m_sluOptions);
// no attempt to preserve column sum
m_sluOptions.ILU_MILU = SILU;
// only basic ILU(k) support -- no direct control over memory consumption
// better to use ILU_DropRule = DROP_BASIC | DROP_AREA
// and set ILU_FillFactor to max memory growth
m_sluOptions.ILU_DropRule = DROP_BASIC;
m_sluOptions.ILU_DropTol = Base::m_precision;
SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0],
&m_sluEqued, &m_sluRscale[0], &m_sluCscale[0],
&m_sluL, &m_sluU,
NULL, 0,
&m_sluB, &m_sluX,
&recip_pivot_gross, &rcond,
&m_sluStat, &info, Scalar());
#else
//std::cerr << "Incomplete factorization is only available in SuperLU v4\n";
Base::m_succeeded = false;
return;
#endif
}
else
{
SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0],
&m_sluEqued, &m_sluRscale[0], &m_sluCscale[0],
&m_sluL, &m_sluU,
NULL, 0,
&m_sluB, &m_sluX,
&recip_pivot_gross, &rcond,
&ferr, &berr,
&m_sluStat, &info, Scalar());
}
StatFree(&m_sluStat);
m_extractedDataAreDirty = true;
// FIXME how to better check for errors ???
Base::m_succeeded = (info == 0);
}
template<typename MatrixType>
template<typename BDerived,typename XDerived>
bool SparseLU<MatrixType,SuperLULegacy>::solve(const MatrixBase<BDerived> &b,
MatrixBase<XDerived> *x, const int transposed) const
{
const int size = m_matrix.rows();
const int rhsCols = b.cols();
eigen_assert(size==b.rows());
switch (transposed) {
case SvNoTrans : m_sluOptions.Trans = NOTRANS; break;
case SvTranspose : m_sluOptions.Trans = TRANS; break;
case SvAdjoint : m_sluOptions.Trans = CONJ; break;
default:
//std::cerr << "Eigen: transposition option \"" << transposed << "\" not supported by the SuperLU backend\n";
m_sluOptions.Trans = NOTRANS;
}
m_sluOptions.Fact = FACTORED;
m_sluOptions.IterRefine = NOREFINE;
m_sluFerr.resize(rhsCols);
m_sluBerr.resize(rhsCols);
m_sluB = SluMatrix::Map(b.const_cast_derived());
m_sluX = SluMatrix::Map(x->derived());
typename BDerived::PlainObject b_cpy;
if(m_sluEqued!='N')
{
b_cpy = b;
m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
}
StatInit(&m_sluStat);
int info = 0;
RealScalar recip_pivot_gross, rcond;
if (m_flags&IncompleteFactorization)
{
#ifdef EIGEN_SUPERLU_HAS_ILU
SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0],
&m_sluEqued, &m_sluRscale[0], &m_sluCscale[0],
&m_sluL, &m_sluU,
NULL, 0,
&m_sluB, &m_sluX,
&recip_pivot_gross, &rcond,
&m_sluStat, &info, Scalar());
#else
//std::cerr << "Incomplete factorization is only available in SuperLU v4\n";
return false;
#endif
}
else
{
SuperLU_gssvx(
&m_sluOptions, &m_sluA,
m_q.data(), m_p.data(),
&m_sluEtree[0], &m_sluEqued,
&m_sluRscale[0], &m_sluCscale[0],
&m_sluL, &m_sluU,
NULL, 0,
&m_sluB, &m_sluX,
&recip_pivot_gross, &rcond,
&m_sluFerr[0], &m_sluBerr[0],
&m_sluStat, &info, Scalar());
}
StatFree(&m_sluStat);
// reset to previous state
m_sluOptions.Trans = NOTRANS;
return info==0;
}
//
// the code of this extractData() function has been adapted from the SuperLU's Matlab support code,
//
// Copyright (c) 1994 by Xerox Corporation. All rights reserved.
//
// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
//
template<typename MatrixType>
void SparseLU<MatrixType,SuperLULegacy>::extractData() const
{
if (m_extractedDataAreDirty)
{
int upper;
int fsupc, istart, nsupr;
int lastl = 0, lastu = 0;
SCformat *Lstore = static_cast<SCformat*>(m_sluL.Store);
NCformat *Ustore = static_cast<NCformat*>(m_sluU.Store);
Scalar *SNptr;
const int size = m_matrix.rows();
m_l.resize(size,size);
m_l.resizeNonZeros(Lstore->nnz);
m_u.resize(size,size);
m_u.resizeNonZeros(Ustore->nnz);
int* Lcol = m_l._outerIndexPtr();
int* Lrow = m_l._innerIndexPtr();
Scalar* Lval = m_l._valuePtr();
int* Ucol = m_u._outerIndexPtr();
int* Urow = m_u._innerIndexPtr();
Scalar* Uval = m_u._valuePtr();
Ucol[0] = 0;
Ucol[0] = 0;
/* for each supernode */
for (int k = 0; k <= Lstore->nsuper; ++k)
{
fsupc = L_FST_SUPC(k);
istart = L_SUB_START(fsupc);
nsupr = L_SUB_START(fsupc+1) - istart;
upper = 1;
/* for each column in the supernode */
for (int j = fsupc; j < L_FST_SUPC(k+1); ++j)
{
SNptr = &((Scalar*)Lstore->nzval)[L_NZ_START(j)];
/* Extract U */
for (int i = U_NZ_START(j); i < U_NZ_START(j+1); ++i)
{
Uval[lastu] = ((Scalar*)Ustore->nzval)[i];
/* Matlab doesn't like explicit zero. */
if (Uval[lastu] != 0.0)
Urow[lastu++] = U_SUB(i);
}
for (int i = 0; i < upper; ++i)
{
/* upper triangle in the supernode */
Uval[lastu] = SNptr[i];
/* Matlab doesn't like explicit zero. */
if (Uval[lastu] != 0.0)
Urow[lastu++] = L_SUB(istart+i);
}
Ucol[j+1] = lastu;
/* Extract L */
Lval[lastl] = 1.0; /* unit diagonal */
Lrow[lastl++] = L_SUB(istart + upper - 1);
for (int i = upper; i < nsupr; ++i)
{
Lval[lastl] = SNptr[i];
/* Matlab doesn't like explicit zero. */
if (Lval[lastl] != 0.0)
Lrow[lastl++] = L_SUB(istart+i);
}
Lcol[j+1] = lastl;
++upper;
} /* for j ... */
} /* for k ... */
// squeeze the matrices :
m_l.resizeNonZeros(lastl);
m_u.resizeNonZeros(lastu);
m_extractedDataAreDirty = false;
}
}
template<typename MatrixType>
typename SparseLU<MatrixType,SuperLULegacy>::Scalar SparseLU<MatrixType,SuperLULegacy>::determinant() const
{
assert((!NumTraits<Scalar>::IsComplex) && "This function is not implemented for complex yet");
if (m_extractedDataAreDirty)
extractData();
// TODO this code could be moved to the default/base backend
// FIXME perhaps we have to take into account the scale factors m_sluRscale and m_sluCscale ???
Scalar det = Scalar(1);
for (int j=0; j<m_u.cols(); ++j)
{
if (m_u._outerIndexPtr()[j+1]-m_u._outerIndexPtr()[j] > 0)
{
int lastId = m_u._outerIndexPtr()[j+1]-1;
eigen_assert(m_u._innerIndexPtr()[lastId]<=j);
if (m_u._innerIndexPtr()[lastId]==j)
{
det *= m_u._valuePtr()[lastId];
}
}
// std::cout << m_sluRscale[j] << " " << m_sluCscale[j] << " \n";
}
return det;
}
#endif // EIGEN_SUPERLUSUPPORT_LEGACY_H

View File

@ -1,257 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_UMFPACKSUPPORT_LEGACY_H
#define EIGEN_UMFPACKSUPPORT_LEGACY_H
/** \deprecated use class BiCGSTAB, class SuperLU, or class UmfPackLU */
template<typename _MatrixType>
class SparseLU<_MatrixType,UmfPack> : public SparseLU<_MatrixType>
{
protected:
typedef SparseLU<_MatrixType> Base;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
typedef Matrix<Scalar,Dynamic,1> Vector;
typedef Matrix<int, 1, _MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, _MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef SparseMatrix<Scalar,Lower|UnitDiag> LMatrixType;
typedef SparseMatrix<Scalar,Upper> UMatrixType;
using Base::m_flags;
using Base::m_status;
public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Index Index;
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLU(int flags = NaturalOrdering)
: Base(flags), m_numeric(0)
{
}
/** \deprecated the entire class is deprecated */
EIGEN_DEPRECATED SparseLU(const MatrixType& matrix, int flags = NaturalOrdering)
: Base(flags), m_numeric(0)
{
compute(matrix);
}
~SparseLU()
{
if (m_numeric)
umfpack_free_numeric(&m_numeric,Scalar());
}
inline const LMatrixType& matrixL() const
{
if (m_extractedDataAreDirty) extractData();
return m_l;
}
inline const UMatrixType& matrixU() const
{
if (m_extractedDataAreDirty) extractData();
return m_u;
}
inline const IntColVectorType& permutationP() const
{
if (m_extractedDataAreDirty) extractData();
return m_p;
}
inline const IntRowVectorType& permutationQ() const
{
if (m_extractedDataAreDirty) extractData();
return m_q;
}
Scalar determinant() const;
template<typename BDerived, typename XDerived>
bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x) const;
template<typename Rhs>
inline const internal::solve_retval<SparseLU<MatrixType, UmfPack>, Rhs>
solve(const MatrixBase<Rhs>& b) const
{
eigen_assert(true && "SparseLU is not initialized.");
return internal::solve_retval<SparseLU<MatrixType, UmfPack>, Rhs>(*this, b.derived());
}
void compute(const MatrixType& matrix);
inline Index cols() const { return m_matrixRef->cols(); }
inline Index rows() const { return m_matrixRef->rows(); }
inline const MatrixType& matrixLU() const
{
//eigen_assert(m_isInitialized && "LU is not initialized.");
return *m_matrixRef;
}
const void* numeric() const
{
return m_numeric;
}
protected:
void extractData() const;
protected:
// cached data:
void* m_numeric;
const MatrixType* m_matrixRef;
mutable LMatrixType m_l;
mutable UMatrixType m_u;
mutable IntColVectorType m_p;
mutable IntRowVectorType m_q;
mutable bool m_extractedDataAreDirty;
};
namespace internal {
template<typename _MatrixType, typename Rhs>
struct solve_retval<SparseLU<_MatrixType, UmfPack>, Rhs>
: solve_retval_base<SparseLU<_MatrixType, UmfPack>, Rhs>
{
typedef SparseLU<_MatrixType, UmfPack> SpLUDecType;
EIGEN_MAKE_SOLVE_HELPERS(SpLUDecType,Rhs)
template<typename Dest> void evalTo(Dest& dst) const
{
const int rhsCols = rhs().cols();
eigen_assert((Rhs::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major rhs yet");
eigen_assert((Dest::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major result yet");
void* numeric = const_cast<void*>(dec().numeric());
EIGEN_UNUSED int errorCode = 0;
for (int j=0; j<rhsCols; ++j)
{
errorCode = umfpack_solve(UMFPACK_A,
dec().matrixLU()._outerIndexPtr(), dec().matrixLU()._innerIndexPtr(), dec().matrixLU()._valuePtr(),
&dst.col(j).coeffRef(0), &rhs().const_cast_derived().col(j).coeffRef(0), numeric, 0, 0);
eigen_assert(!errorCode && "UmfPack could not solve the system.");
}
}
};
} // end namespace internal
template<typename MatrixType>
void SparseLU<MatrixType,UmfPack>::compute(const MatrixType& a)
{
typedef typename MatrixType::Index Index;
const Index rows = a.rows();
const Index cols = a.cols();
eigen_assert((MatrixType::Flags&RowMajorBit)==0 && "Row major matrices are not supported yet");
m_matrixRef = &a;
if (m_numeric)
umfpack_free_numeric(&m_numeric,Scalar());
void* symbolic;
int errorCode = 0;
errorCode = umfpack_symbolic(rows, cols, a._outerIndexPtr(), a._innerIndexPtr(), a._valuePtr(),
&symbolic, 0, 0);
if (errorCode==0)
errorCode = umfpack_numeric(a._outerIndexPtr(), a._innerIndexPtr(), a._valuePtr(),
symbolic, &m_numeric, 0, 0);
umfpack_free_symbolic(&symbolic,Scalar());
m_extractedDataAreDirty = true;
Base::m_succeeded = (errorCode==0);
}
template<typename MatrixType>
void SparseLU<MatrixType,UmfPack>::extractData() const
{
if (m_extractedDataAreDirty)
{
// get size of the data
int lnz, unz, rows, cols, nz_udiag;
umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar());
// allocate data
m_l.resize(rows,(std::min)(rows,cols));
m_l.resizeNonZeros(lnz);
m_u.resize((std::min)(rows,cols),cols);
m_u.resizeNonZeros(unz);
m_p.resize(rows);
m_q.resize(cols);
// extract
umfpack_get_numeric(m_l._outerIndexPtr(), m_l._innerIndexPtr(), m_l._valuePtr(),
m_u._outerIndexPtr(), m_u._innerIndexPtr(), m_u._valuePtr(),
m_p.data(), m_q.data(), 0, 0, 0, m_numeric);
m_extractedDataAreDirty = false;
}
}
template<typename MatrixType>
typename SparseLU<MatrixType,UmfPack>::Scalar SparseLU<MatrixType,UmfPack>::determinant() const
{
Scalar det;
umfpack_get_determinant(&det, 0, m_numeric, 0);
return det;
}
template<typename MatrixType>
template<typename BDerived,typename XDerived>
bool SparseLU<MatrixType,UmfPack>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> *x) const
{
//const int size = m_matrix.rows();
const int rhsCols = b.cols();
// eigen_assert(size==b.rows());
eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major rhs yet");
eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPack backend does not support non col-major result yet");
int errorCode;
for (int j=0; j<rhsCols; ++j)
{
errorCode = umfpack_solve(UMFPACK_A,
m_matrixRef->_outerIndexPtr(), m_matrixRef->_innerIndexPtr(), m_matrixRef->_valuePtr(),
&x->col(j).coeffRef(0), &b.const_cast_derived().col(j).coeffRef(0), m_numeric, 0, 0);
if (errorCode!=0)
return false;
}
// errorCode = umfpack_di_solve(UMFPACK_A,
// m_matrixRef._outerIndexPtr(), m_matrixRef._innerIndexPtr(), m_matrixRef._valuePtr(),
// x->derived().data(), b.derived().data(), m_numeric, 0, 0);
return true;
}
#endif // EIGEN_UMFPACKSUPPORT_H

View File

@ -2,46 +2,6 @@
include_directories(../../test ../../unsupported ../../Eigen include_directories(../../test ../../unsupported ../../Eigen
${CMAKE_CURRENT_BINARY_DIR}/../../test) ${CMAKE_CURRENT_BINARY_DIR}/../../test)
set(SPARSE_LIBS "")
# configure blas/lapack (use Eigen's by default)
set(BLAS_FOUND TRUE)
set(LAPACK_FOUND TRUE)
set(BLAS_LIBRARIES eigen_blas)
set(LAPACK_LIBRARIES eigen_lapack)
find_package(Cholmod)
if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)
add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
include_directories(${CHOLMOD_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "Cholmod, ")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "Cholmod, ")
endif()
find_package(Umfpack)
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, ")
endif()
find_package(SuperLU)
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, ")
endif()
find_package(GoogleHash) find_package(GoogleHash)
if(GOOGLEHASH_FOUND) if(GOOGLEHASH_FOUND)
add_definitions("-DEIGEN_GOOGLEHASH_SUPPORT") add_definitions("-DEIGEN_GOOGLEHASH_SUPPORT")
@ -88,22 +48,6 @@ else()
ei_add_property(EIGEN_MISSING_BACKENDS "MPFR C++, ") ei_add_property(EIGEN_MISSING_BACKENDS "MPFR C++, ")
endif() endif()
ei_add_test(sparse_llt "" "${SPARSE_LIBS}")
ei_add_test(sparse_ldlt "" "${SPARSE_LIBS}")
ei_add_test(sparse_lu_legacy "" "${SPARSE_LIBS}")
ei_add_test(simplicial_cholesky)
ei_add_test(conjugate_gradient)
ei_add_test(bicgstab)
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 "" "") ei_add_test(sparse_extra "" "")
find_package(FFTW) find_package(FFTW)
@ -150,4 +94,3 @@ endif(GSL_FOUND)
ei_add_test(polynomialsolver " " "${GSL_LIBRARIES}" ) ei_add_test(polynomialsolver " " "${GSL_LIBRARIES}" )
ei_add_test(polynomialutils) ei_add_test(polynomialutils)
ei_add_test(kronecker_product) ei_add_test(kronecker_product)
ei_add_test(cg)