IVSparse  v1.0
A sparse matrix compression library.
CSC_BLAS.hpp
Go to the documentation of this file.
1 
9 #pragma once
10 
11 namespace IVSparse {
12 
13 //* BLAS Level 1 Routines *//
14 
15 // Scalar Multiply
16 template <typename T, typename indexT, bool columnMajor>
18 SparseMatrix<T, indexT, 1, columnMajor>::scalarMultiply(T scalar) {
19 
20  // Deep copy the matrix
22 
23  // else use the iterator
24  #ifdef IVSPARSE_HAS_OPENMP
25  #pragma omp parallel for
26  #endif
27  for (uint32_t i = 0; i < this->outerDim; ++i) {
28  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it(newMatrix, i); it; ++it) {
29  if (it.isNewRun()) { it.coeff(it.value() * scalar); }
30  }
31  }
32  return newMatrix;
33 }
34 
35 // In Place Scalar Multiply
36 template <typename T, typename indexT, bool columnMajor>
37 inline void SparseMatrix<T, indexT, 1, columnMajor>::inPlaceScalarMultiply(T scalar) {
38 
39  // else use the iterator
40  #ifdef IVSPARSE_HAS_OPENMP
41  #pragma omp parallel for
42  #endif
43  for (int i = 0; i < nnz; i++) { vals[i] *= scalar; }
44 }
45 
46 //* BLAS Level 2 Routines *//
47 
48 // Matrix Vector Multiplication (Eigen::VectorXd * IVSparse::SparseMatrix)
49 template <typename T, typename indexT, bool columnMajor>
50 inline Eigen::VectorXd SparseMatrix<T, indexT, 1, columnMajor>::vectorMultiply(Eigen::VectorXd &vec) {
51 
52  #ifdef IVSPARSE_DEBUG
53  // check that the vector is the correct size
54  assert(vec.rows() == outerDim &&
55  "The vector must be the same size as the "
56  "number of columns in the matrix!");
57  #endif
58 
59  Eigen::Matrix<T, -1, 1> eigenTemp(innerDim, 1);
60  eigenTemp.setZero();
61 
62  // iterate over the vector and multiply the corresponding row of the matrix by
63  // the vecIter value
64  #ifdef IVSPARSE_HAS_OPENMP
65  #pragma omp parallel for
66  #endif
67  for (int i = 0; i < vec.rows(); ++i) {
68  if (vec(i) == 0) continue;
69  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator matIter(*this, i); matIter; ++matIter) {
70  eigenTemp.coeffRef(matIter.row()) += matIter.value() * vec(i);
71  }
72  }
73  return eigenTemp;
74 }
75 
76 // Matrix Vector Multiplication
77 // (IVSparse::SparseMatrix * IVSparse::SparseMatrix::Vector)
78 template <typename T, typename indexT, bool columnMajor>
79 inline Eigen::VectorXd SparseMatrix<T, indexT, 1, columnMajor>::vectorMultiply(typename SparseMatrix<T, indexT, 1, columnMajor>::Vector &vec) {
80 
81  #ifdef IVSPARSE_DEBUG
82  if (vec.length() != outerDim)
83  throw std::invalid_argument(
84  "The vector must be the same size as the "
85  "number of columns in the matrix!");
86  #endif
87 
88  Eigen::Matrix<T, -1, 1> newVector = Eigen::Matrix<T, -1, 1>::Zero(innerDim, 1);
89 
90  // #ifdef IVSPARSE_HAS_OPENMP
91  // #pragma omp parallel for
92  // #endif
93  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator vecIter(vec); vecIter; ++vecIter) {
94  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator matIter(*this, vecIter.row()); matIter; ++matIter) {
95  newVector.coeffRef(matIter.row()) += matIter.value() * vecIter.value();
96  }
97  }
98  return newVector;
99 }
100 
101 //* BLAS Level 3 Routines *//
102 
103 // Matrix Vector Multiplication (IVSparse::SparseMatrix * Eigen::Matrix)
104 template <typename T, typename indexT, bool columnMajor>
105 inline Eigen::Matrix<T, -1, -1> SparseMatrix<T, indexT, 1, columnMajor>::matrixMultiply(Eigen::Matrix<T, -1, -1> &mat) {
106 
107  #ifdef IVSPARSE_DEBUG
108  // check that the matrix is the correct size
109  if (mat.rows() != outerDim)
110  throw std::invalid_argument(
111  "The left matrix must be the same size as the number of columns in "
112  "the right matrix!");
113  #endif
114 
115  Eigen::Matrix<T, -1, -1> newMatrix = Eigen::Matrix<T, -1, -1>::Zero(innerDim, mat.cols());
116 
117  #ifdef IVSPARSE_HAS_OPENMP
118  #pragma omp parallel for
119  #endif
120  for (int col = 0; col < mat.cols(); col++) {
121  for (int row = 0; row < mat.rows(); row++) {
122  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator matIter(*this, row); matIter; ++matIter) {
123  newMatrix.coeffRef(matIter.row(), col) += matIter.value() * mat(row, col);
124  }
125  }
126  }
127  return newMatrix;
128 }
129 
130 //* Other Matrix Calculations *//
131 
132 // Finds the sum of each outer vector
133 template <typename T, typename indexT, bool columnMajor>
135 
136  std::vector<T> outerSum = std::vector<T>(outerDim);
137 
138  #ifdef IVSPARSE_HAS_OPENMP
139  #pragma omp parallel for
140  #endif
141  for (int i = 0; i < outerDim; i++) {
142  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
143  outerSum[i] += it.value();
144  }
145  }
146  return outerSum;
147 }
148 
149 // Finds the sum of each inner vector
150 template <typename T, typename indexT, bool columnMajor>
152 
153  std::vector<T> innerSum = std::vector<T>(innerDim);
154 
155  #ifdef IVSPARSE_HAS_OPENMP
156  #pragma omp parallel for
157  #endif
158  for (int i = 0; i < outerDim; i++) {
159  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
160  innerSum[it.row()] += it.value();
161  }
162  }
163  return innerSum;
164 }
165 
166 // Finds the max of each column
167 template <typename T, typename indexT, bool columnMajor>
169 
170  std::vector<T> maxCoeff = std::vector<T>(innerDim);
171 
172  #ifdef IVSPARSE_HAS_OPENMP
173  #pragma omp parallel for
174  #endif
175  for (int i = 0; i < outerDim; i++) {
176  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
177  if (it.value() > maxCoeff[i]) { maxCoeff[i] = it.value(); }
178  }
179  }
180  return maxCoeff;
181 }
182 
183 // Finds the max of each row
184 template <typename T, typename indexT, bool columnMajor>
186 
187  std::vector<T> maxCoeff = std::vector<T>(innerDim);
188 
189  #ifdef IVSPARSE_HAS_OPENMP
190  #pragma omp parallel for
191  #endif
192  for (int i = 0; i < outerDim; i++) {
193  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
194  if (it.value() > maxCoeff[it.row()]) { maxCoeff[it.row()] = it.value(); }
195  }
196  }
197  return maxCoeff;
198 }
199 
200 // Finds the min of each column
201 template <typename T, typename indexT, bool columnMajor>
203 
204  std::vector<T> minCoeff = std::vector<T>(innerDim);
205 
206  #ifdef IVSPARSE_HAS_OPENMP
207  #pragma omp parallel for
208  #endif
209  for (int i = 0; i < outerDim; i++) {
210  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
211  if (it.value() < minCoeff[i]) { minCoeff[i] = it.value(); }
212  }
213  }
214  return minCoeff;
215 }
216 
217 // Finds the min of each row
218 template <typename T, typename indexT, bool columnMajor>
220 
221  std::vector<T> minCoeff = std::vector<T>(innerDim);
222  memset(minCoeff.data(), 0xF, innerDim * sizeof(T));
223 
224  #ifdef IVSPARSE_HAS_OPENMP
225  #pragma omp parallel for
226  #endif
227  for (int i = 0; i < outerDim; i++) {
228  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
229  if (it.value() < minCoeff[it.row()]) { minCoeff[it.row()] = it.value(); }
230  }
231  }
232  return minCoeff;
233 }
234 
235 // finds the trace of the matrix
236 template <typename T, typename indexT, bool columnMajor>
238 
239  #ifdef IVSPARSE_DEBUG
240  assert(innerDim == outerDim && "Trace is only defined for square matrices!");
241  #endif
242 
243  T trace = 0;
244  #ifdef IVSPARSE_HAS_OPENMP
245  #pragma omp parallel for
246  #endif
247  for (int i = 0; i < outerDim; i++) {
248  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
249  if (it.row() == i) { trace += it.value(); }
250  else if (it.row() > i) { continue; }
251  }
252  }
253  return trace;
254 }
255 
256 // Finds the sum of the matrix
257 template <typename T, typename indexT, bool columnMajor>
259 
260  T sum = 0;
261 
262  #ifdef IVSPARSE_HAS_OPENMP
263  #pragma omp parallel for
264  #endif
265  for (int i = 0; i < outerDim; i++) {
266  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
267  sum += it.value();
268  }
269  }
270  return sum;
271 }
272 
273 // Finds the norm of the matrix
274 template <typename T, typename indexT, bool columnMajor>
276 
277  double norm = 0;
278 
279  for (int i = 0; i < outerDim; i++) {
280  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it( *this, i); it; ++it) {
281  norm += it.value() * it.value();
282  }
283  }
284  return sqrt(norm);
285 }
286 
287 // Finds the length of a vector in the matrix
288 template <typename T, typename indexT, bool columnMajor>
290 
291  #ifdef IVSPARSE_DEBUG
292  // ensure the column is in bounds
293  assert(col < outerDim && col >= 0 && "Column is out of bounds!");
294  #endif
295 
296  double norm = 0;
297 
298  for (typename SparseMatrix<T, indexT, 1, columnMajor>::InnerIterator it(*this, col); it; ++it) {
299  norm += it.value() * it.value();
300  }
301  return sqrt(norm);
302 }
303 
304 } // namespace IVSparse
Definition: IVCSC_Iterator.hpp:25
Definition: CSC_SparseMatrix.hpp:24
std::vector< T > maxRowCoeff()
Definition: IVCSC_BLAS.hpp:161
std::vector< T > minRowCoeff()
Definition: IVCSC_BLAS.hpp:199
std::vector< T > innerSum()
Definition: IVCSC_BLAS.hpp:126
T sum()
Definition: IVCSC_BLAS.hpp:239
double norm()
Definition: IVCSC_BLAS.hpp:256
std::vector< T > minColCoeff()
Definition: IVCSC_BLAS.hpp:180
std::vector< T > outerSum()
Definition: IVCSC_BLAS.hpp:111
double vectorLength(uint32_t vec)
Definition: IVCSC_BLAS.hpp:272
std::vector< T > maxColCoeff()
Definition: IVCSC_BLAS.hpp:142
T trace()
Definition: IVCSC_BLAS.hpp:218