MoCSI API Reference
Loading...
Searching...
No Matches
DenseMatrix.h
Go to the documentation of this file.
1#ifndef DENSE_MATRIX_H
2#define DENSE_MATRIX_H
3
4#include <iostream>
5#include <string>
6#include <valarray>
7#include <vector>
8
9#include "CoreEnums.h"
10#include "GenericMatrix.h"
11
16template <typename T>
17class DenseMatrix : public GenericMatrix<T>
18{
19 public:
21 DenseMatrix(int rows, int cols);
22 DenseMatrix(int rows, int cols, const std::valarray<T>& values);
23
24 T& operator()(int rows, int cols) override;
25 T operator()(int rows, int cols) const override;
26
27 DenseMatrix(const DenseMatrix&) = default;
28 DenseMatrix& operator=(const DenseMatrix&) = default;
29
32
33 std::valarray<T> scalarAdd(T value) const override;
34 std::valarray<T> matrixAddElementWise(const DenseMatrix& dense_matrix) const;
35 std::valarray<T> scalarSubtract(T value) const override;
36 std::valarray<T> matrixSubtractElementWise(const DenseMatrix& dense_matrix) const;
37 std::valarray<T> scalarMultiply(T value) const override;
38 std::valarray<T> matrixMultiplyElementWise(const DenseMatrix& dense_matrix) const;
40 std::valarray<T> scalarDivide(T value) const override;
41 std::valarray<T> matrixDivideElementWise(const DenseMatrix& dense_matrix) const;
42
43 std::valarray<T> vectorElemAdd(const std::valarray<T>& value) const override;
44 std::valarray<T> vectorElemSubtract(const std::valarray<T>& value) const override;
45 std::valarray<T> vectorElemMultiply(const std::valarray<T>& value) const override;
46 std::valarray<T> vectorElemDivide(const std::valarray<T>& value) const override;
47
48 std::valarray<T> matrixVectorMultiplication(const std::valarray<T>& value) const override;
49
50 void buildAtRuntime(int rows, int cols) override;
51 void updateNonZeroElements() override;
52 const std::vector<std::pair<int, int>>& getNonZeroElements() override
53 {
54 return this->m_non_zero_elements;
55 }
56
57 const MatrixType getMatrixType() override { return MatrixType::Dense; }
58
59 ~DenseMatrix() override = default;
60};
61
65template <typename T>
69
76template <typename T>
80
90template <typename T>
91DenseMatrix<T>::DenseMatrix(int rows, int cols, const std::valarray<T>& values)
92 : GenericMatrix<T>{rows, cols, values, false}
93{
94 if (values.size() != rows * cols)
95 {
96 throw std::invalid_argument("Size mismatch between dimensions and provided values.");
97 }
98}
99
106template <typename T>
107T& DenseMatrix<T>::operator()(const int rows, const int cols)
108{
109 if (rows >= this->m_rows || cols >= this->m_cols)
110 {
111 std::cerr << "[DenseMatrix]: Trying to access a matrix out of bounds!\n";
112 throw MatrixOutOfBoundsError(rows, cols, this->m_rows, this->m_cols,
113 static_cast<std::string>("[DenseMatrix]:"));
114 }
115 return this->m_matrix[rows * this->m_cols + cols];
116}
117
125template <typename T>
126T DenseMatrix<T>::operator()(const int rows, const int cols) const
127{
128 if (rows >= this->m_rows || cols >= this->m_cols)
129 {
130 std::cerr << "[DenseMatrix]: Trying to access a matrix out of bounds!\n";
131 throw MatrixOutOfBoundsError(rows, cols, this->m_rows, this->m_cols,
132 static_cast<std::string>("[DenseMatrix]:"));
133 }
134 return this->m_matrix[rows * this->m_cols + cols];
135}
136
142template <typename T>
143std::valarray<T> DenseMatrix<T>::scalarAdd(const T value) const
144{
145 return this->m_matrix + value;
146}
147
153template <typename T>
155{
156 return this->m_matrix + dense_matrix.m_matrix;
157}
158
164template <typename T>
165std::valarray<T> DenseMatrix<T>::scalarSubtract(const T value) const
166{
167 return this->m_matrix - value;
168}
169
175template <typename T>
177{
178 return this->m_matrix - dense_matrix.m_matrix;
179}
180
186template <typename T>
187std::valarray<T> DenseMatrix<T>::scalarMultiply(const T value) const
188{
189 return this->m_matrix * value;
190}
191
197template <typename T>
199{
200 // Multiply matrices A^(n x m) * B^(m x k) = C^(n x k)
201 // Not very efficient algorithm, please revise if used more intensily in the future!
202 std::valarray<T> result(this->m_rows * dense_matrix.m_cols);
203 for (int i = 0; i < this->m_rows; i++)
204 {
205 for (int j = 0; j < dense_matrix.m_cols; j++)
206 {
207 T sum = {0};
208 for (int k = 0; k < this->m_cols; k++)
209 {
210 sum += this->m_matrix[i * this->m_cols + k]
212 }
213 result[i * this->m_cols + j] = sum;
214 }
215 }
216 return {this->m_rows, dense_matrix.m_cols, result};
217}
218
224template <typename T>
226{
227 return this->m_matrix * dense_matrix.m_matrix;
228}
229
235template <typename T>
236std::valarray<T> DenseMatrix<T>::scalarDivide(const T value) const
237{
238 return this->m_matrix / value;
239}
240
246template <typename T>
248{
249 return this->m_matrix / dense_matrix.m_matrix;
250}
251
256template <typename T>
257std::valarray<T> DenseMatrix<T>::vectorElemAdd(const std::valarray<T>& value) const
258{
259 return this->m_matrix + value;
260}
261
267template <typename T>
268std::valarray<T> DenseMatrix<T>::vectorElemSubtract(const std::valarray<T>& value) const
269{
270 return this->m_matrix - value;
271}
272
278template <typename T>
279std::valarray<T> DenseMatrix<T>::vectorElemMultiply(const std::valarray<T>& value) const
280{
281 return this->m_matrix * value;
282}
283
289template <typename T>
290std::valarray<T> DenseMatrix<T>::vectorElemDivide(const std::valarray<T>& value) const
291{
292 return this->m_matrix / value;
293}
294
302template <typename T>
303std::valarray<T> DenseMatrix<T>::matrixVectorMultiplication(const std::valarray<T>& value) const
304{
305 std::valarray<T> result(value.size());
306 for (int i{0}; i < value.size(); i++)
307 {
308 for (int j = 0; j < this->m_cols; j++)
309 {
310 result[i] += this->m_matrix[i * this->m_cols + j];
311 }
312 result[i] *= value[i];
313 }
314 return result;
315}
316
323template <typename T>
325{
326 std::pair<int, int> size = dm_1.size();
327 return {size.first, size.second, dm_1.matrix_add_element_wise(dm_2)};
328}
329
336template <typename T>
338{
339 std::pair<int, int> size = dense_matrix.size();
340 return {size.first, size.second, dense_matrix.scalarAdd(value)};
341}
342
350template <typename T>
352{
353 std::pair<int, int> size = dense_matrix.size();
354 return {size.first, size.second, dense_matrix.scalarAdd(value)};
355}
356
363template <typename T>
365{
366 std::pair<int, int> size = dm_1.size();
367 return {size.first, size.second, dm_1.matrix_subtract_element_wise(dm_2)};
368}
369
376template <typename T>
378{
379 std::pair<int, int> size = dense_matrix.size();
380 return {size.first, size.second, dense_matrix.scalarSubtract(value)};
381}
382
390template <typename T>
392{
393 std::pair<int, int> size = dense_matrix.size();
394 return {size.first, size.second, -dense_matrix.scalarSubtract(value)};
395}
396
407template <typename T>
409{
410 std::pair<int, int> size = dm_1.size();
411 return {size.first, size.second, dm_1.matrixMultiplyElementWise(dm_2)};
412}
413
420template <typename T>
422{
423 std::pair<int, int> size = dense_matrix.size();
424 return {size.first, size.second, dense_matrix.scalarMultiply(value)};
425}
426
437template <typename T>
439{
440 std::pair<int, int> size = dense_matrix.size();
441 return {size.first, size.second, dense_matrix.scalarMultiply(value)};
442}
443
450template <typename T>
452{
453 std::pair<int, int> size = dm_1.size();
454 return {size.first, size.second, dm_1.matrix_divide_element_wise(dm_2)};
455}
456
463template <typename T>
465{
466 std::pair<int, int> size = dense_matrix.size();
467 return {size.first, size.second, dense_matrix.scalarDivide(value)};
468}
469
476template <typename T>
478{
479 std::pair<int, int> size = dense_matrix.size();
480 return {size.first, size.second, 1 / dense_matrix.scalarDivide(value)};
481}
482
489template <typename T>
490std::ostream& operator<<(std::ostream& out, const DenseMatrix<T>& dense_matrix)
491{
492 std::pair<int, int> size = dense_matrix.size();
493 for (int i = 0; i < size.first; i++)
494 {
495 for (int j = 0; j < size.second; j++)
496 {
497 std::cout << dense_matrix(i, j) << " ";
498 }
499 std::cout << "\n";
500 }
501 return out;
502}
503
512template <typename T>
513void DenseMatrix<T>::buildAtRuntime(const int rows, const int cols)
514{
515 this->m_rows = rows;
516 this->m_cols = cols;
517 this->m_matrix.resize(rows * cols);
518}
519
526template <typename T>
528{
529 for (int i{0}; i < this->m_rows; i++)
530 {
531 for (int j{0}; j < this->m_cols; j++)
532 {
533 if (this->m_matrix[i * this->m_cols + j] != 0)
534 {
535 this->m_non_zero_elements.emplace_back(i, j);
536 }
537 }
538 }
539}
540#endif
MatrixType
Definition CoreEnums.h:36
DenseMatrix< T > operator+(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary + operator.
Definition DenseMatrix.h:324
DenseMatrix< T > operator/(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary / operator.
Definition DenseMatrix.h:451
DenseMatrix< T > operator*(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary * operator. Does matrix multiplication/matrix product.
Definition DenseMatrix.h:408
DenseMatrix< T > operator-(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary - operator.
Definition DenseMatrix.h:364
std::ostream & operator<<(std::ostream &out, const DenseMatrix< T > &dense_matrix)
Overload of the << operator.
Definition DenseMatrix.h:490
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:37
std::valarray< T > scalarSubtract(T value) const override
Subtraction of a scalar from the matrix values element-wise.
Definition CsrMatrix.h:499
std::valarray< T > scalarDivide(T value) const override
Division of a scalar from the matrix values element-wise.
Definition CsrMatrix.h:521
std::valarray< T > scalarMultiply(T value) const override
Multiplication of a scalar to the matrix values element-wise.
Definition CsrMatrix.h:510
CsrSparseMatrix()
Constructor for an empty CsrSparseMatrix object. Leaves all storage arrays empty but sets the flag to...
Definition CsrMatrix.h:94
std::valarray< T > scalarAdd(T value) const override
Addition of a scalar to the matrix values element-wise.
Definition CsrMatrix.h:488
Concrete implemenatation of a matrix class representing a dense matrix. Offers basic access and eleme...
Definition DenseMatrix.h:18
DenseMatrix< T > matrixMultiply(const DenseMatrix &dense_matrix) const
Mathematical matrix multiplication of two DenseMatrix objects.
Definition DenseMatrix.h:198
std::valarray< T > matrixAddElementWise(const DenseMatrix &dense_matrix) const
Addition of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:154
DenseMatrix(DenseMatrix &&)=default
DenseMatrix & operator=(DenseMatrix &&)=default
DenseMatrix & operator=(const DenseMatrix &)=default
const std::vector< std::pair< int, int > > & getNonZeroElements() override
Definition DenseMatrix.h:52
DenseMatrix(const DenseMatrix &)=default
std::valarray< T > scalarSubtract(T value) const override
Subtraction of a scalar from the matrix values element-wise.
Definition DenseMatrix.h:165
std::valarray< T > vectorElemMultiply(const std::valarray< T > &value) const override
Multiplication of a vector to the matrix values element-wise.
Definition DenseMatrix.h:279
std::valarray< T > vectorElemDivide(const std::valarray< T > &value) const override
Division of a vector from the matrix values element-wise.
Definition DenseMatrix.h:290
std::valarray< T > matrixMultiplyElementWise(const DenseMatrix &dense_matrix) const
Multiplication of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:225
std::valarray< T > matrixDivideElementWise(const DenseMatrix &dense_matrix) const
Division of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:247
std::valarray< T > matrixSubtractElementWise(const DenseMatrix &dense_matrix) const
Subtraction of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:176
std::valarray< T > scalarMultiply(T value) const override
Multiplication of a scalar to the matrix values element-wise.
Definition DenseMatrix.h:187
std::valarray< T > vectorElemAdd(const std::valarray< T > &value) const override
Addition of a vector to the matrix values element-wise.
Definition DenseMatrix.h:257
std::valarray< T > matrixVectorMultiplication(const std::valarray< T > &value) const override
Matrix-vector-multiplication for dense matrices.
Definition DenseMatrix.h:303
~DenseMatrix() override=default
std::valarray< T > scalarAdd(T value) const override
Addition of a scalar to the matrix values element-wise.
Definition DenseMatrix.h:143
void buildAtRuntime(int rows, int cols) override
Updates row, col values and array size if creation was deferred at invocation of constructor.
Definition DenseMatrix.h:513
T & operator()(int rows, int cols) override
Parentheses operator to allow access to the matrix values as Matrix(row,column).
Definition DenseMatrix.h:107
std::valarray< T > scalarDivide(T value) const override
Division of a scalar from the matrix values element-wise.
Definition DenseMatrix.h:236
void updateNonZeroElements() override
Updates the vector containing the non-zero element row-col pairs. Used for optimization.
Definition DenseMatrix.h:527
const MatrixType getMatrixType() override
Definition DenseMatrix.h:57
DenseMatrix()
Constructor used for buildAtRuntime.
Definition DenseMatrix.h:66
std::valarray< T > vectorElemSubtract(const std::valarray< T > &value) const override
Subtraction of a vector from the matrix values element-wise.
Definition DenseMatrix.h:268
Template generalized Matrix object that should be the base for all further implementations of a matri...
Definition GenericMatrix.h:19
std::valarray< T > m_matrix
Definition GenericMatrix.h:24
std::vector< std::pair< int, int > > m_non_zero_elements
Definition GenericMatrix.h:25
std::pair< int, int > size() const
Function that returns the size of the matrix as a pair in (rows, columns) format.
Definition GenericMatrix.h:120
int m_rows
Definition GenericMatrix.h:21
int m_cols
Definition GenericMatrix.h:22
Error class to throw when the matrix is accessed out of bounds. Inherits from std::exception.
Definition GenericMatrix.h:152