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