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