A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
matrix-array.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Biljana Bojovic <bbojovic@cttc.es>
7 */
8
9#ifndef MATRIX_ARRAY_H
10#define MATRIX_ARRAY_H
11
12#include "val-array.h"
13
14#include <valarray>
15
16namespace ns3
17{
18
19/**
20 * \ingroup Matrices
21 *
22 * \brief MatrixArray class inherits ValArray class and provides additional
23 * interfaces to ValArray which enable page-wise linear algebra operations for
24 * arrays of matrices. While ValArray class is focused on efficient storage,
25 * access and basic algebra element-wise operations on 3D numerical arrays,
26 * MatrixArray is focused on the efficient algebra operations on arrays of
27 * matrices.
28 *
29 * Each page (2-dimensional array) within a 3D array is considered to
30 * be a matrix, and operations are performed separately for each page/matrix.
31 * For example, a multiplication of two MatrixArrays means that a matrix
32 * multiplication is performed between each page in the first MatrixArray with
33 * the corresponding page in the second MatrixArray. Some of the operations can
34 * use the Eigen3 matrix library for speedup. In addition, this class can be
35 * extended to provide interfaces to the Eigen3 matrix library and enable
36 * additional linear algebra operations. The objective of this class is to two-fold:
37 *
38 * - First, it provides simple interfaces to perform matrix operations in parallel
39 * on all pages without the need to write an outer loop over all the pages.
40 *
41 * - Second, it can improve the performance of such parallel matrix operations,
42 * as this class uses a single memory allocation and one common set of size
43 * variables (rows, cols) for all pages, which can be an advantage compared to
44 * having separate memory allocations and size variables for each page/matrix,
45 * especially when those matrices are very small.
46 *
47 * Important characteristics:
48 *
49 * - Matrices are in column-major order.
50 *
51 * - Matrices can be 1-dimensional, in the sense that either the number of rows
52 * or columns is equal to 1.
53 *
54 * - The array of matrices can contain just one matrix or more matrices.
55 *
56 * - For binary operators, both MatrixArrays must have an equal number of pages,
57 * as well compatible row and column dimensions between the matrices.
58 *
59 * - Binary operators are performed among matrices with the same index from lhs
60 * and rhs matrix.
61 *
62 * - MatrixArray improves computationally complex matrix operations by using
63 * Eigen library when it is available at compile time. MatrixArray class makes
64 * use of Eigen Map class, which allows re-using already existing portion of
65 * memory as an Eigen type, e.g. ValArray can return a pointer to a memory
66 * where are placed elements of a specific matrix, and this can be passed to
67 * Eigen Map class which does not do a copy of the elements, but is using these
68 * elements directly in linear algebra operations.
69 */
70template <class T>
71class MatrixArray : public ValArray<T>
72{
73 public:
74 // instruct the compiler to generate the default constructor
75 MatrixArray() = default;
76 /**
77 * \brief Constructor "pages" number of matrices that are of size "numRows"x"numCols",
78 * and are initialized with all-zero elements.
79 * If only 1 parameter, numRows, is provided then a single 1D array is being created.
80 * \param numRows the number of rows
81 * \param numCols the number of columns
82 * \param numPages the number of pages
83 */
84 MatrixArray(size_t numRows, size_t numCols = 1, size_t numPages = 1);
85 /**
86 * \brief Constructor creates a single array of values.size () elements and 1 column,
87 * and uses std::valarray<T> values to initialize the elements.
88 * \param values std::valarray<T> that will be used to initialize elements of 1D array
89 */
90 explicit MatrixArray(const std::valarray<T>& values);
91 /**
92 * \brief Constructor creates a single array of values.size () elements and 1 column,
93 * and moves std::valarray<T> values to initialize the elements.
94 * \param values std::valarray<T> that will be moved to initialize elements of 1D array
95 */
96 MatrixArray(std::valarray<T>&& values);
97 /**
98 * \brief Constructor creates a single array of values.size () elements and 1 column,
99 * and uses std::vector<T> values to initialize the elements.
100 * \param values std::vector<T> that will be used to initialize elements of 1D array
101 */
102 explicit MatrixArray(const std::vector<T>& values);
103 /**
104 * \brief Constructor creates a single matrix of numRows and numCols, and uses
105 * std::valarray<T> values to initialize the elements.
106 * \param numRows the number of rows
107 * \param numCols the number of columns
108 * \param values std::valarray<T> that will be used to initialize elements of 3D array
109 */
110 MatrixArray(size_t numRows, size_t numCols, const std::valarray<T>& values);
111 /**
112 * \brief Constructor creates a single matrix of numRows and numCols, and moves
113 * std::valarray<T> values to initialize the elements.
114 * \param numRows the number of rows
115 * \param numCols the number of columns
116 * \param values std::valarray<T> that will be moved to initialize elements of 3D array
117 */
118 MatrixArray(size_t numRows, size_t numCols, std::valarray<T>&& values);
119 /**
120 * \brief Constructor creates the array of numPages matrices of numRows x numCols dimensions,
121 * and uses std::valarray<T> values to initialize all the elements.
122 * \param numRows the number of rows
123 * \param numCols the number of columns
124 * \param numPages the number of pages
125 * \param values std::valarray<T> that will be used to initialize elements of 3D array
126 */
127 MatrixArray(size_t numRows, size_t numCols, size_t numPages, const std::valarray<T>& values);
128 /**
129 * \brief Constructor creates the array of numPages matrices of numRows x numCols dimensions,
130 * and moves std::valarray<T> values to initialize all the elements.
131 * \param numRows the number of rows
132 * \param numCols the number of columns
133 * \param numPages the number of pages
134 * \param values std::valarray<T> that will be used to initialize elements of 3D array
135 */
136 MatrixArray(size_t numRows, size_t numCols, size_t numPages, std::valarray<T>&& values);
137
138 /**
139 * \brief Element-wise multiplication with a scalar value.
140 * \param rhs is a scalar value of type T
141 * \returns The matrix in which each element has been multiplied by the given
142 * scalar value.
143 */
144 MatrixArray operator*(const T& rhs) const;
145 /**
146 * \brief operator+ definition for MatrixArray<T>.
147 * \param rhs The rhs MatrixArray object
148 * \returns The result of operator+ of this MatrixArray and rhs MatrixArray
149 */
151 /**
152 * \brief binary operator- definition for MatrixArray<T>.
153 * \param rhs The rhs MatrixArray object
154 * \returns The result of operator- of this MatrixArray and rhs MatrixArray
155 */
157 /**
158 * \brief unary operator- definition for MatrixArray<T>.
159 * \return the result of the operator-
160 */
162 /**
163 * \brief Page-wise matrix multiplication.
164 * This operator interprets the 3D array as an array of matrices,
165 * and performs a linear algebra operation on each of the matrices (pages),
166 * i.e., matrices from this MatrixArray and rhs with the same page indices are
167 * multiplied.
168 * The number of columns of this MatrixArray must be equal to the number of
169 * rows in rhs, and rhs must have the same number of pages as this MatrixArray.
170 * \param rhs is another MatrixArray instance
171 * \returns The array of results of matrix multiplications.
172 */
173 MatrixArray operator*(const MatrixArray<T>& rhs) const;
174 /**
175 * \brief This operator interprets the 3D array as an array of matrices,
176 * and performs a linear algebra operation on each of the matrices (pages),
177 * i.e., transposes the matrix or array of matrices definition for MatrixArray<T>.
178 * \return The resulting MatrixArray composed of the array of transposed matrices.
179 */
180 MatrixArray Transpose() const;
181 /**
182 * \brief This operator calculates a vector o determinants, one for each page
183 * \return The resulting MatrixArray with the determinants for each page.
184 */
185 MatrixArray Determinant() const;
186 /**
187 * \brief This operator calculates a vector of Frobenius norm, one for each page
188 * \return The resulting MatrixArray with the Frobenius norm for each page.
189 */
191 /**
192 * \brief Multiply each matrix in the array by the left and the right matrix.
193 * For each page of this MatrixArray the operation performed is
194 * lMatrix * matrix(pageIndex) * rMatrix, and the resulting MatrixArray<T>
195 * contains the array of the results per page. If "this" has dimensions
196 * M x N x P, lMatrix must have dimensions M number of columns, and a single
197 * page, and rMatrix must have N number of rows, and also a single page.
198 *
199 * The result of this function will have the dimensions J x K x P. Where J is
200 * the number of rows of the lMatrix, and K is the number of
201 * columns of rMatrix. Dimensions are:
202 *
203 * lMatrix(JxMx1) * this (MxNxP) * rMatrix(NxKx1) -> result(JxKxP)
204 *
205 * This operation is not possible when using the multiplication operator because
206 * the number of pages does not match.
207 *
208 * \param lMatrix the left matrix in the multiplication
209 * \param rMatrix the right matrix in the multiplication
210 * \returns Returns the result of the multiplication which is a 3D MatrixArray
211 * with dimensions J x K x P as explained previously.
212 */
214 const MatrixArray<T>& rMatrix) const;
215
216 using ValArray<T>::GetPagePtr;
217 using ValArray<T>::EqualDims;
219
220 /**
221 * \brief Function that performs the Hermitian transpose of this MatrixArray
222 * and returns a new matrix that is the result of the operation.
223 * This function assumes that the matrix contains complex numbers, because of that
224 * it is only available for the <std::complex<double>> specialization of MatrixArray.
225 * \return Returns a new matrix that is the result of the Hermitian transpose
226 */
227 template <bool EnableBool = true,
228 typename = std::enable_if_t<(std::is_same_v<T, std::complex<double>> && EnableBool)>>
230
231 /**
232 * \brief Function that copies the current 1-page matrix into a new matrix with n copies of the
233 * original matrix
234 * \param nCopies Number of copies to make of the input 1-page MatrixArray
235 * \return Returns a new matrix with n page copies
236 */
237 MatrixArray<T> MakeNCopies(size_t nCopies) const;
238 /**
239 * \brief Function extracts a page from a MatrixArray
240 * \param page Index of the page to be extracted from the n-page MatrixArray
241 * \return Returns an extracted page of the original MatrixArray
242 */
243 MatrixArray<T> ExtractPage(size_t page) const;
244 /**
245 * \brief Function joins multiple pages into a single MatrixArray
246 * \param pages Vector containing n 1-page MatrixArrays to be merged into a n-page MatrixArray
247 * \return Returns a joint MatrixArray
248 */
249 static MatrixArray<T> JoinPages(const std::vector<MatrixArray<T>>& pages);
250 /**
251 * \brief Function produces an identity MatrixArray with the specified size
252 * \param size Size of the output identity matrix
253 * \param pages Number of copies of the identity matrix
254 * \return Returns an identity MatrixArray
255 */
256 static MatrixArray<T> IdentityMatrix(const size_t size, const size_t pages = 1);
257 /**
258 * \brief Function produces an identity MatrixArray with the same size
259 * as the input MatrixArray
260 * \param likeme Input matrix used to determine the size of the identity matrix
261 * \return Returns an identity MatrixArray
262 */
263 static MatrixArray<T> IdentityMatrix(const MatrixArray& likeme);
264
265 protected:
266 // To simplify functions in MatrixArray that are using members from the template base class
267 using ValArray<T>::m_numRows;
268 using ValArray<T>::m_numCols;
269 using ValArray<T>::m_numPages;
270 using ValArray<T>::m_values;
271};
272
273/// Create an alias for MatrixArray using int type
275
276/// Create an alias for MatrixArray using double type
278
279/// Create an alias for MatrixArray using complex type
281
282/*************************************************
283 ** Class MatrixArray inline implementations
284 ************************************************/
285template <class T>
286inline MatrixArray<T>
287MatrixArray<T>::operator*(const T& rhs) const
288{
289 return MatrixArray<T>(m_numRows,
290 m_numCols,
291 m_numPages,
292 m_values * std::valarray<T>(rhs, m_numRows * m_numCols * m_numPages));
293}
294
295template <class T>
296inline MatrixArray<T>
298{
299 AssertEqualDims(rhs);
300 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, m_values + rhs.m_values);
301}
302
303template <class T>
304inline MatrixArray<T>
306{
307 AssertEqualDims(rhs);
308 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, m_values - rhs.m_values);
309}
310
311template <class T>
312inline MatrixArray<T>
314{
315 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, -m_values);
316}
317
318} // namespace ns3
319
320#endif // MATRIX_ARRAY_H
MatrixArray class inherits ValArray class and provides additional interfaces to ValArray which enable...
MatrixArray< T > HermitianTranspose() const
Function that performs the Hermitian transpose of this MatrixArray and returns a new matrix that is t...
MatrixArray operator*(const T &rhs) const
Element-wise multiplication with a scalar value.
MatrixArray operator-() const
unary operator- definition for MatrixArray<T>.
MatrixArray Determinant() const
This operator calculates a vector o determinants, one for each page.
static MatrixArray< T > IdentityMatrix(const size_t size, const size_t pages=1)
Function produces an identity MatrixArray with the specified size.
static MatrixArray< T > JoinPages(const std::vector< MatrixArray< T > > &pages)
Function joins multiple pages into a single MatrixArray.
MatrixArray Transpose() const
This operator interprets the 3D array as an array of matrices, and performs a linear algebra operatio...
MatrixArray< T > MakeNCopies(size_t nCopies) const
Function that copies the current 1-page matrix into a new matrix with n copies of the original matrix...
MatrixArray()=default
MatrixArray operator-(const MatrixArray< T > &rhs) const
binary operator- definition for MatrixArray<T>.
MatrixArray< T > ExtractPage(size_t page) const
Function extracts a page from a MatrixArray.
MatrixArray MultiplyByLeftAndRightMatrix(const MatrixArray< T > &lMatrix, const MatrixArray< T > &rMatrix) const
Multiply each matrix in the array by the left and the right matrix.
MatrixArray FrobeniusNorm() const
This operator calculates a vector of Frobenius norm, one for each page.
MatrixArray operator+(const MatrixArray< T > &rhs) const
operator+ definition for MatrixArray<T>.
ValArray is a class to efficiently store 3D array.
Definition val-array.h:74
T * GetPagePtr(size_t pageIndex)
Get a data pointer to a specific 2D array for use in linear algebra libraries.
Definition val-array.h:516
void AssertEqualDims(const ValArray< T > &rhs) const
Function that asserts if the dimensions of lhs and rhs ValArray are not equal and prints a message wi...
Definition val-array.h:691
size_t m_numCols
The size of the second dimension, i.e., the number of columns of each 2D array.
Definition val-array.h:361
std::valarray< T > m_values
The data values.
Definition val-array.h:364
size_t m_numRows
The size of the first dimension, i.e., the number of rows of each 2D array.
Definition val-array.h:359
bool EqualDims(const ValArray< T > &rhs) const
Checks whether rhs and lhs ValArray objects have the same dimensions.
Definition val-array.h:532
size_t m_numPages
The size of the third dimension, i.e., the number of 2D arrays.
Definition val-array.h:363
Every class exported by the ns3 library is enclosed in the ns3 namespace.