sparse_matrix.h

来自「很多二维 三维几何计算算法 C++ 类库」· C头文件 代码 · 共 248 行

H
248
字号
/* * author:  Bruno Levy, INRIA, project ALICE * website: http://www.loria.fr/~levy/software *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation *  * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * * Scientific work that use this software can reference the website and * the following publication: * * @INPROCEEDINGS {levy:NMDGP:05, *    AUTHOR = Bruno Levy, *    TITLE  = Numerical Methods for Digital Geometry Processing, *    BOOKTITLE =Israel Korea Bi-National Conference, *    YEAR=November 2005, *    URL=http://www.loria.fr/~levy/php/article.php?pub=../publications/papers/2005/Numerics * } * *  Laurent Saboret 01/2005: Change for CGAL: *      - Added OpenNL namespace *      - SparseMatrix is now a model of the SparseLinearAlgebraTraits_d::Matrix concept*/#ifndef __OPENNL_SPARSE_MATRIX__#define __OPENNL_SPARSE_MATRIX__#include <CGAL/OpenNL/full_vector.h>#include <vector>#include <cstdlib>#include <cassert>namespace OpenNL {//________________________________________________________________// Class SparseMatrix// Model of the SparseLinearAlgebraTraits_d::Matrix concepttemplate <class T> class SparseMatrix{// Public typespublic:    typedef T CoeffType ;    // added for SparseLinearAlgebraTraits_d::Matrix concept    typedef T NT;    struct Coeff {        Coeff() { }        Coeff(unsigned int i, T val) : index(i), a(val) { }        unsigned int index ;        T a ;    } ;//__________________________________________________   /**    * A row or a column of a SparseMatrix. The row/column is    * compressed, and stored in the form of a list of    * (value,index) couples.    */    class Row : public std::vector<Coeff> {        typedef typename std::vector<Coeff> superclass ;    public:        /** a_{index} <- a_{index} + val */        void add_coef(unsigned int index, T val)        {            // search for coefficient in superclass vector            for(typename superclass::iterator it = superclass::begin() ;                it != superclass::end() ;                it++)            {                if(it->index == index) {                    it->a += val ;                      // +=                    return ;                }            }            // coefficient doesn't exist yet if we reach this point            superclass::push_back(Coeff(index, val)) ;        }        // a_{index} <- val        // (added for SparseLinearAlgebraTraits_d::Matrix concept)        void set_coef(unsigned int index, T val)        {            // search for coefficient in superclass vector            for(typename superclass::iterator it = superclass::begin() ;                it != superclass::end() ;                it++)            {                if(it->index == index) {                    it->a = val ;                       // =                    return ;                }            }            // coefficient doesn't exist yet if we reach this point            superclass::push_back(Coeff(index, val)) ;        }        // return a_{index} (0 by default)        // (added for SparseLinearAlgebraTraits_d::Matrix concept)        T get_coef(unsigned int index) const        {            // search for coefficient in superclass vector            for(typename superclass::const_iterator it = superclass::begin() ;                it != superclass::end() ;                it++)            {                if(it->index == index)                    return it->a ;                      // return value            }            // coefficient doesn't exist if we reach this point            return 0 ;        }    } ;// Public operationspublic:    //__________ constructors / destructor _____    // Create a square matrix initialized with zeros    SparseMatrix(unsigned int dim) {        assert(dim > 0);        dimension_ = dim ;        row_ = new Row[dimension_] ;    }    // Create a rectangular matrix initialized with zeros    // (added for SparseLinearAlgebraTraits_d::Matrix concept)    // WARNING: this class supports square matrices only    SparseMatrix (unsigned int rows, unsigned int columns ) {        assert(rows == columns);        assert(columns > 0);        dimension_ = columns ;        row_ = new Row[dimension_] ;    }    ~SparseMatrix() {        delete[] row_ ;        row_ = NULL ;    }    //___________ access ________________________    // Return the matrix dimension    unsigned int dimension() const {  return dimension_ ;  }    // Added for SparseLinearAlgebraTraits_d::Matrix concept:    // Return the matrix number of rows    unsigned int row_dimension() const    { return dimension(); }    // Return the matrix number of columns    unsigned int column_dimension() const { return dimension(); }    Row& row(unsigned int i) {        assert(i < dimension_) ;        return row_[i] ;    }    const Row& row(unsigned int i) const {        assert(i < dimension_) ;        return row_[i] ;    }    // Read access to 1 matrix coefficient    // (added for SparseLinearAlgebraTraits_d::Matrix concept)    //    // Preconditions:    // * 0 <= i < row_dimension()    // * 0 <= j < column_dimension()    NT  get_coef (unsigned int i, unsigned int j) const {        assert(i < dimension_) ;        assert(j < dimension_) ;        return row(i).get_coef(j) ;    }    // Write access to 1 matrix coefficient: a_ij <- a_ij + val    //    // Preconditions:    // * 0 <= i < row_dimension()    // * 0 <= j < column_dimension()    void add_coef(unsigned int i, unsigned int j, T val) {        assert(i < dimension_) ;        assert(j < dimension_) ;        row(i).add_coef(j, val) ;    }    // Write access to 1 matrix coefficient: a_ij <- val    //(added for SparseLinearAlgebraTraits_d::Matrix concept)    //    // Preconditions:    // * 0 <= i < row_dimension()    // * 0 <= j < column_dimension()    void set_coef(unsigned int i, unsigned int j, NT  val) {        assert(i < dimension_) ;        assert(j < dimension_) ;        row(i).set_coef(j, val) ;    }    /**     * removes all the coefficients and frees the allocated     * space.     */    void clear() {        for(unsigned int i=0; i<dimension_; i++) {            row(i).clear() ;        }    }private:    unsigned int dimension_ ;    Row* row_ ;    // SparseMatrix cannot be copied    // (for the moment, could be implemented if needed).    SparseMatrix(const SparseMatrix& rhs) ;    SparseMatrix& operator=(const SparseMatrix& rhs) ;} ;template <class T> void mult(const SparseMatrix<T>& M, const FullVector<T>& x, FullVector<T>& y) {    unsigned int N = M.dimension() ;    assert(x.dimension() == N) ;    assert(y.dimension() == N) ;    for(unsigned int i=0; i<N; i++) {        y[i] = 0 ;        const typename SparseMatrix<T>::Row& R = M.row(i) ;        for(unsigned int jj=0; jj<R.size(); jj++) {            unsigned int j = R[jj].index ;            y[i] += R[jj].a * x[j] ;        }    }}}; // namespace OpenNL#endif // __OPENNL_SPARSE_MATRIX__

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?