IVSparse  v1.0
A sparse matrix compression library.
IVCSC_BLAS.hpp
1 
9 #pragma once
10 
11 namespace IVSparse {
12 
13  //* BLAS Level 1 Routines *//
14 
15  // Scalar Multiply
16  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
17  inline IVSparse::SparseMatrix<T, indexT, compressionLevel, columnMajor> SparseMatrix<T, indexT, compressionLevel, columnMajor>::scalarMultiply(T scalar) {
18  // Deep copy the matrix
20 
21  // else use the iterator
22  #pragma omp parallel for schedule(dynamic)
23  for (uint32_t i = 0; i < this->outerDim; ++i)
24  {
25  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(newMatrix, i); it; ++it)
26  {
27  if (it.isNewRun())
28  {
29  it.coeff(it.value() * scalar);
30  }
31  }
32  }
33  return newMatrix;
34  }
35 
36  // In Place Scalar Multiply
37  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
38  inline void SparseMatrix<T, indexT, compressionLevel, columnMajor>::inPlaceScalarMultiply(T scalar) {
39  // else use the iterator
40  #pragma omp parallel for schedule(dynamic)
41  for (uint32_t i = 0; i < outerDim; ++i)
42  {
43  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it)
44  {
45  if (it.isNewRun())
46  {
47  it.coeff(it.value() * scalar);
48  }
49  }
50  }
51  }
52 
53  //* BLAS Level 2 Routines *//
54 
55  // Matrix Vector Multiplication (Eigen::VectorXd * IVSparse::SparseMatrix)
56  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
57  inline Eigen::VectorXd SparseMatrix<T, indexT, compressionLevel, columnMajor>::vectorMultiply(Eigen::VectorXd &vec) {
58  // check that the vector is the correct size
59  assert(vec.rows() == outerDim && "The vector must be the same size as the number of columns in the matrix!");
60 
61  Eigen::Matrix<T, -1, 1> eigenTemp(innerDim, 1);
62  eigenTemp.setZero();
63 
64  // iterate over the vector and multiply the corresponding row of the matrix by the vecIter value
65  #pragma omp parallel for schedule(dynamic)
66  for (int i = 0; i < vec.rows(); ++i) {
67  if (vec(i) == 0)
68  continue;
69  for (typename SparseMatrix<T, indexT, compressionLevel, 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 (IVSparse::SparseMatrix::Vector * IVSparse::SparseMatrix)
77  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
78  inline Eigen::VectorXd SparseMatrix<T, indexT, compressionLevel, columnMajor>::vectorMultiply(typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::Vector &vec) {
79  if (vec.length() != outerDim)
80  throw std::invalid_argument("The vector must be the same size as the number of columns in the matrix!");
81 
82  Eigen::Matrix<T, -1, 1> newVector = Eigen::Matrix<T, -1, 1>::Zero(innerDim, 1);
83 
84  // #pragma omp parallel for schedule(dynamic)
85  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator vecIter(vec); vecIter; ++vecIter) {
86  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator matIter(*this, vecIter.row()); matIter; ++matIter) {
87  newVector.coeffRef(matIter.row()) += matIter.value() * vecIter.value();
88  }
89  }
90  return newVector;
91  }
92 
93  //* BLAS Level 3 Routines *//
94 
95  // Matrix Vector Multiplication (IVSparse::SparseMatrix * Eigen::Matrix)
96  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
97  inline Eigen::Matrix<T, -1, -1> SparseMatrix<T, indexT, compressionLevel, columnMajor>::matrixMultiply(Eigen::Matrix<T, -1, -1> &mat) {
98  // check that the matrix is the correct size
99  if (mat.rows() != outerDim)
100  throw std::invalid_argument("The left matrix must be the same size as the number of columns in the right matrix!");
101 
102  Eigen::Matrix<T, -1, -1> newMatrix = Eigen::Matrix<T, -1, -1>::Zero(innerDim, mat.cols());
103 
104  #pragma omp parallel for schedule(dynamic)
105  for (int col = 0; col < mat.cols(); col++) {
106  for (int row = 0; row < mat.rows(); row++) {
107  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator matIter(*this, row); matIter; ++matIter) {
108  newMatrix.coeffRef(matIter.row(), col) += matIter.value() * mat(row, col);
109  }
110  }
111  }
112  return newMatrix;
113  }
114 
115  //* Other Matrix Calculations *//
116 
117  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
119  std::vector<T> outerSum = std::vector<T>(outerDim);
120 
121  #pragma omp parallel for schedule(dynamic)
122  for (int i = 0; i < outerDim; i++) {
123  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
124  outerSum[i] += it.value();
125  }
126  }
127  return outerSum;
128  }
129 
130  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
132  std::vector<T> innerSum = std::vector<T>(innerDim);
133 
134  #pragma omp parallel for schedule(dynamic)
135  for (int i = 0; i < outerDim; i++) {
136  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
137  innerSum[it.row()] += it.value();
138  }
139  }
140  return innerSum;
141  }
142 
143  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
145  std::vector<T> maxCoeff = std::vector<T>(innerDim);
146 
147  #pragma omp parallel for schedule(dynamic)
148  for (int i = 0; i < outerDim; i++) {
149  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
150  if (it.value() > maxCoeff[i]) {
151  maxCoeff[i] = it.value();
152  }
153  }
154  }
155  return maxCoeff;
156  }
157 
158  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
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  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
165  if (it.value() > maxCoeff[it.row()]) {
166  maxCoeff[it.row()] = it.value();
167  }
168  }
169  }
170  return maxCoeff;
171  }
172 
173  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
175  std::vector<T> minCoeff = std::vector<T>(innerDim);
176 
177  #pragma omp parallel for schedule(dynamic)
178  for (int i = 0; i < outerDim; i++) {
179  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
180  if (it.value() < minCoeff[i]) {
181  minCoeff[i] = it.value();
182  }
183  }
184  }
185  return minCoeff;
186  }
187 
188  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
190  std::vector<T> minCoeff = std::vector<T>(innerDim);
191  memset(minCoeff.data(), 0xF, innerDim * sizeof(T));
192 
193  #pragma omp parallel for schedule(dynamic)
194  for (int i = 0; i < outerDim; i++) {
195  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
196  if (it.value() < minCoeff[it.row()]) {
197  minCoeff[it.row()] = it.value();
198  }
199  }
200  }
201  return minCoeff;
202  }
203 
204  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
206  assert(innerDim == outerDim && "Trace is only defined for square matrices!");
207 
208  T trace = 0;
209  for (int i = 0; i < outerDim; i++) {
210  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
211  if (it.row() == i) { trace += it.value(); }
212  else if (it.row() > i) { continue; }
213  }
214  }
215  return trace;
216  }
217 
218  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
220  T sum = 0;
221 
222  #pragma omp parallel for schedule(dynamic)
223  for (int i = 0; i < outerDim; i++) {
224  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
225  sum += it.value();
226  }
227  }
228  return sum;
229  }
230 
231  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
233  double norm = 0;
234 
235  #pragma omp parallel for schedule(dynamic)
236  for (int i = 0; i < outerDim; i++) {
237  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, i); it; ++it) {
238  norm += it.value() * it.value();
239  }
240  }
241  return sqrt(norm);
242  }
243 
244  template <typename T, typename indexT, uint8_t compressionLevel, bool columnMajor>
246  double norm = 0;
247 
248  // #pragma omp parallel for schedule(dynamic)
249  for (typename SparseMatrix<T, indexT, compressionLevel, columnMajor>::InnerIterator it(*this, col); it; ++it) {
250  norm += it.value() * it.value();
251  }
252  return sqrt(norm);
253  }
254 
255 } // namespace IVSparse
Definition: IVCSC_Iterator.hpp:25
Definition: IVCSC_SparseMatrix.hpp:27
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