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 throw MatrixOutOfBoundsError(rows, cols, this->m_rows, this->m_cols);
112 }
113 return this->m_matrix[rows * this->m_cols + cols];
114}
115
123template <typename T>
124T DenseMatrix<T>::operator()(const int rows, const int cols) const
125{
126 if (rows >= this->m_rows || cols >= this->m_cols)
127 {
128 throw MatrixOutOfBoundsError(rows, cols, this->m_rows, this->m_cols);
129 }
130 return this->m_matrix[rows * this->m_cols + cols];
131}
132
138template <typename T>
139std::valarray<T> DenseMatrix<T>::scalarAdd(const T value) const
140{
141 return this->m_matrix + value;
142}
143
149template <typename T>
151{
152 return this->m_matrix + dense_matrix.m_matrix;
153}
154
160template <typename T>
161std::valarray<T> DenseMatrix<T>::scalarSubtract(const T value) const
162{
163 return this->m_matrix - value;
164}
165
171template <typename T>
173{
174 return this->m_matrix - dense_matrix.m_matrix;
175}
176
182template <typename T>
183std::valarray<T> DenseMatrix<T>::scalarMultiply(const T value) const
184{
185 return this->m_matrix * value;
186}
187
193template <typename T>
195{
196 // Multiply matrices A^(n x m) * B^(m x k) = C^(n x k)
197 // Not very efficient algorithm, please revise if used more intensily in the future!
198 std::valarray<T> result(this->m_rows * dense_matrix.m_cols);
199 for (int i = 0; i < this->m_rows; i++)
200 {
201 for (int j = 0; j < dense_matrix.m_cols; j++)
202 {
203 T sum = {0};
204 for (int k = 0; k < this->m_cols; k++)
205 {
206 sum += this->m_matrix[i * this->m_cols + k]
208 }
209 result[i * this->m_cols + j] = sum;
210 }
211 }
212 return {this->m_rows, dense_matrix.m_cols, result};
213}
214
220template <typename T>
222{
223 return this->m_matrix * dense_matrix.m_matrix;
224}
225
231template <typename T>
232std::valarray<T> DenseMatrix<T>::scalarDivide(const T value) const
233{
234 return this->m_matrix / value;
235}
236
242template <typename T>
244{
245 return this->m_matrix / dense_matrix.m_matrix;
246}
247
252template <typename T>
253std::valarray<T> DenseMatrix<T>::vectorElemAdd(const std::valarray<T>& value) const
254{
255 return this->m_matrix + value;
256}
257
263template <typename T>
264std::valarray<T> DenseMatrix<T>::vectorElemSubtract(const std::valarray<T>& value) const
265{
266 return this->m_matrix - value;
267}
268
274template <typename T>
275std::valarray<T> DenseMatrix<T>::vectorElemMultiply(const std::valarray<T>& value) const
276{
277 return this->m_matrix * value;
278}
279
285template <typename T>
286std::valarray<T> DenseMatrix<T>::vectorElemDivide(const std::valarray<T>& value) const
287{
288 return this->m_matrix / value;
289}
290
298template <typename T>
299std::valarray<T> DenseMatrix<T>::matrixVectorMultiplication(const std::valarray<T>& value) const
300{
301 std::valarray<T> result(value.size());
302 for (int i{0}; i < value.size(); i++)
303 {
304 for (int j = 0; j < this->m_cols; j++)
305 {
306 result[i] += this->m_matrix[i * this->m_cols + j];
307 }
308 result[i] *= value[i];
309 }
310 return result;
311}
312
319template <typename T>
321{
322 std::pair<int, int> size = dm_1.size();
323 return {size.first, size.second, dm_1.matrix_add_element_wise(dm_2)};
324}
325
332template <typename T>
334{
335 std::pair<int, int> size = dense_matrix.size();
336 return {size.first, size.second, dense_matrix.scalarAdd(value)};
337}
338
346template <typename T>
348{
349 std::pair<int, int> size = dense_matrix.size();
350 return {size.first, size.second, dense_matrix.scalarAdd(value)};
351}
352
359template <typename T>
361{
362 std::pair<int, int> size = dm_1.size();
363 return {size.first, size.second, dm_1.matrix_subtract_element_wise(dm_2)};
364}
365
372template <typename T>
374{
375 std::pair<int, int> size = dense_matrix.size();
376 return {size.first, size.second, dense_matrix.scalarSubtract(value)};
377}
378
386template <typename T>
388{
389 std::pair<int, int> size = dense_matrix.size();
390 return {size.first, size.second, -dense_matrix.scalarSubtract(value)};
391}
392
403template <typename T>
405{
406 std::pair<int, int> size = dm_1.size();
407 return {size.first, size.second, dm_1.matrixMultiplyElementWise(dm_2)};
408}
409
416template <typename T>
418{
419 std::pair<int, int> size = dense_matrix.size();
420 return {size.first, size.second, dense_matrix.scalarMultiply(value)};
421}
422
433template <typename T>
435{
436 std::pair<int, int> size = dense_matrix.size();
437 return {size.first, size.second, dense_matrix.scalarMultiply(value)};
438}
439
446template <typename T>
448{
449 std::pair<int, int> size = dm_1.size();
450 return {size.first, size.second, dm_1.matrix_divide_element_wise(dm_2)};
451}
452
459template <typename T>
461{
462 std::pair<int, int> size = dense_matrix.size();
463 return {size.first, size.second, dense_matrix.scalarDivide(value)};
464}
465
472template <typename T>
474{
475 std::pair<int, int> size = dense_matrix.size();
476 return {size.first, size.second, 1 / dense_matrix.scalarDivide(value)};
477}
478
485template <typename T>
486std::ostream& operator<<(std::ostream& out, const DenseMatrix<T>& dense_matrix)
487{
488 std::pair<int, int> size = dense_matrix.size();
489 for (int i = 0; i < size.first; i++)
490 {
491 for (int j = 0; j < size.second; j++)
492 {
493 std::cout << dense_matrix(i, j) << " ";
494 }
495 std::cout << "\n";
496 }
497 return out;
498}
499
508template <typename T>
509void DenseMatrix<T>::buildAtRuntime(const int rows, const int cols)
510{
511 this->m_rows = rows;
512 this->m_cols = cols;
513 this->m_matrix.resize(rows * cols);
514}
515
522template <typename T>
524{
525 for (int i{0}; i < this->m_rows; i++)
526 {
527 for (int j{0}; j < this->m_cols; j++)
528 {
529 if (this->m_matrix[i * this->m_cols + j] != 0)
530 {
531 this->m_non_zero_elements.emplace_back(i, j);
532 }
533 }
534 }
535}
536#endif
MatrixType
Definition CoreEnums.h:33
DenseMatrix< T > operator+(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary + operator.
Definition DenseMatrix.h:320
DenseMatrix< T > operator/(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary / operator.
Definition DenseMatrix.h:447
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:404
DenseMatrix< T > operator-(const DenseMatrix< T > &dm_1, const DenseMatrix< T > &dm_2)
Overload of the binary - operator.
Definition DenseMatrix.h:360
std::ostream & operator<<(std::ostream &out, const DenseMatrix< T > &dense_matrix)
Overload of the << operator.
Definition DenseMatrix.h:486
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:35
std::valarray< T > scalarSubtract(T value) const override
Subtraction of a scalar from the matrix values element-wise.
Definition CsrMatrix.h:492
std::valarray< T > scalarDivide(T value) const override
Division of a scalar from the matrix values element-wise.
Definition CsrMatrix.h:514
std::valarray< T > scalarMultiply(T value) const override
Multiplication of a scalar to the matrix values element-wise.
Definition CsrMatrix.h:503
CsrSparseMatrix()
Constructor for an empty CsrSparseMatrix object. Leaves all storage arrays empty but sets the flag to...
Definition CsrMatrix.h:92
std::valarray< T > scalarAdd(T value) const override
Addition of a scalar to the matrix values element-wise.
Definition CsrMatrix.h:481
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:194
std::valarray< T > matrixAddElementWise(const DenseMatrix &dense_matrix) const
Addition of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:150
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:161
std::valarray< T > vectorElemMultiply(const std::valarray< T > &value) const override
Multiplication of a vector to the matrix values element-wise.
Definition DenseMatrix.h:275
std::valarray< T > vectorElemDivide(const std::valarray< T > &value) const override
Division of a vector from the matrix values element-wise.
Definition DenseMatrix.h:286
std::valarray< T > matrixMultiplyElementWise(const DenseMatrix &dense_matrix) const
Multiplication of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:221
std::valarray< T > matrixDivideElementWise(const DenseMatrix &dense_matrix) const
Division of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:243
std::valarray< T > matrixSubtractElementWise(const DenseMatrix &dense_matrix) const
Subtraction of two DenseMatrix objects element-wise.
Definition DenseMatrix.h:172
std::valarray< T > scalarMultiply(T value) const override
Multiplication of a scalar to the matrix values element-wise.
Definition DenseMatrix.h:183
std::valarray< T > vectorElemAdd(const std::valarray< T > &value) const override
Addition of a vector to the matrix values element-wise.
Definition DenseMatrix.h:253
std::valarray< T > matrixVectorMultiplication(const std::valarray< T > &value) const override
Matrix-vector-multiplication for dense matrices.
Definition DenseMatrix.h:299
~DenseMatrix() override=default
std::valarray< T > scalarAdd(T value) const override
Addition of a scalar to the matrix values element-wise.
Definition DenseMatrix.h:139
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:509
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:232
void updateNonZeroElements() override
Updates the vector containing the non-zero element row-col pairs. Used for optimization.
Definition DenseMatrix.h:523
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:264
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:118
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:150