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

@ -27,33 +27,33 @@
namespace CGAL {
/// The class Eigen_sparse_matrix
/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>.
///
/// This kind of matrix can be either symmetric or not. Symmetric
/// matrices store only the lower triangle.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
///
/// @heading Parameters:
/// @param T Number type.
/// The class Eigen_sparse_matrix
/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>.
///
/// This kind of matrix can be either symmetric or not. Symmetric
/// matrices store only the lower triangle.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
///
/// @heading Parameters:
/// @param T Number type.
template<class T>
struct Eigen_sparse_matrix
{
// Public types
public:
template<class T, int Options = Eigen::RowMajor>
struct Eigen_sparse_matrix
{
// Public types
public:
typedef Eigen::SparseMatrix<T> EigenType;
typedef Eigen::SparseMatrix<T, Options> EigenType;
typedef T NT;
// Public operations
public:
// Public operations
public:
/// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(int dim, ///< Matrix dimension.
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);
@ -68,7 +68,7 @@ public:
Eigen_sparse_matrix(int rows, ///< Number of rows.
int columns, ///< Number of columns.
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(columns > 0);
@ -103,7 +103,7 @@ public:
/// @commentheading Preconditions:
/// - 0 <= i < row_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(j < column_dimension());
@ -111,18 +111,8 @@ public:
if (m_is_symmetric && (j > i))
return;
if (m_is_already_built)
m_matrix.coeffRef(i,j)=val;
else
{
if ( new_coef == false )
{
assemble_matrix();
m_matrix.coeffRef(i,j)=val;
}
else
m_triplets.push_back(Triplet(i,j,val));
}
m_is_uptodate = false;
}
/// Write access to a matrix coefficient: a_ij <- a_ij+val.
@ -142,23 +132,19 @@ public:
if (m_is_symmetric && (j > i))
return;
if (m_is_already_built)
m_matrix.coeffRef(i,j)+=val;
else
m_triplets.push_back(Triplet(i,j,val));
m_is_uptodate = false;
}
void assemble_matrix() const
{
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
}
const EigenType& eigen_object() const
{
if(!m_is_already_built) assemble_matrix();
if(!m_is_uptodate)
{
m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end());
m_is_uptodate = true;
}
// turns the matrix into compressed mode:
// -> release some memory
// -> required for some external solvers
@ -166,17 +152,17 @@ public:
return m_matrix;
}
private:
private:
/// Eigen_sparse_matrix cannot be copied (yet)
Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs);
Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs);
// Fields
private:
// Fields
private:
mutable bool m_is_already_built;
mutable bool m_is_uptodate;
typedef Eigen::Triplet<T,int> Triplet;
mutable std::vector<Triplet> m_triplets;
@ -185,28 +171,28 @@ private:
// Symmetric/hermitian?
bool m_is_symmetric;
}; // Eigen_sparse_matrix
}; // Eigen_sparse_matrix
/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper
/// around a Eigen sparse matrix (type Eigen::SparseMatrix).
///
/// Symmetric matrices store only the lower triangle.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
///
/// @heading Parameters:
/// @param T Number type.
/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper
/// around a Eigen sparse matrix (type Eigen::SparseMatrix).
///
/// Symmetric matrices store only the lower triangle.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
///
/// @heading Parameters:
/// @param T Number type.
template<class T>
struct Eigen_sparse_symmetric_matrix
template<class T>
struct Eigen_sparse_symmetric_matrix
: public Eigen_sparse_matrix<T>
{
// Public types
{
// Public types
typedef T NT;
// Public operations
// Public operations
/// Create a square *symmetric* matrix initialized with zeros.
Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
@ -222,11 +208,11 @@ struct Eigen_sparse_symmetric_matrix
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
{
}
};
};
template <class FT>
struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic>
{
template <class FT>
struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic>
{
typedef ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> EigenType;
Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){}
@ -245,7 +231,7 @@ struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynami
return static_cast<const EigenType&>(*this);
}
};
};
} //namespace CGAL

View File

@ -22,6 +22,7 @@
#include <CGAL/basic.h> // include basic.h before testing #defines
#include <Eigen/Sparse>
#include <Eigen/SparseLU>
#include <CGAL/Eigen_matrix.h>
#include <CGAL/Eigen_vector.h>
#include <boost/shared_ptr.hpp>
@ -29,7 +30,7 @@
namespace CGAL {
namespace internal {
namespace internal {
template <class EigenSolver,class FT>
struct Get_eigen_matrix{
typedef Eigen_sparse_matrix<FT> type;
@ -44,31 +45,36 @@ namespace internal {
struct Get_eigen_matrix< ::Eigen::SimplicialCholesky<EigenMatrix>,FT>{
typedef Eigen_sparse_symmetric_matrix<FT> type;
};
} //internal
/// The class Eigen_solver_traits
/// is a generic traits class for solving asymmetric or symmetric positive definite (SPD)
/// sparse linear systems using one of the Eigen solvers.
/// The default solver is the iterative bi-congugate gradient stabilized solver
/// Eigen::BiCGSTAB for double.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d concept.
template <class FT, class EigenMatrix, class EigenOrdering>
struct Get_eigen_matrix< ::Eigen::SparseLU<EigenMatrix, EigenOrdering >, FT> {
typedef Eigen_sparse_matrix<FT, ::Eigen::ColMajor> type;
};
} //internal
template<class EigenSolverT = Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
class Eigen_solver_traits
{
/// The class Eigen_solver_traits
/// is a generic traits class for solving asymmetric or symmetric positive definite (SPD)
/// sparse linear systems using one of the Eigen solvers.
/// The default solver is the iterative bi-congugate gradient stabilized solver
/// Eigen::BiCGSTAB for double.
///
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d concept.
template<class EigenSolverT = Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
class Eigen_solver_traits
{
typedef typename EigenSolverT::Scalar Scalar;
// Public types
public:
// Public types
public:
typedef Scalar NT;
typedef typename internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
typedef Eigen_vector<Scalar> Vector;
// Public operations
public:
// Public operations
public:
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT)
Eigen_solver_traits():m_mat(NULL), m_solver_sptr(new EigenSolverT)
{
}
@ -93,27 +99,44 @@ public:
return m_solver_sptr->info() == Eigen::Success;
}
protected:
bool pre_factor (const Matrix& A, NT& D)
{
D = 1;
m_mat = &A.eigen_object();
solver().compute(*m_mat);
return solver().info() == Eigen::Success;
}
bool linear_solver(const Vector& B, Vector& X)
{
CGAL_precondition(m_mat!=NULL); //pre_factor should have been called first
X = solver().solve(B);
return solver().info() == Eigen::Success;
}
protected:
const typename Matrix::EigenType* m_mat;
boost::shared_ptr<EigenSolverT> m_solver_sptr;
};
};
//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<>
class Eigen_solver_traits< Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
{
//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<>
class Eigen_solver_traits< Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> >
{
typedef Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> EigenSolverT;
typedef EigenSolverT::Scalar Scalar;
// Public types
public:
// Public types
public:
typedef Scalar NT;
typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
typedef Eigen_vector<Scalar> Vector;
// Public operations
public:
// Public operations
public:
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT)
{
@ -141,10 +164,10 @@ public:
return m_solver_sptr->info() == Eigen::Success;
}
protected:
protected:
boost::shared_ptr<EigenSolverT> m_solver_sptr;
};
};
} //namespace CGAL