SparseLibrary  Version 1.6.0
ZZ_CRS.hpp
1 /*
2  * Copyright (c) 2007-2014, A. N. Yzelman, Utrecht University 2007-2011;
3  * KU Leuven 2011-2014.
4  * R. H. Bisseling, Utrecht University 2007-2014.
5  *
6  * This file is part of the Sparse Library.
7  *
8  * This library was developed under supervision of Prof. dr. Rob H. Bisseling at
9  * Utrecht University, from 2007 until 2011. From 2011-2014, development continued
10  * at KU Leuven, where Prof. dr. Dirk Roose contributed significantly to the ideas
11  * behind the newer parts of the library code.
12  *
13  * The Sparse Library is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by the
15  * Free Software Foundation, either version 3 of the License, or (at your
16  * option) any later version.
17  *
18  * The Sparse Library is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  * for more details.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with the Sparse Library. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 
28 /*
29  * File created by:
30  * A. N. Yzelman, Dept. of Mathematics, Utrecht University, 2009.
31  */
32 
33 
34 #include "SparseMatrix.hpp"
35 #include "Triplet.hpp"
36 #include <assert.h>
37 #include <vector>
38 #include <algorithm>
39 #include<iostream>
40 
41 //#define _DEBUG
42 
43 #ifndef _H_ZZ_CRS
44 #define _H_ZZ_CRS
45 
49 template< typename T, typename _i_value=LI >
50 class ZZ_CRS: public SparseMatrix< T, LI > {
51 
52  private:
53 
54  protected:
55 
57  T* ds;
58 
60  LI* col_ind;
61 
63  LI* row_start;
64 
66  static bool compareTripletsLTR( const Triplet< T >* one, const Triplet< T >* two ) {
67  if( one->i() < two->i() )
68  return true;
69  if ( one->i() > two->i() )
70  return false;
71  return one->j() < two->j();
72  }
73 
75  static bool compareTripletsRTL( const Triplet< T >* one, const Triplet< T >* two ) {
76  if( one->i() < two->i() )
77  return true;
78  if ( one->i() > two->i() )
79  return false;
80  return one->j() > two->j();
81  }
82 
83  public:
84 
86  ZZ_CRS() {}
87 
92  ZZ_CRS( std::string file, T zero = 0 ) {
93  this->loadFromFile( file, zero );
94  }
95 
105  ZZ_CRS( const long int number_of_nonzeros, const long int number_of_rows, const long int number_of_cols, T zero ):
106  SparseMatrix< T, unsigned long int >( number_of_nonzeros, number_of_rows, number_of_cols, zero ) {
107  ds = new T[ this->nnz ];
108  col_ind = new long int[ this->nnz ];
109  row_start = new long int[ this->nor + 1 ];
110  }
111 
116  ZZ_CRS( ZZ_CRS< T >& toCopy ) {
117  this->zero_element = toCopy.zero_element;
118  this->nnz = toCopy.nnz;
119  this->noc = toCopy.noc;
120  this->nor = toCopy.nor;
121  ds = new T[ this->nnz ];
122  col_ind = new long int[ this->nnz ];
123  row_start = new long int[ this->nor ];
124  for( long int i=0; i<this->nnz; i = i + 1 ) {
125  ds[ i ] = toCopy.ds[ i ];
126  col_ind[ i ]= toCopy.col_ind[ i ];
127  }
128  for( long int i=0; i<=this->nor; i++ )
129  row_start[ i ] = toCopy.row_start[ i ];
130  }
131 
142  ZZ_CRS( std::vector< Triplet< T > >& input, const LI m, const LI n, const T zero ) {
143  load( input, m, n, zero );
144  }
145 
147  virtual void load( std::vector< Triplet< T > >& input, const LI m, const LI n, const T zero ) {
148  this->zero_element = zero;
149  this->nnz = input.size();
150  this->nor = m;
151  this->noc = n;
152 
153  std::vector< std::vector< Triplet< T >* > > ds( this->nor );
154 
155  //move input there
156  typename std::vector< Triplet< T > >::iterator in_it = input.begin();
157  for( ; in_it != input.end(); in_it++ ) {
158  Triplet< T >* cur = &(*in_it);
159  const long int currow = cur->i();
160  const T value = cur->value;
161  if( value == this->zero_element ) { this->nnz--; continue; }
162  ds.at( currow ).push_back( cur );
163  }
164 
165  //allocate arrays
166  this->ds = new T[ this->nnz ];
167  col_ind = new LI[ this->nnz ];
168  row_start = new LI[ this->nor + 1 ];
169 
170  //make ZZ-CRS
171  long int index = 0;
172  bool LTR = true;
173  for( long int currow = 0; currow < this->nor; currow++ ) {
174  row_start[ currow ] = index;
175  if( ds.at( currow ).size() == 0 ) continue;
176  if( LTR )
177  sort( ds.at( currow ).begin(), ds.at( currow ).end(), compareTripletsLTR );
178  else
179  sort( ds.at( currow ).begin(), ds.at( currow ).end(), compareTripletsRTL );
180  LTR = !LTR;
181  typename std::vector< Triplet< T >* >::iterator row_it = ds.at( currow ).begin();
182  for( ; row_it!=ds.at( currow ).end(); row_it++ ) {
183  const Triplet< T > cur = *(*row_it);
184  this->ds[ index ] = cur.value;
185  col_ind[ index ] = cur.j();
186  index++;
187  }
188  }
189  assert( index == this->nnz );
190  row_start[ this->nor ] = this->nnz;
191  }
192 
194  virtual void getFirstIndexPair( LI &row, LI &col ) {
195  row = static_cast< unsigned long int >( this->row_start[ 0 ] );
196  col = static_cast< unsigned long int >( this->col_ind[ 0 ] );
197  }
198 
205  virtual void zxa( const T* x, T* z ) {
206  T*__restrict__ ds_p = ds;
207  LI*__restrict__ col_ind_p = col_ind;
208  LI row, index;
209  for( row = 0; row < this->nor; row++, x++ ) {
210  for( index = row_start[ row ]; index < row_start[ row + 1 ]; index++ )
211  z[ *col_ind_p++ ] += *ds_p++ * *x;
212  }
213  }
214 
221  virtual void zax( const T*__restrict__ x, T*__restrict z ) {
222  T*__restrict__ ds_p = ds;
223  _i_value*__restrict__ col_ind_p = col_ind;
224  long int index=0,row=0;
225  for( ; row < this->nor; row++, z++ )
226  for( index = row_start[ row ]; index < row_start[ row + 1 ]; index++ )
227  *z += *ds_p++ * x[ *col_ind_p++ ];
228  }
229 
230  virtual size_t bytesUsed() {
231  return sizeof( LI ) * ( this->nnz + this->nor + 1 ) + sizeof( T ) * this->nnz;
232  }
233 
236  delete [] ds;
237  delete [] col_ind;
238  delete [] row_start;
239  }
240 
241 };
242 
243 #endif
244 
LI nnz
Number of non-zeros.
Definition: SparseMatrix.hpp:58
virtual void zxa(const T *x, T *z)
In-place z=xA multiplication algorithm.
Definition: ZZ_CRS.hpp:205
ZZ_CRS()
Base constructor.
Definition: ZZ_CRS.hpp:86
ZZ_CRS(std::string file, T zero=0)
Base constructor.
Definition: ZZ_CRS.hpp:92
LI * row_start
Array containing the row jumps.
Definition: ZZ_CRS.hpp:63
ULI i() const
Definition: Triplet.hpp:70
virtual size_t bytesUsed()
Function to query the amount of storage required by this sparse matrix.
Definition: ZZ_CRS.hpp:230
virtual unsigned long int m()
Queries the number of rows this matrix contains.
Definition: SparseMatrix.hpp:107
T * ds
Array containing the actual this->nnz non-zeros.
Definition: ZZ_CRS.hpp:57
ZZ_CRS(ZZ_CRS< T > &toCopy)
Copy constructor.
Definition: ZZ_CRS.hpp:116
ZZ_CRS(const long int number_of_nonzeros, const long int number_of_rows, const long int number_of_cols, T zero)
Base constructor which only initialises the internal arrays.
Definition: ZZ_CRS.hpp:105
void loadFromFile(const std::string file, const T zero=0)
Function which loads a matrix from a matrix market file.
Definition: SparseMatrix.hpp:89
Interface common to all sparse matrix storage schemes.
Definition: SparseMatrix.hpp:46
static bool compareTripletsRTL(const Triplet< T > *one, const Triplet< T > *two)
Comparison function used for sorting input data.
Definition: ZZ_CRS.hpp:75
static bool compareTripletsLTR(const Triplet< T > *one, const Triplet< T > *two)
Comparison function used for sorting input data.
Definition: ZZ_CRS.hpp:66
LI * col_ind
Array containing the column jumps.
Definition: ZZ_CRS.hpp:60
LI noc
Number of columns.
Definition: SparseMatrix.hpp:55
T value
Value stored at this triplet.
Definition: Triplet.hpp:95
virtual void load(std::vector< Triplet< T > > &input, const LI m, const LI n, const T zero)
Definition: ZZ_CRS.hpp:147
LI nor
Number of rows.
Definition: SparseMatrix.hpp:52
ZZ_CRS(std::vector< Triplet< T > > &input, const LI m, const LI n, const T zero)
Constructor which transforms a collection of input triplets to CRS format.
Definition: ZZ_CRS.hpp:142
T zero_element
The element considered to be zero.
Definition: SparseMatrix.hpp:63
The zig-zag compressed row storage sparse matrix data structure.
Definition: ZZ_CRS.hpp:50
ULI j() const
Definition: Triplet.hpp:73
virtual void getFirstIndexPair(LI &row, LI &col)
Returns the first nonzero index, per reference.
Definition: ZZ_CRS.hpp:194
virtual unsigned long int n()
Queries the number of columns this matrix contains.
Definition: SparseMatrix.hpp:115
virtual void zax(const T *__restrict__ x, T *__restrict z)
In-place z=Ax multiplication algorithm.
Definition: ZZ_CRS.hpp:221
A single triplet value.
Definition: Triplet.hpp:52
~ZZ_CRS()
Base deconstructor.
Definition: ZZ_CRS.hpp:235