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