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