SparseLibrary  Version 1.6.0
SVM.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 <vector>
37 
38 //#define _DEBUG
39 
40 #ifndef _H_SVM
41 #define _H_SVM
42 
43 #ifdef _DEBUG
44 #include<iostream>
45 #endif
46 
50 template< typename T >
51 class SVM: public SparseMatrix< T, ULI > {
52 
53  private:
54 
55  protected:
56 
58  char major;
59 
61  std::vector< std::vector< Triplet< T > > > ds;
62 
64  static int compareTripletsR( const void * left, const void * right ) {
65  const Triplet< T > one = *( (Triplet< T > *)left );
66  const Triplet< T > two = *( (Triplet< T > *)right );
67  if ( one.j() < two.j() )
68  return -1;
69  if ( one.j() > two.j() )
70  return 1;
71  return 0;
72  }
73 
75  static int compareTripletsC( const void * left, const void * right ) {
76  const Triplet< T > one = *( (Triplet< T > *)left );
77  const Triplet< T > two = *( (Triplet< T > *)right );
78  if ( one.i() < two.i() )
79  return -1;
80  if ( one.i() > two.i() )
81  return 1;
82  return 0;
83  }
84 
92  bool find( const ULI col_index, const ULI row_index, Triplet< double > &ret ) {
93  if( major ) { //column major
94  std::vector< Triplet< double > >::iterator it = ds.at( col_index ).begin();
96  while( it!=ds.get( col_index ).end() ) {
97  cur = *(it++);
98  if( cur.i() == row_index ) {
99  ret = cur;
100  return true;
101  }
102  }
103  } else {
104  std::vector< Triplet< double > >::iterator it = ds.get( row_index ).begin();
105  Triplet< double > cur;
106  while( it!=ds.get( row_index ).end() ) {
107  cur = *(it++);
108  if( cur.j() == col_index ) {
109  ret = cur;
110  return true;
111  }
112  }
113  }
114  return false;
115  }
116 
117  public:
118 
120  SVM() {}
121 
126  SVM( std::string file, T zero = 0 ) {
127  this->loadFromFile( file, zero );
128  }
129 
137  SVM( const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, const T zero ):
138  SparseMatrix< T, ULI >( number_of_nonzeros, number_of_rows, number_of_cols, zero ) {}
139 
143  SVM( SVM< T >& toCopy ) {
144  this->zero_element = toCopy.zero_element;
145  this->nnz = toCopy.nnz;
146  this->nor = toCopy.nor;
147  this->noc = toCopy.noc;
148  major = toCopy.major;
149  for( ULI i=0; i<(major?this->noc:this->nor); i++ ) {
150  std::vector< Triplet< double > > toAdd;
151  std::vector< Triplet< double > >::iterator it = toCopy.ds.get( i ).begin();
152  while( it!=toCopy.ds.get( i ).end() ) toAdd.push_back( *(it++) );
153  ds.push_back( toAdd );
154  }
155  }
156 
168  SVM( const std::vector< Triplet< T > >& input, const ULI m, const ULI n, const T zero, const char direction = 0 ) {
169  load( input, m, n, zero, direction );
170  }
171 
176  virtual void load( std::vector< Triplet< T > >& input, const ULI m, const ULI n, const T zero ) {
177  load( input, m, n, zero, 0 );
178  }
179 
191  void load( const std::vector< Triplet< T > >& input, const ULI m, const ULI n, const T zero, const char direction ) {
192  this->zero_element = zero;
193  this->nnz = input.size();
194  this->nor = m;
195  this->noc = n;
196  major = direction;
197 
198  //build datastructure, move input there
199  ds.resize(major?this->noc:this->nor);
200  typename std::vector< Triplet< T > >::const_iterator in_it = input.begin();
201  for( ; in_it != input.end(); in_it++ ) {
202  Triplet< T > cur = *in_it;
203  const ULI currow = major ? cur.j() : cur.i();
204  const T value = cur.value;
205  if( value == this->zero_element ) { this->nnz--; continue; }
206  ds.at( currow ).push_back( cur );
207  }
208 
209  //sort
210  for( ULI currow = 0; currow < this->nor; currow++ ) {
211  if( ds.at( currow ).size() == 0 ) continue;
212  qsort( &( ds.at( currow )[ 0 ] ), ds.at( currow ).size(), sizeof( Triplet< T > ),
214  }
215  }
216 
220  std::vector< std::vector< Triplet< double > > >& getData() {
221  return ds;
222  }
223 
230  T& random_access( ULI i, ULI j ) {
231  Triplet< T > ret;
232  if ( find( i, j, ret ) ) {
233  return ret.value;
234  } else
235  return this->zero_element;
236  }
237 
239  virtual void getFirstIndexPair( ULI &row, ULI &col ) {
240  row = ds[0].at(0).i();
241  col = ds[0].at(0).j();
242  }
243 
250  virtual void zxa( const T*__restrict__ x, T*__restrict__ z ) {
251  if( major ) {
252  ULI col;
253  for( col = 0; col < this->noc; col++, z++ ) {
254  std::vector< Triplet< double > >::iterator it = ds.at( col ).begin();
255  while( it!=ds.at(col).end() ) {
256  const Triplet< double > cur = *(it++);
257  *z += cur.value * x[ cur.i() ];
258  }
259  }
260  } else {
261  ULI row;
262  for( row = 0; row < this->nor; row++, x++ ) {
263  std::vector< Triplet< double > >::iterator it = ds.at( row ).begin();
264  while( it!=ds.at( row ).end() ) {
265  const Triplet< double > cur = *(it++);
266  z[ cur.j() ] += cur.value * *x;
267  }
268  }
269  }
270  }
271 
278  virtual void zax( const T*__restrict__ x, T*__restrict__ z ) {
279  if( major ) {
280  ULI col;
281  for( col = 0; col < this->noc; col++, x++ ) {
282  std::vector< Triplet< double > >::iterator it = ds.at( col ).begin();
283  while( it!=ds.at(col).end() ) {
284  const Triplet< double > cur = *(it++);
285  z[ cur.i() ] = cur.value * *x;
286  }
287  }
288  } else {
289  ULI row;
290  for( row = 0; row < this->nor; row++, z++ ) {
291  std::vector< Triplet< double > >::iterator it = ds.at( row ).begin();
292  while( it!=ds.at( row ).end() ) {
293  const Triplet< double > cur = *(it++);
294  *z += cur.value * x[ cur.j() ];
295  }
296  }
297  }
298  }
299 
300  virtual size_t bytesUsed() {
301  //not optimal since Triplets are stored within vectors of vectors (the last term is unnecessary)
302  return sizeof( ULI ) * 2 * this->nnz + sizeof( T ) * this->nnz + sizeof( void* ) * this->nor;
303  }
304 
306  ~SVM() {}
307 
308 };
309 
310 #undef _DEBUG
311 #endif
312 
ULI nnz
Number of non-zeros.
Definition: SparseMatrix.hpp:58
SVM(const std::vector< Triplet< T > > &input, const ULI m, const ULI n, const T zero, const char direction=0)
Constructor which transforms a collection of input triplets to SVM format.
Definition: SVM.hpp:168
~SVM()
Base deconstructor.
Definition: SVM.hpp:306
SVM(const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, const T zero)
Base constructor which only initialises the internal arrays.
Definition: SVM.hpp:137
static int compareTripletsR(const void *left, const void *right)
Sorts 1D columnwise.
Definition: SVM.hpp:64
ULI i() const
Definition: Triplet.hpp:70
virtual unsigned long int m()
Queries the number of rows this matrix contains.
Definition: SparseMatrix.hpp:107
std::vector< std::vector< Triplet< double > > > & getData()
Definition: SVM.hpp:220
static int compareTripletsC(const void *left, const void *right)
Sorts 1D rowwise.
Definition: SVM.hpp:75
virtual void load(std::vector< Triplet< T > > &input, const ULI m, const ULI n, const T zero)
This will default to row-major SVM format.
Definition: SVM.hpp:176
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
SVM(SVM< T > &toCopy)
Copy constructor.
Definition: SVM.hpp:143
std::vector< std::vector< Triplet< T > > > ds
SVM structure.
Definition: SVM.hpp:61
SVM(std::string file, T zero=0)
Base constructor.
Definition: SVM.hpp:126
bool find(const ULI col_index, const ULI row_index, Triplet< double > &ret)
Helper function which finds a value with a given index.
Definition: SVM.hpp:92
ULI noc
Number of columns.
Definition: SparseMatrix.hpp:55
virtual void zax(const T *__restrict__ x, T *__restrict__ z)
In-place z=Ax function.
Definition: SVM.hpp:278
virtual void zxa(const T *__restrict__ x, T *__restrict__ z)
In-place z=xA function.
Definition: SVM.hpp:250
SVM()
Base constructor.
Definition: SVM.hpp:120
virtual void getFirstIndexPair(ULI &row, ULI &col)
Returns the first nonzero index, per reference.
Definition: SVM.hpp:239
The sparse vector matrix format.
Definition: SVM.hpp:51
void load(const std::vector< Triplet< T > > &input, const ULI m, const ULI n, const T zero, const char direction)
Will load a collection of triplets into SVM format.
Definition: SVM.hpp:191
virtual size_t bytesUsed()
Function to query the amount of storage required by this sparse matrix.
Definition: SVM.hpp:300
T value
Value stored at this triplet.
Definition: Triplet.hpp:95
char major
Row major (0), column major (1)
Definition: SVM.hpp:58
T & random_access(ULI i, ULI j)
Method which provides random matrix access to the stored sparse matrix.
Definition: SVM.hpp:230
ULI nor
Number of rows.
Definition: SparseMatrix.hpp:52
T zero_element
The element considered to be zero.
Definition: SparseMatrix.hpp:63
ULI j() const
Definition: Triplet.hpp:73
virtual unsigned long int n()
Queries the number of columns this matrix contains.
Definition: SparseMatrix.hpp:115
A single triplet value.
Definition: Triplet.hpp:52