mirror of https://github.com/CGAL/cgal
Adding Sparse matrix with prefactor related changes
This commit is contained in:
parent
bb67aa6d0a
commit
57d6bf71bb
|
|
@ -27,225 +27,211 @@
|
|||
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.
|
||||
|
||||
template<class T>
|
||||
struct Eigen_sparse_matrix
|
||||
{
|
||||
// Public types
|
||||
public:
|
||||
|
||||
typedef Eigen::SparseMatrix<T> EigenType;
|
||||
typedef T NT;
|
||||
|
||||
// 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)
|
||||
{
|
||||
CGAL_precondition(dim > 0);
|
||||
|
||||
m_is_symmetric = is_symmetric;
|
||||
// reserve memory for a regular 3D grid
|
||||
m_triplets.reserve(dim);
|
||||
}
|
||||
|
||||
/// Create a rectangular matrix initialized with zeros.
|
||||
/// The class Eigen_sparse_matrix
|
||||
/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>.
|
||||
///
|
||||
/// @commentheading Precondition: rows == columns if is_symmetric is true.
|
||||
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)
|
||||
{
|
||||
CGAL_precondition(rows > 0);
|
||||
CGAL_precondition(columns > 0);
|
||||
if (m_is_symmetric) {
|
||||
CGAL_precondition(rows == columns);
|
||||
}
|
||||
|
||||
m_is_symmetric = is_symmetric;
|
||||
// reserve memory for a regular 3D grid
|
||||
m_triplets.reserve(rows);
|
||||
}
|
||||
|
||||
/// Delete this object and the wrapped TAUCS matrix.
|
||||
~Eigen_sparse_matrix()
|
||||
{
|
||||
}
|
||||
|
||||
/// Return the matrix number of rows
|
||||
int row_dimension() const { return m_matrix.rows(); }
|
||||
/// Return the matrix number of columns
|
||||
int column_dimension() const { return m_matrix.cols(); }
|
||||
|
||||
|
||||
/// Write access to a matrix coefficient: a_ij <- val.
|
||||
/// This kind of matrix can be either symmetric or not. Symmetric
|
||||
/// matrices store only the lower triangle.
|
||||
///
|
||||
/// Optimizations:
|
||||
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
|
||||
/// set_coef() does nothing if (i, j) belongs to the upper triangle.
|
||||
/// - Caller can optimize this call by setting 'new_coef' to true
|
||||
/// if the coefficient does not already exist in the matrix.
|
||||
/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 0 <= i < row_dimension().
|
||||
/// - 0 <= j < column_dimension().
|
||||
void set_coef(int i, int j, T val, bool new_coef = false)
|
||||
/// @heading Parameters:
|
||||
/// @param T Number type.
|
||||
|
||||
template<class T, int Options = Eigen::RowMajor>
|
||||
struct Eigen_sparse_matrix
|
||||
{
|
||||
CGAL_precondition(i < row_dimension());
|
||||
CGAL_precondition(j < column_dimension());
|
||||
// Public types
|
||||
public:
|
||||
|
||||
if (m_is_symmetric && (j > i))
|
||||
return;
|
||||
typedef Eigen::SparseMatrix<T, Options> EigenType;
|
||||
typedef T NT;
|
||||
|
||||
if (m_is_already_built)
|
||||
m_matrix.coeffRef(i,j)=val;
|
||||
else
|
||||
// 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_uptodate(false), m_matrix(dim,dim)
|
||||
{
|
||||
if ( new_coef == false )
|
||||
{
|
||||
assemble_matrix();
|
||||
m_matrix.coeffRef(i,j)=val;
|
||||
}
|
||||
else
|
||||
m_triplets.push_back(Triplet(i,j,val));
|
||||
CGAL_precondition(dim > 0);
|
||||
|
||||
m_is_symmetric = is_symmetric;
|
||||
// reserve memory for a regular 3D grid
|
||||
m_triplets.reserve(dim);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write access to a matrix coefficient: a_ij <- a_ij+val.
|
||||
///
|
||||
/// Optimizations:
|
||||
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
|
||||
/// add_coef() does nothing if (i, j) belongs to the upper triangle.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 0 <= i < row_dimension().
|
||||
/// - 0 <= j < column_dimension().
|
||||
void add_coef(int i, int j, T val)
|
||||
{
|
||||
CGAL_precondition(i < row_dimension());
|
||||
CGAL_precondition(j < column_dimension());
|
||||
/// Create a rectangular matrix initialized with zeros.
|
||||
///
|
||||
/// @commentheading Precondition: rows == columns if is_symmetric is true.
|
||||
Eigen_sparse_matrix(int rows, ///< Number of rows.
|
||||
int columns, ///< Number of columns.
|
||||
bool is_symmetric = false) ///< Symmetric/hermitian?
|
||||
: m_is_uptodate(false), m_matrix(rows,columns)
|
||||
{
|
||||
CGAL_precondition(rows > 0);
|
||||
CGAL_precondition(columns > 0);
|
||||
if (m_is_symmetric) {
|
||||
CGAL_precondition(rows == columns);
|
||||
}
|
||||
|
||||
if (m_is_symmetric && (j > i))
|
||||
return;
|
||||
m_is_symmetric = is_symmetric;
|
||||
// reserve memory for a regular 3D grid
|
||||
m_triplets.reserve(rows);
|
||||
}
|
||||
|
||||
/// Delete this object and the wrapped TAUCS matrix.
|
||||
~Eigen_sparse_matrix()
|
||||
{
|
||||
}
|
||||
|
||||
/// Return the matrix number of rows
|
||||
int row_dimension() const { return m_matrix.rows(); }
|
||||
/// Return the matrix number of columns
|
||||
int column_dimension() const { return m_matrix.cols(); }
|
||||
|
||||
|
||||
/// Write access to a matrix coefficient: a_ij <- val.
|
||||
///
|
||||
/// Optimizations:
|
||||
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
|
||||
/// set_coef() does nothing if (i, j) belongs to the upper triangle.
|
||||
/// - Caller can optimize this call by setting 'new_coef' to true
|
||||
/// if the coefficient does not already exist in the matrix.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 0 <= i < row_dimension().
|
||||
/// - 0 <= j < column_dimension().
|
||||
void set_coef(int i, int j, T val, bool /* new_coef */ = false)
|
||||
{
|
||||
CGAL_precondition(i < row_dimension());
|
||||
CGAL_precondition(j < column_dimension());
|
||||
|
||||
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
|
||||
}
|
||||
/// Write access to a matrix coefficient: a_ij <- a_ij+val.
|
||||
///
|
||||
/// Optimizations:
|
||||
/// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle
|
||||
/// add_coef() does nothing if (i, j) belongs to the upper triangle.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 0 <= i < row_dimension().
|
||||
/// - 0 <= j < column_dimension().
|
||||
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_already_built) assemble_matrix();
|
||||
if (m_is_symmetric && (j > i))
|
||||
return;
|
||||
|
||||
// turns the matrix into compressed mode:
|
||||
// -> release some memory
|
||||
// -> required for some external solvers
|
||||
m_matrix.makeCompressed();
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
mutable bool m_is_already_built;
|
||||
typedef Eigen::Triplet<T,int> Triplet;
|
||||
mutable std::vector<Triplet> m_triplets;
|
||||
|
||||
mutable EigenType m_matrix;
|
||||
|
||||
// Symmetric/hermitian?
|
||||
bool m_is_symmetric;
|
||||
|
||||
}; // Eigen_sparse_matrix
|
||||
m_triplets.push_back(Triplet(i,j,val));
|
||||
m_is_uptodate = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 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.
|
||||
const EigenType& eigen_object() const
|
||||
{
|
||||
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
|
||||
m_matrix.makeCompressed();
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct Eigen_sparse_symmetric_matrix
|
||||
: public Eigen_sparse_matrix<T>
|
||||
{
|
||||
// Public types
|
||||
typedef T NT;
|
||||
private:
|
||||
|
||||
// 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 */)
|
||||
{
|
||||
}
|
||||
/// Eigen_sparse_matrix cannot be copied (yet)
|
||||
Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs);
|
||||
Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs);
|
||||
|
||||
/// Create a square *symmetric* matrix initialized with zeros.
|
||||
// Fields
|
||||
private:
|
||||
|
||||
mutable bool m_is_uptodate;
|
||||
typedef Eigen::Triplet<T,int> Triplet;
|
||||
mutable std::vector<Triplet> m_triplets;
|
||||
|
||||
mutable EigenType m_matrix;
|
||||
|
||||
// Symmetric/hermitian?
|
||||
bool m_is_symmetric;
|
||||
|
||||
}; // Eigen_sparse_matrix
|
||||
|
||||
|
||||
|
||||
/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper
|
||||
/// around a Eigen sparse matrix (type Eigen::SparseMatrix).
|
||||
///
|
||||
/// @commentheading Precondition: rows == columns.
|
||||
Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows.
|
||||
int columns) ///< Number of columns.
|
||||
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
|
||||
/// 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
|
||||
: public Eigen_sparse_matrix<T>
|
||||
{
|
||||
}
|
||||
};
|
||||
// Public types
|
||||
typedef T NT;
|
||||
|
||||
template <class FT>
|
||||
struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic>
|
||||
{
|
||||
typedef ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> EigenType;
|
||||
// Public operations
|
||||
|
||||
Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){}
|
||||
/// Create a square *symmetric* matrix initialized with zeros.
|
||||
Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
|
||||
: Eigen_sparse_matrix<T>(dim, true /* symmetric */)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t number_of_rows () const {return this->rows();}
|
||||
/// Create a square *symmetric* matrix initialized with zeros.
|
||||
///
|
||||
/// @commentheading Precondition: rows == columns.
|
||||
Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows.
|
||||
int columns) ///< Number of columns.
|
||||
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::size_t number_of_columns () const {return this->cols();}
|
||||
template <class FT>
|
||||
struct Eigen_matrix : public ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic>
|
||||
{
|
||||
typedef ::Eigen::Matrix<FT,::Eigen::Dynamic,::Eigen::Dynamic> EigenType;
|
||||
|
||||
FT operator()( std::size_t i , std::size_t j ) const {return this->operator()(i,j);}
|
||||
Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){}
|
||||
|
||||
void set( std::size_t i, std::size_t j,FT value){
|
||||
this->coeffRef(i,j)=value;
|
||||
}
|
||||
std::size_t number_of_rows () const {return this->rows();}
|
||||
|
||||
const EigenType& eigen_object() const{
|
||||
return static_cast<const EigenType&>(*this);
|
||||
}
|
||||
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){
|
||||
this->coeffRef(i,j)=value;
|
||||
}
|
||||
|
||||
const EigenType& eigen_object() const{
|
||||
return static_cast<const EigenType&>(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
|
|
|
|||
|
|
@ -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,122 +30,144 @@
|
|||
namespace CGAL {
|
||||
|
||||
|
||||
namespace internal {
|
||||
template <class EigenSolver,class FT>
|
||||
struct Get_eigen_matrix{
|
||||
typedef Eigen_sparse_matrix<FT> type;
|
||||
};
|
||||
namespace internal {
|
||||
template <class EigenSolver,class FT>
|
||||
struct Get_eigen_matrix{
|
||||
typedef Eigen_sparse_matrix<FT> type;
|
||||
};
|
||||
|
||||
template <class FT,class EigenMatrix>
|
||||
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::ConjugateGradient<EigenMatrix>,FT>{
|
||||
typedef Eigen_sparse_symmetric_matrix<FT> type;
|
||||
};
|
||||
|
||||
template <class FT,class EigenMatrix>
|
||||
struct Get_eigen_matrix< ::Eigen::SimplicialCholesky<EigenMatrix>,FT>{
|
||||
typedef Eigen_sparse_symmetric_matrix<FT> type;
|
||||
};
|
||||
} //internal
|
||||
template <class FT,class EigenMatrix>
|
||||
struct Get_eigen_matrix< ::Eigen::SimplicialCholesky<EigenMatrix>,FT>{
|
||||
typedef Eigen_sparse_symmetric_matrix<FT> type;
|
||||
};
|
||||
|
||||
/// 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
|
||||
{
|
||||
typedef typename EigenSolverT::Scalar Scalar;
|
||||
// Public types
|
||||
public:
|
||||
typedef Scalar NT;
|
||||
typedef typename internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
|
||||
typedef Eigen_vector<Scalar> Vector;
|
||||
/// 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:
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
EigenSolverT& solver() { return *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.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - A.row_dimension() == B.dimension().
|
||||
/// - 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.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 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;
|
||||
return false;
|
||||
|
||||
X = m_solver_sptr->solve(B);
|
||||
|
||||
return m_solver_sptr->info() == Eigen::Success;
|
||||
}
|
||||
protected:
|
||||
boost::shared_ptr<EigenSolverT> m_solver_sptr;
|
||||
}
|
||||
|
||||
};
|
||||
bool pre_factor (const Matrix& A, NT& D)
|
||||
{
|
||||
D = 1;
|
||||
|
||||
//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:
|
||||
typedef Scalar NT;
|
||||
typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
|
||||
typedef Eigen_vector<Scalar> Vector;
|
||||
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> >
|
||||
{
|
||||
typedef Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType> EigenSolverT;
|
||||
typedef EigenSolverT::Scalar Scalar;
|
||||
// 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)
|
||||
{
|
||||
}
|
||||
Eigen_solver_traits(): m_solver_sptr(new EigenSolverT)
|
||||
{
|
||||
}
|
||||
|
||||
EigenSolverT& solver() { return *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.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - A.row_dimension() == B.dimension().
|
||||
/// - 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.
|
||||
///
|
||||
/// @commentheading Preconditions:
|
||||
/// - 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;
|
||||
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;
|
||||
}
|
||||
protected:
|
||||
boost::shared_ptr<EigenSolverT> m_solver_sptr;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue