#pragma once #include #include #include #include "lib_begin.h" namespace cgv { namespace math { class CGV_API sparse_les; /// reference counted pointer type for sparse les solver typedef cgv::data::ref_ptr sparse_les_ptr; /// capability options for a sparse linear solver enum SparseLesCaps { SLC_SYMMETRIC = 1, SLC_UNSYMMETRIC = 2, SLC_NZE_OPTIONAL = 4, SLC_ALL = 7 }; /// factory class for sparse linear system solvers class CGV_API sparse_les_factory : public cgv::data::ref_counted { public: /// return the supported capabilities of the solver virtual SparseLesCaps get_caps() const = 0; /// return the name of the solver virtual std::string get_solver_name() const = 0; //! create an instance of the solver. /*! The parameters to the creation function are - n ... the number of unknowns, - nr_rhs ... the number of right hand sides - nr_nze ... the estimated number of non zero elements in the sparse matrix. For solvers with the SLC_NZE_OPTIONAL cap flag set, one can skip this argument. */ virtual sparse_les_ptr create(int n, int nr_rhs, int nr_nze = -1) = 0; }; /// reference counted pointer type for sparse les solver factories typedef cgv::data::ref_ptr sparse_les_factory_ptr; /** interface for implementations of solvers for sparse linear systems of the form A * x = b with a square matrix A. */ class CGV_API sparse_les : public cgv::data::ref_counted { public: /**@name static interface */ //@{ /// register a factory for a new type of linear equation solver static void register_solver_factory(sparse_les_factory_ptr sls_fac); /// return the list of registered solvers static const std::vector& get_solver_factories(); /// check the registered solver types for one with the given name static sparse_les_ptr create_by_name(const std::string& solver_name, int n, int nr_rhs, int nr_nze = -1); /// check the registered solver types for one with the given capabilities and create an instance of it static sparse_les_ptr create_by_cap(SparseLesCaps caps, int n, int nr_rhs, int nr_nze = -1); //@} /**@name problem setup */ //@{ /// set entry in row r and column c in the sparse matrix A virtual void set_mat_entry(int r, int c, double val) = 0; /// set i-th entry in a single right hand side b virtual void set_b_entry(int i, double val); /// set i-th entry in the j-th right hand side virtual void set_b_entry(int i, int j, double val) = 0; /// return reference to i-th entry in a single right hand side b virtual double& ref_b_entry(int i); /// set i-th entry in j-th right hand side virtual double& ref_b_entry(int i, int j) = 0; //@} /// try to solve system - in case of success analyze residuals if demanded by the optional parameter virtual bool solve(bool analyze_residual = false) = 0; /**@name access to solution*/ //@{ /// return the i-th component of a single solution vector virtual double get_x_entry(int i) const; /// return the i-th component of the j-th solution vector virtual double get_x_entry(int i, int j) const = 0; //@} }; /// implementation of factory class for sparse linear system solvers template class sparse_les_factory_impl : public sparse_les_factory { protected: std::string solver_name; SparseLesCaps caps; public: sparse_les_factory_impl(const std::string& _solver_name, SparseLesCaps _caps) : solver_name(_solver_name), caps(_caps) {} /// return the supported capabilities of the solver SparseLesCaps get_caps() const { return caps; } /// return the name of the solver std::string get_solver_name() const { return solver_name; } /// create an instance of the solver. sparse_les_ptr create(int n, int nr_rhs, int nr_nze) { return sparse_les_ptr(new T(n, nr_rhs, nr_nze)); } }; /// helper template to register a sparse les solver template struct register_sparse_les_factory { register_sparse_les_factory(const std::string& _solver_name, SparseLesCaps _caps) { sparse_les::register_solver_factory(sparse_les_factory_ptr( new sparse_les_factory_impl(_solver_name, _caps))); } }; } } #include