Adding Sparse matrix with prefactor related changes

This commit is contained in:
iyaz 2013-05-29 17:25:16 +03:00
parent bb67aa6d0a
commit 57d6bf71bb
2 changed files with 412 additions and 403 deletions

View File

@ -1,252 +1,238 @@
// Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved. // Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved.
// //
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as // 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, // published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version. // or (at your option) any later version.
// //
// Licensees holding a valid commercial license may use this file in // Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software. // accordance with the commercial license agreement provided with the software.
// //
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $URL$
// $Id$ // $Id$
// //
// Author(s) : Gael Guennebaud // Author(s) : Gael Guennebaud
#ifndef CGAL_EIGEN_MATRIX_H #ifndef CGAL_EIGEN_MATRIX_H
#define CGAL_EIGEN_MATRIX_H #define CGAL_EIGEN_MATRIX_H
#include <CGAL/basic.h> // include basic.h before testing #defines #include <CGAL/basic.h> // include basic.h before testing #defines
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse> #include <Eigen/Sparse>
namespace CGAL { namespace CGAL {
/// The class Eigen_sparse_matrix /// The class Eigen_sparse_matrix
/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>. /// is a C++ wrapper around Eigen' matrix type SparseMatrix<>.
/// ///
/// This kind of matrix can be either symmetric or not. Symmetric /// This kind of matrix can be either symmetric or not. Symmetric
/// matrices store only the lower triangle. /// matrices store only the lower triangle.
/// ///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. /// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
/// ///
/// @heading Parameters: /// @heading Parameters:
/// @param T Number type. /// @param T Number type.
template<class T> template<class T, int Options = Eigen::RowMajor>
struct Eigen_sparse_matrix struct Eigen_sparse_matrix
{ {
// Public types // Public types
public: public:
typedef Eigen::SparseMatrix<T> EigenType; typedef Eigen::SparseMatrix<T, Options> EigenType;
typedef T NT; typedef T NT;
// Public operations // Public operations
public: public:
/// Create a square matrix initialized with zeros. /// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(int dim, ///< Matrix dimension. Eigen_sparse_matrix(int dim, ///< Matrix dimension.
bool is_symmetric = false) ///< Symmetric/hermitian? bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false), m_matrix(dim,dim) : m_is_uptodate(false), m_matrix(dim,dim)
{ {
CGAL_precondition(dim > 0); CGAL_precondition(dim > 0);
m_is_symmetric = is_symmetric; m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid // reserve memory for a regular 3D grid
m_triplets.reserve(dim); m_triplets.reserve(dim);
} }
/// Create a rectangular matrix initialized with zeros. /// Create a rectangular matrix initialized with zeros.
/// ///
/// @commentheading Precondition: rows == columns if is_symmetric is true. /// @commentheading Precondition: rows == columns if is_symmetric is true.
Eigen_sparse_matrix(int rows, ///< Number of rows. Eigen_sparse_matrix(int rows, ///< Number of rows.
int columns, ///< Number of columns. int columns, ///< Number of columns.
bool is_symmetric = false) ///< Symmetric/hermitian? bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false), m_matrix(rows,columns) : m_is_uptodate(false), m_matrix(rows,columns)
{ {
CGAL_precondition(rows > 0); CGAL_precondition(rows > 0);
CGAL_precondition(columns > 0); CGAL_precondition(columns > 0);
if (m_is_symmetric) { if (m_is_symmetric) {
CGAL_precondition(rows == columns); CGAL_precondition(rows == columns);
} }
m_is_symmetric = is_symmetric; m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid // reserve memory for a regular 3D grid
m_triplets.reserve(rows); m_triplets.reserve(rows);
} }
/// Delete this object and the wrapped TAUCS matrix. /// Delete this object and the wrapped TAUCS matrix.
~Eigen_sparse_matrix() ~Eigen_sparse_matrix()
{ {
} }
/// Return the matrix number of rows /// Return the matrix number of rows
int row_dimension() const { return m_matrix.rows(); } int row_dimension() const { return m_matrix.rows(); }
/// Return the matrix number of columns /// Return the matrix number of columns
int column_dimension() const { return m_matrix.cols(); } int column_dimension() const { return m_matrix.cols(); }
/// Write access to a matrix coefficient: a_ij <- val. /// Write access to a matrix coefficient: a_ij <- val.
/// ///
/// Optimizations: /// Optimizations:
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
/// set_coef() does nothing if (i, j) belongs to the upper triangle. /// set_coef() does nothing if (i, j) belongs to the upper triangle.
/// - Caller can optimize this call by setting 'new_coef' to true /// - Caller can optimize this call by setting 'new_coef' to true
/// if the coefficient does not already exist in the matrix. /// if the coefficient does not already exist in the matrix.
/// ///
/// @commentheading Preconditions: /// @commentheading Preconditions:
/// - 0 <= i < row_dimension(). /// - 0 <= i < row_dimension().
/// - 0 <= j < column_dimension(). /// - 0 <= j < column_dimension().
void set_coef(int i, int j, T val, bool new_coef = false) void set_coef(int i, int j, T val, bool /* new_coef */ = false)
{ {
CGAL_precondition(i < row_dimension()); CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension()); CGAL_precondition(j < column_dimension());
if (m_is_symmetric && (j > i)) if (m_is_symmetric && (j > i))
return; return;
if (m_is_already_built) m_triplets.push_back(Triplet(i,j,val));
m_matrix.coeffRef(i,j)=val; m_is_uptodate = false;
else }
{
if ( new_coef == false ) /// Write access to a matrix coefficient: a_ij <- a_ij+val.
{ ///
assemble_matrix(); /// Optimizations:
m_matrix.coeffRef(i,j)=val; /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
} /// add_coef() does nothing if (i, j) belongs to the upper triangle.
else ///
m_triplets.push_back(Triplet(i,j,val)); /// @commentheading Preconditions:
} /// - 0 <= i < row_dimension().
} /// - 0 <= j < column_dimension().
void add_coef(int i, int j, T val)
/// Write access to a matrix coefficient: a_ij <- a_ij+val. {
/// CGAL_precondition(i < row_dimension());
/// Optimizations: CGAL_precondition(j < column_dimension());
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
/// add_coef() does nothing if (i, j) belongs to the upper triangle. if (m_is_symmetric && (j > i))
/// return;
/// @commentheading Preconditions:
/// - 0 <= i < row_dimension(). m_triplets.push_back(Triplet(i,j,val));
/// - 0 <= j < column_dimension(). m_is_uptodate = false;
void add_coef(int i, int j, T val) }
{
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
const EigenType& eigen_object() const
if (m_is_symmetric && (j > i)) {
return; if(!m_is_uptodate)
{
if (m_is_already_built) m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end());
m_matrix.coeffRef(i,j)+=val; m_is_uptodate = true;
else }
m_triplets.push_back(Triplet(i,j,val)); // turns the matrix into compressed mode:
} // -> release some memory
// -> required for some external solvers
void assemble_matrix() const m_matrix.makeCompressed();
{ return m_matrix;
m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end()); }
m_is_already_built = true;
m_triplets.clear(); //the matrix is built and will not be rebuilt private:
}
const EigenType& eigen_object() const /// Eigen_sparse_matrix cannot be copied (yet)
{ Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs);
if(!m_is_already_built) assemble_matrix(); Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs);
// turns the matrix into compressed mode: // Fields
// -> release some memory private:
// -> required for some external solvers
m_matrix.makeCompressed(); mutable bool m_is_uptodate;
return m_matrix; typedef Eigen::Triplet<T,int> Triplet;
} mutable std::vector<Triplet> m_triplets;
private: mutable EigenType m_matrix;
// Symmetric/hermitian?
/// Eigen_sparse_matrix cannot be copied (yet) bool m_is_symmetric;
Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs);
Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs); }; // Eigen_sparse_matrix
// Fields
private:
/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper
mutable bool m_is_already_built; /// around a Eigen sparse matrix (type Eigen::SparseMatrix).
typedef Eigen::Triplet<T,int> Triplet; ///
mutable std::vector<Triplet> m_triplets; /// Symmetric matrices store only the lower triangle.
///
mutable EigenType m_matrix; /// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
///
// Symmetric/hermitian? /// @heading Parameters:
bool m_is_symmetric; /// @param T Number type.
}; // Eigen_sparse_matrix template<class T>
struct Eigen_sparse_symmetric_matrix
: public Eigen_sparse_matrix<T>
{
/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper // Public types
/// around a Eigen sparse matrix (type Eigen::SparseMatrix). typedef T NT;
///
/// Symmetric matrices store only the lower triangle. // Public operations
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. /// Create a square *symmetric* matrix initialized with zeros.
/// Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
/// @heading Parameters: : Eigen_sparse_matrix<T>(dim, true /* symmetric */)
/// @param T Number type. {
}
template<class T>
struct Eigen_sparse_symmetric_matrix /// Create a square *symmetric* matrix initialized with zeros.
: public Eigen_sparse_matrix<T> ///
{ /// @commentheading Precondition: rows == columns.
// Public types Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows.
typedef T NT; int columns) ///< Number of columns.
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
// Public operations {
}
/// Create a square *symmetric* matrix initialized with zeros. };
Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
: Eigen_sparse_matrix<T>(dim, true /* symmetric */) template <class FT>
{ struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic>
} {
typedef ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> EigenType;
/// Create a square *symmetric* matrix initialized with zeros.
/// Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){}
/// @commentheading Precondition: rows == columns.
Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows. std::size_t number_of_rows () const {return this->rows();}
int columns) ///< Number of columns.
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */) std::size_t number_of_columns () const {return this->cols();}
{
} FT operator()( std::size_t i , std::size_t j ) const {return this->operator()(i,j);}
};
void set( std::size_t i, std::size_t j,FT value){
template <class FT> this->coeffRef(i,j)=value;
struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> }
{
typedef ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> EigenType; const EigenType& eigen_object() const{
return static_cast<const EigenType&>(*this);
Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){} }
std::size_t number_of_rows () const {return this->rows();} };
std::size_t number_of_columns () const {return this->cols();} } //namespace CGAL
FT operator()( std::size_t i , std::size_t j ) const {return this->operator()(i,j);} #endif // CGAL_EIGEN_MATRIX_H
void set( std::size_t i, std::size_t j,FT value){
this->coeffRef(i,j)=value;
}
const EigenType& eigen_object() const{
return static_cast<const EigenType&>(*this);
}
};
} //namespace CGAL
#endif // CGAL_EIGEN_MATRIX_H

