IVSparse  v1.0
A sparse matrix compression library.
CSC_Operators.hpp
Go to the documentation of this file.
1 
9 #pragma once
10 
11 namespace IVSparse {
12 
13  // Assignment Operator
14  template <typename T, typename indexT, bool columnMajor>
15  SparseMatrix<T, indexT, 1, columnMajor> &SparseMatrix<T, indexT, 1, columnMajor>::operator=(const IVSparse::SparseMatrix<T, indexT, 1, columnMajor> &other) {
16 
17  // check for self assignment
18  if (this != &other) {
19 
20  // free the old data
21  if (vals != nullptr) { free(vals); }
22  if (innerIdx != nullptr) { free(innerIdx); }
23  if (outerPtr != nullptr) {free(outerPtr);}
24  if (metadata != nullptr) {delete[] metadata;}
25 
26  // Deep copy the matrix
27  metadata = new uint32_t[NUM_META_DATA];
28  memcpy(metadata, other.metadata, NUM_META_DATA * sizeof(uint32_t));
29 
30  // set the dimensions of the matrix
31  numRows = other.numRows;
32  numCols = other.numCols;
33  outerDim = other.outerDim;
34  innerDim = other.innerDim;
35  nnz = other.nnz;
36  compSize = other.compSize;
37 
38  // encode the value type and index type
39  encodeValueType();
40  index_t = sizeof(indexT);
41 
42  // check for an empty matrix
43  if (nnz == 0) {
44  vals = nullptr;
45  innerIdx = nullptr;
46  outerPtr = nullptr;
47  }
48 
49  // allocate the memory
50  try {
51  vals = (T *)malloc(nnz * sizeof(T));
52  innerIdx = (indexT *)malloc(nnz * sizeof(indexT));
53  outerPtr = (indexT *)malloc((outerDim + 1) * sizeof(indexT));
54  } catch (std::bad_alloc &e) {
55  std::cerr << "Error: Failed to allocate memory for the matrix" << std::endl;
56  exit(1);
57  }
58 
59  // copy the data
60  memcpy(vals, other.vals, nnz * sizeof(T));
61  memcpy(innerIdx, other.innerIdx, nnz * sizeof(indexT));
62  memcpy(outerPtr, other.outerPtr, (outerDim + 1) * sizeof(indexT));
63  }
64 
65  // return the matrix
66  return *this;
67  }
68 
69  // Equality Operator
70  template <typename T, typename indexT, bool columnMajor>
71  bool SparseMatrix<T, indexT, 1, columnMajor>::operator==(const SparseMatrix<T, indexT, 1, columnMajor> &other) {
72  // check if the dimensions are the same
73  if (numRows != other.numRows || numCols != other.numCols) { return false; }
74 
75  // check if the number of nonzeros are the same
76  if (nnz != other.nnz) { return false; }
77 
78  // check the matrix data against each other
79  if (memcmp(vals, other.vals, nnz * sizeof(T)) != 0) { return false; }
80  if (memcmp(innerIdx, other.innerIdx, nnz * sizeof(indexT)) != 0) { return false; }
81  if (memcmp(outerPtr, other.outerPtr, (outerDim + 1) * sizeof(indexT)) != 0) { return false; }
82 
83  // if all the data is the same return true
84  return true;
85  }
86 
87  // Inequality Operator
88  template <typename T, typename indexT, bool columnMajor>
89  bool SparseMatrix<T, indexT, 1, columnMajor>::operator!=(const SparseMatrix<T, indexT, 1, columnMajor> &other) {
90  return !(*this == other);
91  }
92 
93  // Coefficent Access Operator
94  template <typename T, typename indexT, bool columnMajor>
95  T SparseMatrix<T, indexT, 1, columnMajor>::operator()(uint32_t row, uint32_t col)
96  {
97 
98  // check if the row and column are in bounds
99  if (row >= numRows || col >= numCols) {
100  std::cerr << "Error: Index out of bounds" << std::endl;
101  exit(1);
102  }
103 
104  // get the vector and index
105  uint32_t vector = columnMajor ? col : row;
106  uint32_t index = columnMajor ? row : col;
107 
108  // get an iterator for the desired vector
109  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it(*this, vector); it; ++it) {
110  if (it.getIndex() == (indexT)index) {
111  // if the index is found return the value
112  return it.value();
113  }
114  }
115 
116  // if the index is not found return 0
117  return 0;
118  }
119 
120  // Vector Access Operator
121  template <typename T, typename indexT, bool columnMajor>
122  typename SparseMatrix<T, indexT, 1, columnMajor>::Vector SparseMatrix<T, indexT, 1, columnMajor>::operator[](uint32_t vec) {
123 
124  #ifdef CSF_DEBUG
125  // check if the vector is out of bounds
126  assert((vec < outerDim && vec >= 0) && "Vector index out of bounds");
127  #endif
128 
129  // return a IVSparse vector
130  typename IVSparse::SparseMatrix<T, indexT, 1, columnMajor>::Vector newVector(*this, vec);
131  return newVector;
132  }
133 
134  //* BLAS Operators *//
135 
136  // Scalar Multiplication
137  template <typename T, typename indexT, bool columnMajor>
138  IVSparse::SparseMatrix<T, indexT, 1, columnMajor> SparseMatrix<T, indexT, 1, columnMajor>::operator*(T scalar) {
139  return scalarMultiply(scalar);
140  }
141 
142  // In place scalar multiplication
143  template <typename T, typename indexT, bool columnMajor>
144  void SparseMatrix<T, indexT, 1, columnMajor>::operator*=(T scalar) {
145  return inPlaceScalarMultiply(scalar);
146  }
147 
148  // IVSparse Matrix * IVSparse Vector Multiplication
149  template <typename T, typename indexT, bool columnMajor>
150  Eigen::VectorXd SparseMatrix<T, indexT, 1, columnMajor>::operator*(SparseMatrix<T, indexT, 1, columnMajor>::Vector &vec) {
151  return vectorMultiply(vec);
152  }
153 
154  // Matrix Vector Multiplication (IVSparse Eigen -> Eigen)
155  template <typename T, typename indexT, bool columnMajor>
156  Eigen::VectorXd SparseMatrix<T, indexT, 1, columnMajor>::operator*(Eigen::VectorXd &vec) {
157  return vectorMultiply(vec);
158  }
159 
160  // Matrix Matrix Multiplication (IVSparse Eigen -> Eigen)
161  template <typename T, typename indexT, bool columnMajor>
162  Eigen::Matrix<T, -1, -1> SparseMatrix<T, indexT, 1, columnMajor>::operator*(Eigen::Matrix<T, -1, -1> mat) {
163  return matrixMultiply(mat);
164  }
165 
166 } // namespace IVSparse
Definition: CSC_SparseMatrix.hpp:24
Definition: IVCSC_SparseMatrix.hpp:27