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