LCOV - code coverage report
Current view: top level - ugbase/lib_algebra/cpu_algebra - sparsematrix.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 22.7 % 66 15
Test Date: 2025-09-21 23:31:46 Functions: 5.0 % 20 1

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__CPU_ALGEBRA__SPARSEMATRIX__
      34              : #define __H__UG__CPU_ALGEBRA__SPARSEMATRIX__
      35              : 
      36              : #include <math.h>
      37              : #include "common/common.h"
      38              : #include "../algebra_common/sparsematrix_util.h"
      39              : #include <iostream>
      40              : #include <algorithm>
      41              : #include "common/util/ostream_util.h"
      42              : 
      43              : #include "../algebra_common/connection.h"
      44              : #include "../algebra_common/matrixrow.h"
      45              : #include "../common/operations_mat/operations_mat.h"
      46              : 
      47              : #define PROFILE_SPMATRIX(name) PROFILE_BEGIN_GROUP(name, "SparseMatrix algebra")
      48              : 
      49              : #ifndef NDEBUG
      50              : #define CHECK_ROW_ITERATORS
      51              : #endif
      52              : 
      53              : namespace ug{
      54              : 
      55              : /// \addtogroup cpu_algebra
      56              : ///     @{
      57              : 
      58              : 
      59              : // example for the variable CRS storage structure:
      60              : // say we have:
      61              : // rowStart = 0 3 8
      62              : // rowEnd = 3 6 11
      63              : // rowMax = 3 8 11
      64              : // cols ( | marking end of row): 2 5 6 | 2 6 7 x x| 8 9 10
      65              : 
      66              : // now insert (0 3): row 0 is full (rowEnd[0]==rowMax[0]), copy it to the end, and insert index
      67              : // rowStart = 11 3 8
      68              : // rowEnd = 15 6 11
      69              : // rowMax = 17 8 11
      70              : // cols ( | marking end of row): x x x | 2 6 7 x x| 8 9 10 | 2 3 5 6 x x |
      71              : 
      72              : // now insert (1 3): row 1 not full, we can add it
      73              : // rowStart 11 3 8
      74              : // rowEnd 15 7 11
      75              : // rowMax = 17 8 11
      76              : // cols : x x x | 2 3 6 7 x | 8 9 10 | 2 3 5 6 x x |
      77              : 
      78              : // defragment:
      79              : // rowStart 0 4 8
      80              : // rowEnd 4 8 11
      81              : // rowMax = 4 8 11
      82              : // cols : 2 3 5 6 | 2 3 6 7 | 8 9 10
      83              : 
      84              : 
      85              : /** SparseMatrix
      86              :  *  \brief sparse matrix for big, variable sparse matrices.
      87              :  *
      88              :  *  matrix is stored independent row-wise
      89              :  *  When doing discretisation, use the add set and get methods
      90              :  *  for dealing with submatrices of A.
      91              :  *  For other things you can use the row iterators or
      92              :  *  operator()-methods.
      93              :  *
      94              :  * \sa matrixrow, CreateAsMultiplyOf
      95              :  * \param T blocktype
      96              :  * \param T blocktype
      97              :  */
      98              : template<typename TValueType> class SparseMatrix
      99              : {
     100              : public:
     101              :         typedef TValueType value_type;
     102              :         enum {rows_sorted=true};
     103              : 
     104              :         typedef SparseMatrix<value_type> this_type;
     105              : 
     106              : public:
     107              :         typedef AlgebraicConnection<TValueType> connection;
     108              :         typedef MatrixRow<this_type> row_type;
     109              :         typedef ConstMatrixRow<this_type> const_row_type;
     110              : 
     111              : public:
     112              :         // construction etc
     113              :         //----------------------
     114              : 
     115              :         /// constructor for empty SparseMatrix
     116              :         SparseMatrix();
     117              :         /// destructor
     118           13 :         virtual ~SparseMatrix () {}
     119              : 
     120              :         /**
     121              :          * @brief Clears the matrix vectors and frees their memory
     122              :          */
     123              :         void clear_and_free();
     124              : 
     125              :         /**
     126              :          * \brief resizes the SparseMatrix
     127              :          * \param newRows new nr of rows
     128              :          * \param newCols new nr of cols
     129              :          * \return
     130              :          */
     131              :         void resize_and_clear(size_t newRows, size_t newCols);
     132              :         void resize_and_keep_values(size_t newRows, size_t newCols);
     133              :         void clear_retain_structure();
     134              : 
     135              :         /**
     136              :          * \brief write in a empty SparseMatrix (this) the transpose SparseMatrix of B.
     137              :          * \param B                     the matrix of which to create the transpose of
     138              :          * \param scale         an optional scaling
     139              :          * \return                      true on success
     140              :          */
     141              :         void set_as_transpose_of(const SparseMatrix<value_type> &B, double scale=1.0);
     142              :         void set_as_transpose_of2(const SparseMatrix<value_type> &B, double scale=1.0);
     143              : 
     144              :         /**
     145              :          * \brief create/recreate this as a copy of SparseMatrix B
     146              :          * \param B                     the matrix of which to create a copy of
     147              :          * \param scale         an optional scaling
     148              :          * \return                      true on success
     149              :          */
     150              :         void set_as_copy_of(const SparseMatrix<value_type> &B, double scale=1.0);
     151              :         SparseMatrix<value_type> &operator = (const SparseMatrix<value_type> &B)
     152              :         {
     153            0 :                 set_as_copy_of(B);
     154            0 :                 return *this;
     155              :         }
     156              : 
     157              : 
     158              : public:
     159              :         //! calculate dest = alpha1*v1 + beta1*A*w1 (A = this matrix)
     160              :         template<typename vector_t>
     161              :         void axpy(vector_t &dest,
     162              :                         const number &alpha1, const vector_t &v1,
     163              :                         const number &beta1, const vector_t &w1) const;
     164              : 
     165              :         //! calculate dest = alpha1*v1 + beta1*A^T*w1 (A = this matrix)
     166              :         template<typename vector_t>
     167              :         void axpy_transposed(vector_t &dest,
     168              :                         const number &alpha1, const vector_t &v1,
     169              :                         const number &beta1, const vector_t &w1) const;
     170              : 
     171              :         //! calculated dest = beta1*A*w1 . For empty rows, dest will not be changed
     172              :         template<typename vector_t>
     173              :         void apply_ignore_zero_rows(vector_t &dest,
     174              :                         const number &beta1, const vector_t &w1) const;
     175              : 
     176              :         //! calculated dest = beta1*A*w1 . For empty cols of A (=empty rows of A^T), dest will not be changed
     177              :         template<typename vector_t>
     178              :         void apply_transposed_ignore_zero_rows(vector_t &dest,
     179              :                         const number &beta1, const vector_t &w1) const;
     180              : 
     181              :         // DEPRECATED!
     182              :         //! calculate res = A x
     183              :                 // apply is deprecated because of axpy(res, 0.0, res, 1.0, beta, w1)
     184              :                 template<typename Vector_type>
     185              :                 bool apply(Vector_type &res, const Vector_type &x) const
     186              :                 {
     187            0 :                         axpy(res, 0.0, res, 1.0, x);
     188              :                         return true;
     189              :                 }
     190              : 
     191              :                 //! calculate res = A.T x
     192              :                 // apply is deprecated because of axpy(res, 0.0, res, 1.0, beta, w1)
     193              :                 template<typename Vector_type>
     194              :                 bool apply_transposed(Vector_type &res, const Vector_type &x) const
     195              :                 {
     196            0 :                         axpy_transposed(res, 0.0, res, 1.0, x);
     197              :                         return true;
     198              :                 }
     199              : 
     200              :                 // matmult_minus is deprecated because of axpy(res, 1.0, res, -1.0, x);
     201              :                 //! calculate res -= A x
     202              :                 template<typename Vector_type>
     203              :                 bool matmul_minus(Vector_type &res, const Vector_type &x) const
     204              :                 {
     205            0 :                         axpy(res, 1.0, res, -1.0, x);
     206            0 :                         return true;
     207              :                 }
     208              : 
     209              : 
     210              : 
     211              :         /**
     212              :          * \brief check for isolated condition of an index
     213              :          * \param i
     214              :          * \return true if only A[i,i] != 0.0
     215              :          */
     216              :         inline bool is_isolated(size_t i) const;
     217              : 
     218              :         void scale(double d);
     219              :         SparseMatrix<value_type> &operator *= (double d) { scale(d); return *this; }
     220              : 
     221              :         // submatrix set/get functions
     222              :         //-------------------------------
     223              : 
     224              :         /** Add a local matrix
     225              :          *
     226              :          * The local matrix type must declare the following members:
     227              :          * - num_rows()
     228              :          * - num_cols()
     229              :          * - row_index(size_t i)
     230              :          * - col_index(size_t j)
     231              :          * - operator()(size_t i, size_t j)
     232              :          * so that mat(i,j) will go to SparseMat(mat.row_index(i), mat.col_index(j))
     233              :          * \param mat the whole local matrix type
     234              :          */
     235              :         template<typename M>
     236              :         void add(const M &mat);
     237              :         template<typename M>
     238              :         //! set local matrix \sa add
     239              :         void set(const M &mat);
     240              :         //! get local matrix \sa add
     241              :         template<typename M>
     242              :         void get(M &mat) const;
     243              : 
     244              :         // finalizing functions
     245              :         //----------------------
     246              : 
     247              : 
     248              : 
     249              :         inline void check_rc(size_t r, size_t c) const
     250              :         {
     251              :                 UG_ASSERT(r < num_rows() && c < num_cols(), "tried to access element (" << r << ", " << c << ") of " << num_rows() << " x " << num_cols() << " matrix.");
     252              :         }
     253              : 
     254              :         inline void check_row_modifiable(size_t r) const
     255              :         {
     256              : #ifdef CHECK_ROW_ITERATORS
     257              :                 UG_ASSERT(nrOfRowIterators[r] == 0, "row " << r << " is used by an iterator and should not be modified.")
     258              : #endif
     259              :         }
     260              : 
     261              : 
     262              :         //! set matrix to Id*a
     263              :         void set(double a);
     264              : 
     265              :         /** operator() (size_t r, size_t c) const
     266              :          * access connection (r, c)
     267              :          * \param r row
     268              :          * \param c column
     269              :          * \note if connection (r, c) is not there, returns 0.0
     270              :          * \return SparseMat(r, c)
     271              :          */
     272            0 :         const value_type &operator () (size_t r, size_t c)  const
     273              :     {
     274              :                 check_rc(r, c);
     275        22172 :         int j=get_index_const(r, c);
     276        22172 :                 if(j == -1)
     277              :                 {
     278            0 :                         static value_type v(0.0);
     279            0 :                         return v;
     280              :                 }
     281              :         UG_ASSERT(cols[j]==(int)c && j >= rowStart[r] && j < rowEnd[r], "");
     282        21291 :         return values[j];
     283              :     }
     284              : 
     285              :         /** operator() (size_t r, size_t c) const
     286              :          * access or create connection (r, c)
     287              :          * \param r row
     288              :          * \param c column
     289              :          * \note (r,c) is added to sparsity pattern if not already there
     290              :          * use operator()(r,c,bConnectionFound) to prevent
     291              :          * \return SparseMat(r, c)=0.0 if connection created, otherwise SparseMat(r, c)
     292              :          */
     293              :         value_type &operator() (size_t r, size_t c)
     294              :         {
     295              :                 check_rc(r, c);
     296        32199 :                 int j=get_index(r, c);
     297              :         UG_ASSERT(j != -1 && cols[j]==(int)c && j >= rowStart[r] && j < rowEnd[r], "");
     298        32199 :         return values[j];
     299              :     }
     300              : 
     301              : public:
     302              :         // row functions
     303              : 
     304              :         /**
     305              :          * set a row of the matrix. all previous content in this row is destroyed (@sa add_matrix_row).
     306              :          * \param row index of the row to set
     307              :          * \param c pointer to a array of sorted connections of size nr
     308              :          * \param nr number of connections in c
     309              :          * \remark will sort array c
     310              :          */
     311              :         void set_matrix_row(size_t row, connection *c, size_t nr);
     312              : 
     313              :         /**
     314              :          * adds the connections c to the matrixrow row.
     315              :          * if c has a connection con with con.iIndex=i, and the matrix already has a connection (row, i),
     316              :          * the function will set A(row,i) += con.dValue. otherwise the connection A(row, i) is created
     317              :          * and set to con.dValue.
     318              :          * \param row row to add to
     319              :          * \param c connections ("row") to be added the row.
     320              :          * \param nr number of connections in array c.
     321              :          * \return true on success.
     322              :          * \note you may use double connections in c.
     323              :          */
     324              :         void add_matrix_row(size_t row, connection *c, size_t nr);
     325              : 
     326              : 
     327              :         //! calculates dest += alpha * A[row, .] v;
     328              :         template<typename vector_t>
     329              :         inline void mat_mult_add_row(size_t row, typename vector_t::value_type &dest, double alpha, const vector_t &v) const;
     330              : public:
     331              :         // accessor functions
     332              :         //----------------------
     333              : 
     334              :         //! returns number of connections of row row.
     335              :         inline size_t num_connections(size_t i) const
     336              :         {
     337            0 :                 if(rowStart[i] == -1) return 0;
     338            0 :                 else return rowEnd[i]-rowStart[i];
     339              :         }
     340              : 
     341              :         //! returns number of rows
     342              :         size_t num_rows() const { return rowEnd.size(); }
     343              : 
     344              :         //! returns the number of cols
     345            3 :         size_t num_cols() const { return m_numCols; }
     346              : 
     347              :         //! returns the total number of connections
     348            0 :         size_t total_num_connections() const { return nnz; }
     349              : 
     350              : public:
     351              : 
     352              :         // Iterators
     353              :         //---------------------------
     354              : 
     355              :         // a row_iterator has to suppport
     356              :         // operator ++, operator +=, index() const, const value_type &value() const, value_type &value()
     357              :         // a const_row_iterator has to suppport
     358              :         // operator ++, operator +=, index() const, const value_type &value() const
     359              : 
     360              : 
     361              :         /**
     362              :          *  row_iterator
     363              :          *  iterator over a row
     364              :          */
     365              :         class row_iterator
     366              :     {
     367              :         SparseMatrix &A;
     368              : #ifdef CHECK_ROW_ITERATORS
     369              :         size_t _row;
     370              : #endif
     371              :         size_t i;
     372              :     public:
     373              :         inline void check() const {
     374              : #ifdef CHECK_ROW_ITERATORS
     375              :                           A.check_row(_row, i);
     376              : #endif
     377              :                   }
     378            0 :         row_iterator(SparseMatrix &_A, size_t row, size_t _i) : A(_A)
     379              : #ifdef CHECK_ROW_ITERATORS
     380              :                                  , _row(row)
     381              : #endif
     382            0 :                                  , i(_i) { A.add_iterator(row); }
     383              :         row_iterator(row_iterator &&other) : A(other.A),
     384              : #ifdef CHECK_ROW_ITERATORS
     385              :                   _row(other._row),
     386              : #endif
     387              :                   i(other.i) {
     388              : #ifdef CHECK_ROW_ITERATORS
     389              :                                 A.add_iterator(other._row);
     390              : #else
     391              :                                 A.add_iterator(-1);
     392              : #endif
     393              :                   }
     394              :         row_iterator(const row_iterator &other) : A(other.A),
     395              : #ifdef CHECK_ROW_ITERATORS
     396              :                   _row(other._row),
     397              : #endif
     398              :                   i(other.i) {
     399              : #ifdef CHECK_ROW_ITERATORS
     400              :                           A.add_iterator(other._row);
     401              : #else
     402              :                           A.add_iterator(-1);
     403              : #endif
     404              :                   }
     405              :         ~row_iterator() {
     406              : #ifdef CHECK_ROW_ITERATORS
     407              :                           A.remove_iterator(_row);
     408              : #else
     409            0 :                           A.remove_iterator(-1);
     410              : #endif
     411            0 :                   }
     412              :         row_iterator *operator ->() { return this; }
     413            0 :         value_type &value() { check(); return A.values[i];   }
     414            0 :         size_t index() const { check(); return A.cols[i]; }
     415              :         bool operator != (const row_iterator &o) const { return i != o.i;  }
     416            0 :         void operator ++ () { ++i; }
     417              :                 void operator += (int nr) { i+=nr; }
     418              :                 bool operator == (const row_iterator &other) const { return other.i == i; check(); }
     419              :     };
     420              :     class const_row_iterator
     421              :     {
     422              :         const SparseMatrix &A;
     423              : #ifdef CHECK_ROW_ITERATORS
     424              :         size_t _row; // int?
     425              : #endif
     426              :         size_t i;
     427              :     public:
     428              :         inline void check() const {
     429              : #ifdef CHECK_ROW_ITERATORS
     430              :                           A.check_row(_row, i);
     431              : #endif
     432              :                   }
     433            0 :         const_row_iterator(const SparseMatrix &_A, size_t row, size_t _i) : A(_A),
     434              : #ifdef CHECK_ROW_ITERATORS
     435              :                   _row(row),
     436              : #endif
     437            0 :                   i(_i) {A.add_iterator(row);}
     438            0 :         const_row_iterator(const const_row_iterator &other) : A(other.A),
     439              : #ifdef CHECK_ROW_ITERATORS
     440              :                   _row(other._row),
     441              : #endif
     442            0 :                   i(other.i) {
     443              : #ifdef CHECK_ROW_ITERATORS
     444              :                           A.add_iterator(_row);
     445              : #else
     446              :                           A.add_iterator(-1);
     447              : #endif
     448              :                   }
     449              :         const_row_iterator(const_row_iterator&& other) : A(other.A),
     450              : #ifdef CHECK_ROW_ITERATORS
     451              :                      _row(other._row),
     452              : #endif
     453              :                           i(other.i) {
     454              : #ifdef CHECK_ROW_ITERATORS
     455              :                           A.add_iterator(_row);
     456              : #else
     457              :                           A.add_iterator(-1);
     458              : #endif
     459              :                   }
     460              :                   const_row_iterator& operator=(const_row_iterator const&) = delete;
     461              :                   const_row_iterator& operator=(const_row_iterator&&) = delete;
     462              :         ~const_row_iterator() {
     463              : #ifdef CHECK_ROW_ITERATORS
     464              :                           A.remove_iterator(_row);
     465              : #else
     466            0 :                           A.remove_iterator(-1);
     467              : #endif
     468            0 :                   }
     469              :         const const_row_iterator *operator ->() const { return this; }
     470            0 :         const value_type &value() const { check(); return A.values[i];   }
     471        20031 :         size_t index() const { check(); return A.cols[i];     }
     472            0 :         bool operator != (const const_row_iterator &o) const { return i != o.i; }
     473        12165 :         void operator ++ () { ++i; }
     474              :         void operator += (int nr) { i+=nr; }
     475              :                 bool operator == (const const_row_iterator &other) const { return other.i == i; }
     476              :                 public: // BUG
     477              :                  // int row() const{return _row;}
     478              :                  size_t idx() const{return i;}
     479              :     };
     480              : 
     481              : 
     482              : 
     483              : 
     484            0 :         row_iterator         begin_row(size_t r)         { return row_iterator(*this, r, rowStart[r]);  }
     485            0 :     row_iterator         end_row(size_t r)           { return row_iterator(*this, r, rowEnd[r]);  }
     486         1445 :     const_row_iterator   begin_row(size_t r) const   { return const_row_iterator(*this, r, rowStart[r]);  }
     487        13610 :     const_row_iterator   end_row(size_t r)   const   { return const_row_iterator(*this, r, rowEnd[r]);  }
     488              : 
     489              :     row_type            get_row(size_t r)               { return row_type(*this, r); }
     490              :     const_row_type      get_row(size_t r) const { return const_row_type(*this, r); }
     491              : 
     492              : public:
     493              :         // connectivity functions
     494              :         //-------------------------
     495              : 
     496              :     bool has_connection(size_t r, size_t c) const
     497              :     {
     498              :         check_rc(r, c);
     499              :         bool bFound;
     500            0 :         get_connection(r, c, bFound);
     501            0 :         return bFound;
     502              :     }
     503              : 
     504              :         /**
     505              :          * \param r index of the row
     506              :          * \param c index of the column
     507              :          * \return a const_row_iterator to the connection A(r,c) if existing, otherwise end_row(row)
     508              :          */
     509              :         row_iterator get_iterator_or_next(size_t r, size_t c)
     510              :         {
     511              :                 check_rc(r, c);
     512              :                 if(rowStart[r] == -1 || rowStart[r] == rowEnd[r])
     513              :                 return end_row(r);
     514              :         else
     515              :         {
     516              :                 int j=get_index_internal(r, c);
     517              :                 if(j > maxValues) return end_row(r);
     518              :                 else return row_iterator(*this, r, j);
     519              :         }
     520              :     }
     521              : 
     522              :         /**
     523              :          * \param r index of the row
     524              :          * \param c index of the column
     525              :          * \return a const_row_iterator to the connection A(r,c) if existing, otherwise end_row(row)
     526              :          */
     527            0 :         const_row_iterator get_connection(size_t r, size_t c, bool &bFound) const
     528              :         {
     529              :                 check_rc(r, c);
     530            0 :                 int j=get_index_const(r, c);
     531            0 :                 if(j != -1)
     532              :                 {
     533            0 :                         bFound = true;
     534            0 :                         return const_row_iterator(*this, r, j);
     535              :                 }
     536              :                 else
     537              :                 {
     538            0 :                         bFound = false;
     539              :                         return end_row(r);
     540              :                 }
     541              :     }
     542              :         /**
     543              :          * \param r index of the row
     544              :          * \param c index of the column
     545              :          * \return a row_iterator to the connection A(r,c) if existing, otherwise end_row(row)
     546              :          */
     547            0 :         row_iterator get_connection(size_t r, size_t c, bool &bFound)
     548              :         {
     549              :                 check_rc(r, c);
     550            0 :                 int j=get_index_const(r, c);
     551            0 :                 if(j != -1)
     552              :                 {
     553            0 :                         bFound = true;
     554            0 :                         return row_iterator(*this, r, j);
     555              :                 }
     556              :                 else
     557              :                 {
     558            0 :                         bFound = false;
     559              :                         return end_row(r);
     560              :                 }
     561              :         }
     562              : 
     563              :         /**
     564              :          * \param r index of the row
     565              :          * \param c index of the column
     566              :          * \return a const_row_iterator to the connection A(r,c) if existing, otherwise end_row(row)
     567              :          */
     568              :         const_row_iterator get_connection(size_t r, size_t c) const
     569              :         {
     570              :                 bool b;
     571            0 :                 return get_connection(r, c, b);
     572              :         }
     573              :         /**
     574              :          * \param r index of the row
     575              :          * \param c index of the column
     576              :          * \return a row_iterator to the connection A(r,c)
     577              :          * \remark creates connection if necessary.
     578              :          */
     579              :         row_iterator get_connection(size_t r, size_t c)
     580              :         {
     581              :                 check_rc(r, c);
     582              :                 assert(bNeedsValues);
     583              :                 int j=get_index(r, c);
     584              :                 return row_iterator(*this, r, j);
     585              :         }
     586              : 
     587              : 
     588            0 :         void defragment()
     589              :     {
     590            0 :                 if(num_rows() != 0 && num_cols() != 0)
     591            0 :                         copyToNewSize(nnz);
     592            0 :     }
     593              : 
     594              :         void defragment() const
     595              :         {
     596            0 :                 (const_cast<this_type*>(this))->defragment();
     597            0 :         }
     598              : 
     599              :         /**
     600              :          * copies the matrix to the standard CRS format
     601              :          * @param numRows       (out) num rows of A
     602              :          * @param numCols               (out) num rows of A
     603              :          * @param argValues             (out) value_type vector with non-zero values
     604              :          * @param argRowStart   (out) row i is from argRowStart[i] to argRowStart[i+1]
     605              :          * @param argColInd             (out) argColInd[i] is colum index of nonzero i
     606              :          */
     607              :         void copy_crs(size_t &numRows, size_t &numCols,
     608              :                         std::vector<value_type> &argValues, std::vector<int> &argRowStart,
     609              :                         std::vector<int> &argColInd) const
     610              :         {
     611              :                 numRows = num_rows();
     612              :                 numCols = num_cols();
     613              :                 defragment();
     614              :                 argValues = values;
     615              :                 argRowStart = rowStart;
     616              :                 argColInd = cols;
     617              :         }
     618              : 
     619              :         /**
     620              :          * returns pointers to CRS format. note that these are only valid as long
     621              :          * as the matrix is not modified.
     622              :          * @param numRows       (out) num rows of A
     623              :          * @param numCols               (out) num rows of A
     624              :          * @param pValues               (out) value_type vector with non-zero values
     625              :          * @param pRowStart   (out) row i is from pRowStart[i] to pRowStart[i+1]
     626              :          * @param pColInd               (out) pColInd[i] is colum index of nonzero i
     627              :          */
     628              :         void get_crs(size_t &numRows, size_t &numCols,
     629              :                         value_type *&pValues, size_t *pRowStart, size_t *pColInd, size_t &nnz) const
     630              :         {
     631              :                 defragment();
     632              :                 pValues = &values[0];
     633              :                 // FIXME:
     634              :                 //pRowStart = &rowStart[0]; // assigning int * to size_t *
     635              :                 //pColInd = &cols[0];       // assigning int * to size_t *
     636              :                 UG_THROW("SparseMatrix::get_crs() needs to be fixed.");
     637              :                 numRows = num_rows();
     638              :                 numCols = num_cols();
     639              :                 nnz = total_num_connections();
     640              :         }
     641              : 
     642              :         /**
     643              :          * assigns a reference to the values vector to argument vector
     644              :          * 
     645              :          * \param argValues vector to be assigned
     646              :          */
     647              :         void get_values(std::vector<value_type> &argValues) const
     648              :         {
     649              :                 defragment();
     650              :                 argValues = values;
     651              :         }
     652              : 
     653              : 
     654              : public:
     655              :         // output functions
     656              :         //----------------------
     657              : 
     658              :         void print(const char * const name = NULL) const;
     659              :         void printtype() const;
     660              : 
     661              :         void print_to_file(const char *filename) const;
     662              :         void printrow(size_t row) const;
     663              : 
     664              :         friend std::ostream &operator<<(std::ostream &out, const SparseMatrix &m)
     665              :         {
     666              :                 out << "SparseMatrix " //<< m.name
     667              :                 << " [ " << m.num_rows() << " x " << m.num_cols() << " ]";
     668              :                 return out;
     669              :         }
     670              : 
     671              : 
     672            0 :         void p() const { print(); } // for use in gdb
     673              :         void pr(size_t row) const {printrow(row); } // for use in gdb
     674              : 
     675              : 
     676              : 
     677              : 
     678              : 
     679              : private:
     680              :         // private functions
     681              : 
     682              :         void add_iterator(size_t row) const
     683              :         {
     684              : #ifdef CHECK_ROW_ITERATORS
     685              :                 nrOfRowIterators[row]++;
     686              : #endif
     687         1445 :                 iIterators++;
     688              :         }
     689              :         void remove_iterator(size_t row) const
     690              :         {
     691              : #ifdef CHECK_ROW_ITERATORS
     692              :                 nrOfRowIterators[row]--;
     693              :                 UG_ASSERT(nrOfRowIterators[row] >= 0, row);
     694              : #endif
     695        13613 :                 iIterators--;
     696              :                 UG_ASSERT(iIterators >= 0, row);
     697              : 
     698              :         }
     699              :         inline void check_row(size_t row, int i) const
     700              :         {
     701              :                 UG_ASSERT(i < rowEnd[row] && i >= rowStart[row], "row iterator row " << row << " pos " << i << " out of bounds [" << rowStart[row] << ", " << rowEnd[row] << "]");
     702              :         }
     703              :     void assureValuesSize(size_t s);
     704              :     size_t get_nnz() const { return nnz; }
     705              : 
     706              : private:
     707              :         // disallowed operations (not defined):
     708              :         //---------------------------------------
     709              :         SparseMatrix(SparseMatrix&); ///< disallow copy operator
     710              : 
     711              : 
     712              : protected:
     713              :         int get_index_internal(size_t row, int col) const;
     714              :     int get_index_const(int r, int c) const;
     715              :     int get_index(int r, int c);
     716              :     void copyToNewSize(size_t newSize)
     717              :     {
     718          150 :         copyToNewSize(newSize, num_cols());
     719          150 :     }
     720              :     void copyToNewSize(size_t newSize, size_t maxCols);
     721              :         void check_fragmentation() const;
     722              :         int get_nnz_max_cols(size_t maxCols);
     723              : 
     724              : public: // bug
     725              :         int col(size_t i) const{
     726              :                 assert(i<cols.size());
     727              :                 return cols[i];
     728              :         }
     729              : 
     730              : #ifndef NDEBUG
     731              :         int iters() const{
     732              :                 return iIterators;
     733              :         }
     734              : #endif
     735              : 
     736              : protected:
     737              :     std::vector<int> rowStart;
     738              :     std::vector<int> rowEnd;
     739              :     std::vector<int> rowMax;
     740              :     std::vector<int> cols;
     741              :     size_t fragmented;
     742              :     size_t nnz;
     743              :     bool bNeedsValues;
     744              : 
     745              :     std::vector<value_type> values;
     746              :     int maxValues;
     747              :     int m_numCols;
     748              :     mutable int iIterators;
     749              : 
     750              : #ifdef CHECK_ROW_ITERATORS
     751              : public:
     752              :     mutable std::vector<int> nrOfRowIterators;
     753              : #endif
     754              : };
     755              : 
     756              : 
     757              : template<typename T>
     758              : struct matrix_algebra_type_traits<SparseMatrix<T> >
     759              : {
     760              :         enum{
     761              :                 type=MATRIX_USE_ROW_FUNCTIONS
     762              :         };
     763              : };
     764              : 
     765              : //! calculates dest = alpha1*v1 + beta1 * A1^T *w1;
     766              : template<typename vector_t, typename matrix_t>
     767              : inline void MatMultTransposedAdd(vector_t &dest,
     768              :                 const number &alpha1, const vector_t &v1,
     769              :                 const number &beta1, const SparseMatrix<matrix_t> &A1, const vector_t &w1)
     770              : {
     771              :         A1.axpy_transposed(dest, alpha1, v1, beta1, w1);
     772              : }
     773              : 
     774              : 
     775              : 
     776              : 
     777              : 
     778              : 
     779              : 
     780              : 
     781              : // end group cpu_algebra
     782              : /// \}
     783              : 
     784              : } // namespace ug
     785              : 
     786              : //#include "matrixrow.h"
     787              : #include "sparsematrix_impl.h"
     788              : #include "sparsematrix_print.h"
     789              : 
     790              : #endif
        

Generated by: LCOV version 2.0-1