View File

@ -1,151 +1,174 @@
// Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved. // Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved.
// //
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as // 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, // published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version. // or (at your option) any later version.
// //
// Licensees holding a valid commercial license may use this file in // Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software. // accordance with the commercial license agreement provided with the software.
// //
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $URL$
// $Id$ // $Id$
// //
// Author(s) : Gael Guennebaud // Author(s) : Gael Guennebaud
#ifndef CGAL_EIGEN_SOLVER_TRAITS_H #ifndef CGAL_EIGEN_SOLVER_TRAITS_H
#define CGAL_EIGEN_SOLVER_TRAITS_H #define CGAL_EIGEN_SOLVER_TRAITS_H
#include <CGAL/basic.h> // include basic.h before testing #defines #include <CGAL/basic.h> // include basic.h before testing #defines
#include <Eigen/Sparse> #include <Eigen/Sparse>
#include <CGAL/Eigen_matrix.h> #include <Eigen/SparseLU>
#include <CGAL/Eigen_vector.h> #include <CGAL/Eigen_matrix.h>
#include <boost/shared_ptr.hpp> #include <CGAL/Eigen_vector.h>
#include <boost/shared_ptr.hpp>
namespace CGAL {
namespace CGAL {
namespace internal {
template <class EigenSolver,class FT> namespace internal {
struct Get_eigen_matrix{ template <class EigenSolver,class FT>
typedef Eigen_sparse_matrix<FT> type; struct Get_eigen_matrix{
}; typedef Eigen_sparse_matrix<FT> type;
};
template <class FT,class EigenMatrix>
struct Get_eigen_matrix< ::Eigen::ConjugateGradient<EigenMatrix>,FT>{ template <class FT,class EigenMatrix>
typedef Eigen_sparse_symmetric_matrix<FT> type; struct Get_eigen_matrix< ::Eigen::ConjugateGradient<EigenMatrix>,FT>{
}; typedef Eigen_sparse_symmetric_matrix<FT> type;
};
template <class FT,class EigenMatrix>
struct Get_eigen_matrix< ::Eigen::SimplicialCholesky<EigenMatrix>,FT>{ template <class FT,class EigenMatrix>
typedef Eigen_sparse_symmetric_matrix<FT> type; struct Get_eigen_matrix< ::Eigen::SimplicialCholesky<EigenMatrix>,FT>{
}; typedef Eigen_sparse_symmetric_matrix<FT> type;
} //internal };
/// The class Eigen_solver_traits template <class FT, class EigenMatrix, class EigenOrdering>
/// is a generic traits class for solving asymmetric or symmetric positive definite (SPD) struct Get_eigen_matrix< ::Eigen::SparseLU<EigenMatrix, EigenOrdering >, FT> {
/// sparse linear systems using one of the Eigen solvers. typedef Eigen_sparse_matrix<FT, ::Eigen::ColMajor> type;
/// The default solver is the iterative bi-congugate gradient stabilized solver };
/// Eigen::BiCGSTAB for double. } //internal
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d concept. /// The class Eigen_solver_traits
/// is a generic traits class for solving asymmetric or symmetric positive definite (SPD)
template<class EigenSolverT = Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> > /// sparse linear systems using one of the Eigen solvers.
class Eigen_solver_traits /// The default solver is the iterative bi-congugate gradient stabilized solver
{ /// Eigen::BiCGSTAB for double.
typedef typename EigenSolverT::Scalar Scalar; ///
// Public types /// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d concept.
public:
typedef Scalar NT; template<class EigenSolverT = Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
typedef typename internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix; class Eigen_solver_traits
typedef Eigen_vector<Scalar> Vector; {
typedef typename EigenSolverT::Scalar Scalar;
// Public types
// Public operations public:
public: typedef Scalar NT;
typedef typename internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT) typedef Eigen_vector<Scalar> Vector;
{
}
// Public operations
EigenSolverT& solver() { return *m_solver_sptr; } public:
/// Solve the sparse linear system "A*X = B". Eigen_solver_traits():m_mat(NULL), m_solver_sptr(new EigenSolverT)
/// Return true on success. The solution is then (1/D) * X. {
/// }
/// @commentheading Preconditions:
/// - A.row_dimension() == B.dimension(). EigenSolverT& solver() { return *m_solver_sptr; }
/// - A.column_dimension() == X.dimension().
bool linear_solver(const Matrix& A, const Vector& B, Vector& X, NT& D) /// Solve the sparse linear system "A*X = B".
{ /// Return true on success. The solution is then (1/D) * X.
D = 1; // Eigen does not support homogeneous coordinates ///
/// @commentheading Preconditions:
m_solver_sptr->compute(A.eigen_object()); /// - A.row_dimension() == B.dimension().
/// - A.column_dimension() == X.dimension().
if(m_solver_sptr->info() != Eigen::Success) bool linear_solver(const Matrix& A, const Vector& B, Vector& X, NT& D)
return false; {
D = 1; // Eigen does not support homogeneous coordinates
X = m_solver_sptr->solve(B);
m_solver_sptr->compute(A.eigen_object());
return m_solver_sptr->info() == Eigen::Success;
} if(m_solver_sptr->info() != Eigen::Success)
protected: return false;
boost::shared_ptr<EigenSolverT> m_solver_sptr;
X = m_solver_sptr->solve(B);
};
return m_solver_sptr->info() == Eigen::Success;
//specilization of the solver for BiCGSTAB as for surface parameterization, the }
//intializer should be a vector of one's (this was the case in 3.1-alpha but not in the official 3.1).
template<> bool pre_factor (const Matrix& A, NT& D)
class Eigen_solver_traits< Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> > {
{ D = 1;
typedef Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> EigenSolverT;
typedef EigenSolverT::Scalar Scalar; m_mat = &A.eigen_object();
// Public types solver().compute(*m_mat);
public: return solver().info() == Eigen::Success;
typedef Scalar NT; }
typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
typedef Eigen_vector<Scalar> Vector; bool linear_solver(const Vector& B, Vector& X)
{
CGAL_precondition(m_mat!=NULL); //pre_factor should have been called first
// Public operations X = solver().solve(B);
public: return solver().info() == Eigen::Success;
}
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT) protected:
{ const typename Matrix::EigenType* m_mat;
} boost::shared_ptr<EigenSolverT> m_solver_sptr;
EigenSolverT& solver() { return *m_solver_sptr; } };
/// Solve the sparse linear system "A*X = B". //specilization of the solver for BiCGSTAB as for surface parameterization, the
/// Return true on success. The solution is then (1/D) * X. //intializer should be a vector of one's (this was the case in 3.1-alpha but not in the official 3.1).
/// template<>
/// @commentheading Preconditions: class Eigen_solver_traits< Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
/// - A.row_dimension() == B.dimension(). {
/// - A.column_dimension() == X.dimension(). typedef Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> EigenSolverT;
bool linear_solver(const Matrix& A, const Vector& B, Vector& X, NT& D) typedef EigenSolverT::Scalar Scalar;
{ // Public types
D = 1; // Eigen does not support homogeneous coordinates public:
typedef Scalar NT;
m_solver_sptr->compute(A.eigen_object()); typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
typedef Eigen_vector<Scalar> Vector;
if(m_solver_sptr->info() != Eigen::Success)
return false;
// Public operations
X.setOnes(B.rows()); public:
X = m_solver_sptr->solveWithGuess(B,X);
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT)
return m_solver_sptr->info() == Eigen::Success; {
} }
protected:
boost::shared_ptr<EigenSolverT> m_solver_sptr; EigenSolverT& solver() { return *m_solver_sptr; }
}; /// Solve the sparse linear system "A*X = B".
/// Return true on success. The solution is then (1/D) * X.
} //namespace CGAL ///
/// @commentheading Preconditions:
#endif // CGAL_EIGEN_SOLVER_TRAITS_H /// - A.row_dimension() == B.dimension().
/// - A.column_dimension() == X.dimension().
bool linear_solver(const Matrix& A, const Vector& B, Vector& X, NT& D)
{
D = 1; // Eigen does not support homogeneous coordinates
m_solver_sptr->compute(A.eigen_object());
if(m_solver_sptr->info() != Eigen::Success)
return false;
X.setOnes(B.rows());
X = m_solver_sptr->solveWithGuess(B,X);
return m_solver_sptr->info() == Eigen::Success;
}
protected:
boost::shared_ptr<EigenSolverT> m_solver_sptr;
};
} //namespace CGAL
#endif // CGAL_EIGEN_SOLVER_TRAITS_H