13#if defined(__GNUC__) && !defined(__clang__)
14#pragma GCC diagnostic push
15#pragma GCC diagnostic ignored "-Wclass-memaccess"
20#if defined(__GNUC__) && !defined(__clang__)
21#pragma GCC diagnostic pop
30using EigenMatrix = Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>;
32using ConstEigenMatrix = Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>;
75 const std::valarray<T>&
values)
98 for (
size_t page = 0; page < res.m_numPages; ++page)
102 ConstEigenMatrix<T> lhsEigenMatrix(GetPagePtr(page), m_numRows, m_numCols);
104 EigenMatrix<T> resEigenMatrix(res.GetPagePtr(page), res.m_numRows, res.m_numCols);
105 resEigenMatrix = lhsEigenMatrix * rhsEigenMatrix;
109 size_t matrixOffset = page * m_numRows * m_numCols;
111 for (
size_t i = 0; i < res.m_numRows; ++i)
113 for (
size_t j = 0; j < res.m_numCols; ++j)
115 res(i, j, page) = (m_values[std::slice(matrixOffset + i, m_numCols, m_numRows)] *
136 for (
size_t page = 0; page < m_numPages; ++page)
140 ConstEigenMatrix<T> thisMatrix(GetPagePtr(page), m_numRows, m_numCols);
141 EigenMatrix<T> resEigenMatrix(res.GetPagePtr(page), res.m_numRows, res.m_numCols);
142 resEigenMatrix = thisMatrix.transpose();
146 size_t matrixIndex = page * m_numRows * m_numCols;
147 for (
size_t i = 0; i < m_numRows; ++i)
149 res.m_values[std::slice(matrixIndex + i * res.m_numRows, res.m_numRows, 1)] =
150 m_values[std::slice(matrixIndex + i, m_numCols, m_numRows)];
163 NS_ASSERT_MSG(m_numRows == m_numCols,
"Matrix is not square");
170 for (
size_t page = 0; page < m_numPages; ++page)
173 auto pageValues = GetPagePtr(page);
178 res(0, 0, page) = pageValues[0] * pageValues[3] - pageValues[1] * pageValues[2];
181 for (
size_t detN = 0; detN < m_numRows; detN++)
183 auto partDetP = T{0} + 1.0;
184 auto partDetN = T{0} + 1.0;
185 for (
size_t row = 0; row < m_numRows; row++)
189 size_t col = (row + detN) % m_numCols;
190 partDetP *= pageValues[row * m_numCols + col];
193 col = m_numCols - 1 - (row + detN) % m_numCols;
194 partDetN *= pageValues[row * m_numCols + col];
196 res(0, 0, page) += partDetP - partDetN;
207 for (
size_t page = 0; page < m_numPages; ++page)
211 auto pagePtr = this->GetPagePtr(page);
212 for (
size_t i = 0; i < m_numRows * m_numCols; i++)
214 auto absVal = std::abs(pagePtr[i]);
215 res[page] += absVal * absVal;
217 res[page] = sqrt(res[page]);
228 "The left and right MatrixArray should have only one page.");
230 "Left vector numCols and this MatrixArray numRows mismatch.");
232 "Right vector numRows and this MatrixArray numCols mismatch.");
242 for (
size_t page = 0; page < m_numPages; ++page)
246 ConstEigenMatrix<T> matrixEigen(GetPagePtr(page), m_numRows, m_numCols);
247 EigenMatrix<T> resEigenMap(res.GetPagePtr(page), res.m_numRows, res.m_numCols);
249 resEigenMap = lMatrixEigen * matrixEigen * rMatrixEigen;
253 size_t matrixOffset = page * m_numRows * m_numCols;
254 for (
size_t resRow = 0; resRow < res.m_numRows; ++resRow)
256 for (
size_t resCol = 0; resCol < res.m_numCols; ++resCol)
260 std::valarray<T> interRes(m_numCols);
261 for (
size_t thisCol = 0; thisCol < m_numCols; ++thisCol)
266 m_values[std::slice(matrixOffset + thisCol * m_numRows, m_numRows, 1)])
270 res(resRow, resCol, page) =
282template <
bool EnableBool,
typename>
288 for (
size_t index = 0; index < this->
GetSize(); ++index)
299 NS_ASSERT_MSG(m_numPages == 1,
"The MatrixArray should have only one page to be copied.");
300 auto copiedMatrix =
MatrixArray<T>{m_numRows, m_numCols, nCopies};
301 for (
size_t copy = 0; copy < nCopies; copy++)
303 for (
size_t i = 0; i < m_numRows * m_numCols; i++)
305 copiedMatrix.
GetPagePtr(copy)[i] = m_values[i];
315 NS_ASSERT_MSG(page < m_numPages,
"The page to extract from the MatrixArray is out of bounds.");
318 for (
size_t i = 0; i < m_numRows * m_numCols; ++i)
320 extractedPage.
m_values[i] = GetPagePtr(page)[i];
322 return extractedPage;
331 for (
size_t page = 0; page < jointMatrix.GetNumPages(); page++)
333 NS_ASSERT_MSG(pages[page].GetNumRows() == jointMatrix.GetNumRows(),
334 "All page matrices should have the same number of rows");
335 NS_ASSERT_MSG(pages[page].GetNumCols() == jointMatrix.GetNumCols(),
336 "All page matrices should have the same number of columns");
338 "All page matrices should have a single page");
341 for (
auto a : pages[page].GetValues())
343 jointMatrix.GetPagePtr(page)[i] = a;
355 for (std::size_t page = 0; page < pages; page++)
357 for (std::size_t i = 0; i < size; i++)
359 identityMatrix(i, i, page) = 1.0;
362 return identityMatrix;
MatrixArray class inherits ValArray class and provides additional interfaces to ValArray which enable...
ValArray is a class to efficiently store 3D array.
T * GetPagePtr(size_t pageIndex)
Get a data pointer to a specific 2D array for use in linear algebra libraries.
size_t GetNumPages() const
size_t m_numCols
The size of the second dimension, i.e., the number of columns of each 2D array.
std::valarray< T > m_values
The data values.
size_t GetNumRows() const
size_t m_numRows
The size of the first dimension, i.e., the number of rows of each 2D array.
size_t GetNumCols() const
size_t m_numPages
The size of the third dimension, i.e., the number of 2D arrays.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added.