IVSparse  v1.0
A sparse matrix compression library.
IVCSC_Vector_Methods.hpp
1 
9 #pragma once
10 
11 namespace IVSparse
12 {
13 
14  //* Constructors and Destructor *//
15 
16  // Destructor
17  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
19  {
20  if (data != nullptr)
21  {
22  free(data);
23  }
24  }
25 
26  // Length Constructor
27  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
29 
30  // IVSparse Matrix Constructor
31  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
33  {
34 
35 #ifdef CSF_DEBUG
36  assert((vec >= 0 && vec < mat.outerSize()) && "Vector index out of bounds");
37  assert((mat.outerSize() > 0 && mat.innerSize() > 0) && "Matrix is empty");
38 #endif
39 
40  // get the length of the vector
41  size = mat.getVectorSize(vec);
42  length = mat.innerSize();
43 
44  // if the size is 0 then the vector is empty
45  if (size == 0)
46  {
47  data = nullptr;
48  endPtr = nullptr;
49  return;
50  }
51 
52  // set data pointer
53  try
54  {
55  data = malloc(size);
56  }
57  catch (std::bad_alloc &e)
58  {
59  std::cerr << e.what() << '\n';
60  }
61 
62  // copy the vector data into the vector
63  memcpy(data, mat.vectorPointer(vec), size);
64 
65  // set the end pointer
66  endPtr = (uint8_t *)data + size;
67 
68  // set the nnz
69  if (nnz == 0 && size > 0)
70  {
71  // make an iterator for the vector
73 
74  // iterate through the vector until the index is found
75  while (it)
76  {
77  nnz++;
78  ++it;
79  }
80  }
81 
82  } // End of IVSparse Matrix Constructor
83 
84  // Deep copy constructor
85  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
87  {
88  // set the size
89  size = vec.size;
90 
91  // set the length
92  length = vec.length;
93 
94  // if the size is 0 then the vector is empty
95  if (size == 0)
96  {
97  data = nullptr;
98  endPtr = nullptr;
99  return;
100  }
101 
102  // set data pointer
103  try
104  {
105  data = malloc(size);
106  }
107  catch (std::bad_alloc &e)
108  {
109  std::cerr << e.what() << '\n';
110  }
111 
112  // copy the vector data into the vector
113  memcpy(data, vec.data, size);
114 
115  // set the end pointer
116  endPtr = (uint8_t *)data + size;
117 
118  // set the nnz
119  nnz = vec.nonZeros();
120 
121 #ifdef CSF_DEBUG
122  userChecks();
123 #endif
124  }
125 
126  //* Private Class Methods *//
127 
128  // User checks to confirm a valid vector
129  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
131  {
132  assert(std::is_floating_point<indexT>::value == false && "The index type must be a non-floating point type");
133  assert((compressionLevel == 1 || compressionLevel == 2 || compressionLevel == 3) && "The compression level must be either 1, 2, or 3");
134  assert((std::is_arithmetic<T>::value && std::is_arithmetic<indexT>::value) && "The value and index types must be numeric types");
135  assert((std::is_same<indexT, bool>::value == false) && "The index type must not be bool");
136  }
137 
138  // Calculates the size of the vector in bytes
139  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
141  {
142  size = 0;
143 
144  size += sizeof(void *); // data pointer
145  size += sizeof(void *); // end pointer
146 
147  // add distance between data and end pointer in bytes to size
148  size += (uint8_t *)endPtr - (uint8_t *)data;
149  }
150 
151  //* Getters *//
152 
153  // Get the inner dimension of the vector
154  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
156 
157  // Get the outer dimension of the vector
158  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
160 
161  // Get the number of non-zero elements in the vector
162  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
164 
165  // Get a pointer to the beginning of the vector
166  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
168 
169  // Get a pointer to the end of the vector
170  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
172 
173  // Get the size of the vector in bytes
174  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
176 
177  // Update the value of the vector at the given index
178  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
180 
181  // Get the length of the vector
182  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
184 
185  //* Utility Methods *//
186 
187  // Prints the vector to console dense
188  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
190  {
191 
192  // if length is larger than 100 then print then don't print
193  if (length > 100)
194  {
195  std::cout << "Vector is too large to print" << std::endl;
196  return;
197  }
198 
199  std::cout << "Vector: ";
200  std::cout << std::endl;
201 
202  // print a dense vector
203  for (uint32_t i = 0; i < length; i++)
204  {
205  std::cout << (*this)[i] << " ";
206  }
207 
208  std::cout << std::endl;
209  }
210 
211  //* Calculations *//
212 
213  // Calculates the norm of the vector
214  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
216  {
217  double norm = 0;
219  {
220  norm += it.value() * it.value();
221  }
222  return sqrt(norm);
223  }
224 
225  // Calculates the sum of the vector
226  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
228  {
229  double sum = 0;
231  {
232  sum += it.value();
233  }
234  return sum;
235  }
236 
237  // Calculates the dot product of the vector with an Eigen dense vector
238  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
240  {
241  double dot = 0;
242 
244  {
245  dot += it.value() * other.coeff(it.row());
246  }
247 
248  return dot;
249  }
250 
251  // Calculates the dot product of the vector with an Eigen sparse vector
252  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
254  {
255  double dot = 0;
256 
258  {
259  dot += it.value() * other.coeff(it.row());
260  }
261  return dot;
262  }
263 
264  //* Operator Overloads *//
265 
266  // Assignment Operator
267  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
269  {
270  // check if the vector is the same
271  if (this == &other)
272  {
273  return *this;
274  }
275 
276  // free the data if it is not null
277  if (data != nullptr)
278  {
279  free(data);
280  }
281 
282  // if the other vector is empty then return
283  if (other.data == nullptr)
284  {
285  data = nullptr;
286  endPtr = nullptr;
287  size = 0;
288  length = other.length;
289  nnz = 0;
290  return *this;
291  }
292 
293  // copy the data
294  data = (uint8_t *)malloc(other.size);
295  memcpy(data, other.data, other.size);
296 
297  size = other.size;
298  length = other.length;
299  nnz = other.nnz;
300  endPtr = (uint8_t *)data + size;
301 
302  // return this
303  return *this;
304  }
305 
306  // equality operator
307  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
308  bool SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector::operator==(typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector &other)
309  {
310  // check if the length is the same
311  if (length != other.length)
312  {
313  return false;
314  }
315 
316  // check the nnz
317  if (nnz != other.nnz)
318  {
319  return false;
320  }
321 
322  // check data equality
323  if (memcmp(data, other.data, size) != 0)
324  {
325  return false;
326  }
327 
328  // return true
329  return true;
330  }
331 
332  // inequality operator
333  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
334  bool SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector::operator!=(typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector &other)
335  {
336  return !(*this == other);
337  }
338 
339  // Coefficient Operator
340  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
341  T SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector::operator[](uint32_t index)
342  {
343 
344 #ifdef CSF_DEBUG
345  // check if the index is out of bounds
346  assert(index < length && "The index is out of bounds");
347 #endif
348 
349  // make an iterator for the vector
351 
352  // iterate through the vector until the index is found
353  while (it)
354  {
355  if (it.getIndex() == (indexT)index)
356  {
357  return it.value();
358  }
359  ++it;
360  }
361 
362  // if the index is not found then return 0
363  return 0;
364  }
365 
366  // In place scalar multiplication
367  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
368  void SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector::operator*=(T scalar)
369  {
370  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this); it; ++it)
371  {
372  if (it.isNewRun())
373  {
374  it.coeff(it.value() * scalar);
375  }
376  }
377  }
378 
379  // Scalar multiplication
380  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
381  typename IVSparse::SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector::operator*(T scalar)
382  {
384 
385  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(newVector); it; ++it)
386  {
387  if (it.isNewRun())
388  {
389  it.coeff(it.value() * scalar);
390  }
391  }
392  return newVector;
393  }
394 
395 } // namespace IVSparse
Definition: IVCSC_Iterator.hpp:25
Definition: IVCSC_Vector.hpp:27
uint32_t getLength()
Definition: IVCSC_Vector_Methods.hpp:183
T coeff(uint32_t index)
Definition: IVCSC_Vector_Methods.hpp:179
void print()
Definition: IVCSC_Vector_Methods.hpp:189
uint32_t innerSize()
Definition: IVCSC_Vector_Methods.hpp:155
T sum()
Definition: IVCSC_Vector_Methods.hpp:227
void * end()
Definition: IVCSC_Vector_Methods.hpp:171
size_t byteSize()
Definition: IVCSC_Vector_Methods.hpp:175
Vector()
Definition: IVCSC_Vector.hpp:61
double norm()
Definition: IVCSC_Vector_Methods.hpp:215
uint32_t nonZeros()
Definition: IVCSC_Vector_Methods.hpp:163
void * begin()
Definition: IVCSC_Vector_Methods.hpp:167
uint32_t outerSize()
Definition: IVCSC_Vector_Methods.hpp:159
~Vector()
Definition: IVCSC_Vector_Methods.hpp:18
double dot(Eigen::Vector< T, -1 > &other)
Definition: IVCSC_Vector_Methods.hpp:239
uint32_t innerSize() const
Definition: IVSparse_Base_Methods.hpp:28
uint32_t outerSize() const
Definition: IVSparse_Base_Methods.hpp:31
Definition: IVCSC_SparseMatrix.hpp:27
T sum()
Definition: IVCSC_BLAS.hpp:219
double norm()
Definition: IVCSC_BLAS.hpp:232
void * vectorPointer(uint32_t vec)
Definition: IVCSC_Methods.hpp:25
size_t getVectorSize(uint32_t vec) const
Definition: IVCSC_Methods.hpp:33