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 Multiply each matrix in the array by the left and the right matrix.
194 * For each page of this MatrixArray the operation performed is
195 * lMatrix * matrix(pageIndex) * rMatrix, and the resulting MatrixArray<T>
196 * contains the array of the results per page. If "this" has dimensions
197 * M x N x P, lMatrix must have dimensions M number of columns, and a single
198 * page, and rMatrix must have N number of rows, and also a single page.
199 *
200 * The result of this function will have the dimensions J x K x P. Where J is
201 * the number of rows of the lMatrix, and K is the number of
202 * columns of rMatrix. Dimensions are:
203 *
204 * lMatrix(JxMx1) * this (MxNxP) * rMatrix(NxKx1) -> result(JxKxP)
205 *
206 * This operation is not possible when using the multiplication operator because
207 * the number of pages does not match.
208 *
209 * \param lMatrix the left matrix in the multiplication
210 * \param rMatrix the right matrix in the multiplication
211 * \returns Returns the result of the multiplication which is a 3D MatrixArray
212 * with dimensions J x K x P as explained previously.
213 */
215 const MatrixArray<T>& rMatrix) const;
216
217 using ValArray<T>::GetPagePtr;
218 using ValArray<T>::EqualDims;
220
221 /**
222 * \brief Function that performs the Hermitian transpose of this MatrixArray
223 * and returns a new matrix that is the result of the operation.
224 * This function assumes that the matrix contains complex numbers, because of that
225 * it is only available for the <std::complex<double>> specialization of MatrixArray.
226 * \return Returns a new matrix that is the result of the Hermitian transpose
227 */
228 template <bool EnableBool = true,
229 typename = std::enable_if_t<(std::is_same_v<T, std::complex<double>> && EnableBool)>>
231
232 protected:
233 // To simplify functions in MatrixArray that are using members from the template base class
234 using ValArray<T>::m_numRows;
235 using ValArray<T>::m_numCols;
236 using ValArray<T>::m_numPages;
237 using ValArray<T>::m_values;
238};
239
240/// Create an alias for MatrixArray using int type
242
243/// Create an alias for MatrixArray using double type
245
246/// Create an alias for MatrixArray using complex type
248
249/*************************************************
250 ** Class MatrixArray inline implementations
251 ************************************************/
252template <class T>
253inline MatrixArray<T>
254MatrixArray<T>::operator*(const T& rhs) const
255{
256 return MatrixArray<T>(m_numRows,
257 m_numCols,
258 m_numPages,
259 m_values * std::valarray<T>(rhs, m_numRows * m_numCols * m_numPages));
260}
261
262template <class T>
263inline MatrixArray<T>
265{
266 AssertEqualDims(rhs);
267 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, m_values + rhs.m_values);
268}
269
270template <class T>
271inline MatrixArray<T>
273{
274 AssertEqualDims(rhs);
275 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, m_values - rhs.m_values);
276}
277
278template <class T>
279inline MatrixArray<T>
281{
282 return MatrixArray<T>(m_numRows, m_numCols, m_numPages, -m_values);
283}
284
285} // namespace ns3
286
287#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:254
MatrixArray operator-() const
unary operator- definition for MatrixArray<T>.
Definition: matrix-array.h:280
MatrixArray Transpose() const
This operator interprets the 3D array as an array of matrices, and performs a linear algebra operatio...
MatrixArray()=default
MatrixArray operator-(const MatrixArray< T > &rhs) const
binary operator- definition for MatrixArray<T>.
Definition: matrix-array.h:272
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 operator+(const MatrixArray< T > &rhs) const
operator+ definition for MatrixArray<T>.
Definition: matrix-array.h:264
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.