A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
val-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#ifndef VAL_ARRAY_H
9#define VAL_ARRAY_H
10
11#include "assert.h"
12#include "simple-ref-count.h"
13
14#include <complex>
15#include <valarray>
16#include <vector>
17
18namespace ns3
19{
20
21/**
22 * \defgroup Matrices Classes to do efficient math operations on arrays
23 * \ingroup core
24 */
25
26/**
27 * \ingroup Matrices
28 *
29 * \brief ValArray is a class to efficiently store 3D array. The class is general
30 * enough to represent 1D array or 2D arrays. ValArray also provides basic
31 * algebra element-wise operations over the whole array (1D, 2D, 3D).
32 *
33 * Main characteristics of ValArray are the following:
34 *
35 * - ValArray uses std::valarray to efficiently store data.
36 *
37 * - In general, the elements are stored in memory as a sequence of consecutive
38 * 2D arrays. The dimensions of 2D arrays are defined by numRows and numCols,
39 * while the number of 2D arrays is defined by numPages. Notice that if we set
40 * the number of pages to 1, we will have only a single 2D array. If we
41 * additionally set numRows or numCols to 1, we will have 1D array.
42 *
43 * - All 2D arrays have the same dimensions, i.e. numRows and numCols.
44 *
45 * - 2D arrays are stored in column-major order, which is the default
46 * order in Eigen and Armadillo libraries, which allows a straightforward mapping
47 * of any page (2D array) within ValArray to Eigen or Armadillo matrices.
48 *
49 * Examples of column-major order:
50 *
51 * a) in the case of a 2D array, we will have in memory the following order of
52 * elements, assuming that the indexes are rowIndex, colIndex, pageIndex:
53 *
54 * a000 a100 a010 a110 a020 a120.
55 *
56 * b) in the case of a 3D array, e.g, if there are two 2D arrays of 2x3 dimensions
57 * we will have in memory the following order of elements,
58 * assuming that the indexes are rowIndex, colIndex, pageIndex:
59 *
60 * a000 a100 a010 a110 a020 a120 a001 a101 a011 a111 a021 a121.
61 *
62 * - The access to the elements is implemented in operators:
63 * - operator (rowIndex) and operator[] (rowIndex) for 1D array (assuming colIndex=0, pageIndex=0),
64 * - operator (rowIndex,colIndex) for 2D array (assuming pageIndex=0) and
65 * - operator(rowIndex, colIndex, pageIndex) for 3D array.
66 *
67 * Definition of ValArray as a template class allows using different numerical
68 * types as the elements of the vectors/matrices, e.g., complex numbers, double,
69 * int, etc.
70 */
71
72template <class T>
73class ValArray : public SimpleRefCount<ValArray<T>>
74{
75 public:
76 // instruct the compiler to generate the default constructor
77 ValArray() = default;
78 /**
79 * \brief Constructor that creates "numPages" number of 2D arrays that are of
80 * dimensions "numRows"x"numCols", and are initialized with all-zero elements.
81 * If only 1 parameter, numRows, is provided then a single 1D array is being created.
82 * \param numRows the number of rows
83 * \param numCols the number of columns
84 * \param numPages the number of pages
85 */
86 ValArray(size_t numRows, size_t numCols = 1, size_t numPages = 1);
87 /**
88 * \brief Constructor creates a single 1D array of values.size () elements and 1 column,
89 * and uses std::valarray<T> values to initialize the elements.
90 * \param values std::valarray<T> that will be used to initialize elements of 1D array
91 */
92 explicit ValArray(const std::valarray<T>& values);
93 /**
94 * \brief Constructor creates a single 1D array of values.size () elements and 1 column,
95 * and moves std::valarray<T> values to initialize the elements.
96 * \param values std::valarray<T> that will be moved to initialize elements of 1D array
97 */
98 ValArray(std::valarray<T>&& values);
99 /**
100 * \brief Constructor creates a single 1D array of values.size () elements and 1 column,
101 * and uses values std::vector<T> to initialize the elements.
102 * \param values std::vector<T> that will be used to initialize elements of 1D array
103 */
104 explicit ValArray(const std::vector<T>& values);
105 /**
106 * \brief Constructor creates a single 2D array of numRows and numCols, and uses
107 * std::valarray<T> values to initialize the elements.
108 * \param numRows the number of rows
109 * \param numCols the number of columns
110 * \param values valarray<T> that will be used to initialize elements of 3D array
111 */
112 ValArray(size_t numRows, size_t numCols, const std::valarray<T>& values);
113 /**
114 * \brief Constructor creates a single 2D array of numRows and numCols, and moves
115 * std::valarray<T> values to initialize the elements.
116 * \param numRows the number of rows
117 * \param numCols the number of columns
118 * \param values valarray<T> that will be used to initialize elements of 3D array
119 */
120 ValArray(size_t numRows, size_t numCols, std::valarray<T>&& values);
121 /**
122 * \brief Constructor creates the 3D array of numRows x numCols x numPages dimensions,
123 * and uses std::valarray<T> values to initialize all the 2D arrays, where first
124 * numRows*numCols elements will belong to the first 2D array.
125 * \param numRows the number of rows
126 * \param numCols the number of columns
127 * \param numPages the number of pages
128 * \param values valarray<T> that will be used to initialize elements of 3D array
129 */
130 ValArray(size_t numRows, size_t numCols, size_t numPages, const std::valarray<T>& values);
131 /**
132 * \brief Constructor creates the 3D array of numRows x numCols x numPages dimensions,
133 * and moves std::valarray<T> values to initialize all the 2D arrays, where first
134 * numRows*numCols elements will belong to the first 2D array.
135 * \param numRows the number of rows
136 * \param numCols the number of columns
137 * \param numPages the number of pages
138 * \param values valarray<T> that will be used to initialize elements of 3D array
139 */
140 ValArray(size_t numRows, size_t numCols, size_t numPages, std::valarray<T>&& values);
141 /** instruct the compiler to generate the implicitly declared destructor*/
142 virtual ~ValArray() = default;
143 /** instruct the compiler to generate the implicitly declared copy constructor*/
144 ValArray(const ValArray<T>&) = default;
145 /**
146 * \brief Copy assignment operator.
147 * Instruct the compiler to generate the implicitly declared copy assignment operator.
148 * \return a reference to the assigned object
149 */
150 ValArray& operator=(const ValArray<T>&) = default;
151 /** instruct the compiler to generate the implicitly declared move constructor*/
152 ValArray(ValArray<T>&&) = default;
153 /**
154 * \brief Move assignment operator.
155 * Instruct the compiler to generate the implicitly declared move assignment operator.
156 * \return a reference to the assigned object
157 */
159 /**
160 * \returns Number of rows
161 */
162 size_t GetNumRows() const;
163 /**
164 * \returns Number of columns
165 */
166 size_t GetNumCols() const;
167 /**
168 * \returns Number of pages, i.e., the number of 2D arrays
169 */
170 size_t GetNumPages() const;
171 /**
172 * \returns Total number of elements
173 */
174 size_t GetSize() const;
175 /**
176 * \brief Access operator, with bound-checking in debug profile
177 * \param rowIndex The index of the row
178 * \param colIndex The index of the column
179 * \param pageIndex The index of the page
180 * \returns A const reference to the element with with rowIndex, colIndex and pageIndex indices.
181 */
182 T& operator()(size_t rowIndex, size_t colIndex, size_t pageIndex);
183 /**
184 * \brief Const access operator, with bound-checking in debug profile
185 * \param rowIndex The index of the row
186 * \param colIndex The index of the column
187 * \param pageIndex The index of the page
188 * \returns A const reference to the element with with rowIndex, colIndex and pageIndex indices.
189 */
190 const T& operator()(size_t rowIndex, size_t colIndex, size_t pageIndex) const;
191 /**
192 * \brief Access operator for 2D ValArrays.
193 * Assuming that the third dimension is equal to 1, e.g. ValArray contains
194 * a single 2D array.
195 * Note: intentionally not implemented through three parameters access operator,
196 * to avoid accidental mistakes by user, e.g., providing 2 parameters when
197 * 3 are necessary, but access operator would return valid value if default
198 * value of pages provided is 0.
199 * \param rowIndex The index of the row
200 * \param colIndex The index of the column
201 * \returns A reference to the element with the specified indices
202 */
203 T& operator()(size_t rowIndex, size_t colIndex);
204 /**
205 * \brief Const access operator for 2D ValArrays.
206 * Assuming that the third dimension is equal to 1, e.g. ValArray contains
207 * a single 2D array.
208 * \param rowIndex row index
209 * \param colIndex column index
210 * \returns a Const reference to the value with the specified row and column index.
211 */
212 const T& operator()(size_t rowIndex, size_t colIndex) const;
213 /**
214 * \brief Single-element access operator() for 1D ValArrays.
215 * Assuming that the number of columns and pages is equal to 1, e.g. ValArray
216 * contains a single column or a single row.
217 *
218 * Note: intentionally not implemented through three parameters access operator,
219 * to avoid accidental mistakes by user, e.g., providing 1 parameters when
220 * 2 or 3 are necessary.
221 * \param index The index of the 1D ValArray.
222 * \returns A reference to the value with the specified index.
223 */
224 T& operator()(size_t index);
225 /**
226 * \brief Single-element access operator() for 1D ValArrays.
227 * \param index The index of the 1D ValArray.
228 * \returns The const reference to the values with the specified index.
229 */
230 const T& operator()(size_t index) const;
231 /**
232 * \brief Element-wise multiplication with a scalar value.
233 * \param rhs A scalar value of type T
234 * \returns ValArray in which each element has been multiplied by the given
235 * scalar value.
236 */
237 ValArray operator*(const T& rhs) const;
238 /**
239 * \brief operator+ definition for ValArray<T>.
240 * \param rhs The rhs ValArray to be added to this ValArray.
241 * \return the ValArray instance that holds the results of the operator+
242 */
243 ValArray operator+(const ValArray<T>& rhs) const;
244 /**
245 * \brief binary operator- definition for ValArray<T>.
246 * \param rhs The rhs ValArray to be subtracted from this ValArray.
247 * \return the ValArray instance that holds the results of the operator-
248 */
249 ValArray operator-(const ValArray<T>& rhs) const;
250 /**
251 * \brief unary operator- definition for ValArray<T>.
252 * \return the ValArray instance that holds the results of the operator-
253 */
255 /**
256 * \brief operator+= definition for ValArray<T>.
257 * \param rhs The rhs ValArray to be added to this ValArray.
258 * \return a reference to this ValArray instance
259 */
261 /**
262 * \brief operator-= definition for ValArray<T>.
263 * \param rhs The rhs ValArray to be subtracted from this ValArray.
264 ** \return a reference to this ValArray instance
265 */
267 /**
268 * \brief operator== definition for ValArray<T>.
269 * \param rhs The ValArray instance to be compared with lhs ValArray instance
270 * \return true if rhs ValArray is equal to this ValArray, otherwise it returns false
271 */
272 bool operator==(const ValArray<T>& rhs) const;
273 /**
274 * \brief operator!= definition for ValArray<T>.
275 * \param rhs The ValArray instance to be compared with lhs ValArray instance
276 * \return true if rhs ValArray is not equal to this ValArray, otherwise it returns true
277 */
278 bool operator!=(const ValArray<T>& rhs) const;
279 /**
280 * \brief Compare Valarray up to a given absolute tolerance. This operation
281 * is element-wise operation, i.e., the elements with the same indices from
282 * the lhs and rhs ValArray are being compared, allowing the tolerance defined
283 * byt "tol" parameter.
284 * \param rhs The rhs ValArray
285 * \param tol The absolute tolerance
286 * \returns true if the differences in each element-wise comparison is less
287 * or equal to tol.
288 */
289 bool IsAlmostEqual(const ValArray<T>& rhs, T tol) const;
290 /**
291 * \brief Get a data pointer to a specific 2D array for use in linear
292 * algebra libraries
293 * \param pageIndex The index of the desired 2D array
294 * \returns a pointer to the data elements of the 2D array
295 */
296 T* GetPagePtr(size_t pageIndex);
297 /**
298 * \brief Get a data pointer to a specific 2D array for use in linear
299 * algebra libraries
300 * \param pageIndex An index of the desired 2D array
301 * \returns a pointer to the data elements of the 2D array
302 */
303 const T* GetPagePtr(size_t pageIndex) const;
304 /**
305 * \brief Checks whether rhs and lhs ValArray objects have the same dimensions.
306 * \param rhs The rhs ValArray
307 * \returns true if the dimensions of lhs and rhs are equal, otherwise it returns false
308 */
309 bool EqualDims(const ValArray<T>& rhs) const;
310 /**
311 * \brief Function that asserts if the dimensions of lhs and rhs ValArray are
312 * not equal and prints a message with the matrices dimensions.
313 * \param rhs the rhs ValArray
314 */
315 void AssertEqualDims(const ValArray<T>& rhs) const;
316 /**
317 * \brief Single-element access operator[] that can be used to access a specific
318 * element of 1D ValArray. It mimics operator[] from std::vector.
319 * This function is introduced for compatibility with ns-3 usage of 1D arrays,
320 * which are usually represented through std::vector operators in spectrum
321 * and antenna module.
322 *
323 * \param index The index of the element to be returned
324 * \returns A reference to a specific element from the underlying std::valarray.
325 */
326 T& operator[](size_t index);
327 /**
328 * \brief Const access operator that can be used to access a specific element of
329 * 1D ValArray.
330 *
331 * \param index The index of the element to be returned
332 * \returns A const reference to a specific element from the underlying std::valarray.
333 */
334 const T& operator[](size_t index) const;
335 /**
336 * \brief Returns underlying values. This function allows to directly work
337 * with the underlying values, which can be faster then using access operators.
338 * \returns A const reference to the underlying std::valarray<T>.
339 */
340 const std::valarray<T>& GetValues() const;
341 /**
342 * \brief Alternative access operator to access a specific element.
343 * \param row the row index of the element to be obtained
344 * \param col the col index of the element to be obtained
345 * \param page the page index of the element to be obtained
346 * \return a reference to the element of this ValArray
347 */
348 T& Elem(size_t row, size_t col, size_t page);
349 /**
350 * \brief Alternative const access operator to access a specific element.
351 * \param row the row index of the element to be obtained
352 * \param col the column index of the element to be obtained
353 * \param page the page index of the element to be obtained
354 * \return a const reference to the element of this ValArray
355 */
356 const T& Elem(size_t row, size_t col, size_t page) const;
357
358 protected:
359 size_t m_numRows =
360 0; //!< The size of the first dimension, i.e., the number of rows of each 2D array
361 size_t m_numCols =
362 0; //!< The size of the second dimension, i.e., the number of columns of each 2D array
363 size_t m_numPages = 0; //!< The size of the third dimension, i.e., the number of 2D arrays
364 std::valarray<T> m_values; //!< The data values
365};
366
367/*************************************************
368 ** Class ValArray inline implementations
369 ************************************************/
370
371template <class T>
372inline size_t
374{
375 return m_numRows;
376}
377
378template <class T>
379inline size_t
381{
382 return m_numCols;
383}
384
385template <class T>
386inline size_t
388{
389 return m_numPages;
390}
391
392template <class T>
393inline size_t
395{
396 return m_values.size();
397}
398
399template <class T>
400inline T&
401ValArray<T>::operator()(size_t rowIndex, size_t colIndex, size_t pageIndex)
402{
403 NS_ASSERT_MSG(rowIndex < m_numRows, "Row index out of bounds");
404 NS_ASSERT_MSG(colIndex < m_numCols, "Column index out of bounds");
405 NS_ASSERT_MSG(pageIndex < m_numPages, "Pages index out of bounds");
406 size_t index = (rowIndex + m_numRows * (colIndex + m_numCols * pageIndex));
407 return m_values[index];
408}
409
410template <class T>
411inline const T&
412ValArray<T>::operator()(size_t rowIndex, size_t colIndex, size_t pageIndex) const
413{
414 NS_ASSERT_MSG(rowIndex < m_numRows, "Row index out of bounds");
415 NS_ASSERT_MSG(colIndex < m_numCols, "Column index out of bounds");
416 NS_ASSERT_MSG(pageIndex < m_numPages, "Pages index out of bounds");
417 size_t index = (rowIndex + m_numRows * (colIndex + m_numCols * pageIndex));
418 return m_values[index];
419}
420
421template <class T>
422inline T&
423ValArray<T>::operator()(size_t rowIndex, size_t colIndex)
424{
425 NS_ASSERT_MSG(m_numPages == 1, "Cannot use 2D access operator for 3D ValArray.");
426 return (*this)(rowIndex, colIndex, 0);
427}
428
429template <class T>
430inline const T&
431ValArray<T>::operator()(size_t rowIndex, size_t colIndex) const
432{
433 NS_ASSERT_MSG(m_numPages == 1, "Cannot use 2D access operator for 3D ValArray.");
434 return (*this)(rowIndex, colIndex, 0);
435}
436
437template <class T>
438inline T&
440{
441 NS_ASSERT_MSG(index < m_values.size(),
442 "Invalid index to 1D ValArray. The size of the array should be set through "
443 "constructor.");
444 NS_ASSERT_MSG(((m_numRows == 1 || m_numCols == 1) && (m_numPages == 1)) ||
445 (m_numRows == 1 && m_numCols == 1),
446 "Access operator allowed only for 1D ValArray.");
447 return m_values[index];
448}
449
450template <class T>
451inline const T&
452ValArray<T>::operator()(size_t index) const
453{
454 NS_ASSERT_MSG(index < m_values.size(),
455 "Invalid index to 1D ValArray.The size of the array should be set through "
456 "constructor.");
457 NS_ASSERT_MSG(((m_numRows == 1 || m_numCols == 1) && (m_numPages == 1)) ||
458 (m_numRows == 1 && m_numCols == 1),
459 "Access operator allowed only for 1D ValArray.");
460 return m_values[index];
461}
462
463template <class T>
464inline ValArray<T>
465ValArray<T>::operator*(const T& rhs) const
466{
467 return ValArray<T>(m_numRows,
468 m_numCols,
469 m_numPages,
470 m_values * std::valarray<T>(rhs, m_numRows * m_numCols * m_numPages));
471}
472
473template <class T>
474inline ValArray<T>
476{
477 AssertEqualDims(rhs);
478 return ValArray<T>(m_numRows, m_numCols, m_numPages, m_values + rhs.m_values);
479}
480
481template <class T>
482inline ValArray<T>
484{
485 AssertEqualDims(rhs);
486 return ValArray<T>(m_numRows, m_numCols, m_numPages, m_values - rhs.m_values);
487}
488
489template <class T>
490inline ValArray<T>
492{
493 return ValArray<T>(m_numRows, m_numCols, m_numPages, -m_values);
494}
495
496template <class T>
497inline ValArray<T>&
499{
500 AssertEqualDims(rhs);
501 m_values += rhs.m_values;
502 return *this;
503}
504
505template <class T>
506inline ValArray<T>&
508{
509 AssertEqualDims(rhs);
510 m_values -= rhs.m_values;
511 return *this;
512}
513
514template <class T>
515inline T*
516ValArray<T>::GetPagePtr(size_t pageIndex)
517{
518 NS_ASSERT_MSG(pageIndex < m_numPages, "Invalid page index.");
519 return &(m_values[m_numRows * m_numCols * pageIndex]);
520}
521
522template <class T>
523inline const T*
524ValArray<T>::GetPagePtr(size_t pageIndex) const
525{
526 NS_ASSERT_MSG(pageIndex < m_numPages, "Invalid page index.");
527 return &(m_values[m_numRows * m_numCols * pageIndex]);
528}
529
530template <class T>
531inline bool
533{
534 return (m_numRows == rhs.m_numRows) && (m_numCols == rhs.m_numCols) &&
535 (m_numPages == rhs.m_numPages);
536}
537
538template <class T>
539inline T&
541{
542 return (*this)(index);
543}
544
545template <class T>
546inline const T&
547ValArray<T>::operator[](size_t index) const
548{
549 return (*this)(index);
550}
551
552template <class T>
553inline const std::valarray<T>&
555{
556 return m_values;
557}
558
559template <class T>
560inline T&
561ValArray<T>::Elem(size_t row, size_t col, size_t page)
562{
563 return (*this)(row, col, page);
564}
565
566template <class T>
567inline const T&
568ValArray<T>::Elem(size_t row, size_t col, size_t page) const
569{
570 return (*this)(row, col, page);
571}
572
573/*************************************************
574 ** Class ValArray non-inline implementations
575 ************************************************/
576
577template <class T>
578ValArray<T>::ValArray(size_t numRows, size_t numCols, size_t numPages)
579 : m_numRows{numRows},
580 m_numCols{numCols},
581 m_numPages{numPages}
582{
584}
585
586template <class T>
587ValArray<T>::ValArray(const std::valarray<T>& values)
588 : m_numRows{values.size()},
589 m_numCols{1},
590 m_numPages{1},
591 m_values{values}
592{
593}
594
595template <class T>
596ValArray<T>::ValArray(std::valarray<T>&& values)
597 : m_numRows{values.size()},
598 m_numCols{1},
599 m_numPages{1},
600 m_values{std::move(values)}
601{
602}
603
604template <class T>
605ValArray<T>::ValArray(const std::vector<T>& values)
606 : m_numRows{values.size()},
607 m_numCols{1},
608 m_numPages{1}
609{
610 m_values.resize(values.size());
611 std::copy(values.begin(), values.end(), std::begin(m_values));
612}
613
614template <class T>
615ValArray<T>::ValArray(size_t numRows, size_t numCols, const std::valarray<T>& values)
616 : m_numRows{numRows},
617 m_numCols{numCols},
618 m_numPages{1},
619 m_values{values}
620{
621 NS_ASSERT_MSG(m_numRows * m_numCols == values.size(),
622 "Dimensions and the initialization array size do not match.");
623}
624
625template <class T>
626ValArray<T>::ValArray(size_t numRows, size_t numCols, std::valarray<T>&& values)
627 : m_numRows{numRows},
628 m_numCols{numCols},
629 m_numPages{1}
630{
631 NS_ASSERT_MSG(m_numRows * m_numCols == values.size(),
632 "Dimensions and the initialization array size do not match.");
633 m_values = std::move(values);
634}
635
636template <class T>
638 size_t numCols,
639 size_t numPages,
640 const std::valarray<T>& values)
641 : m_numRows{numRows},
642 m_numCols{numCols},
643 m_numPages{numPages},
644 m_values{values}
645{
646 NS_ASSERT_MSG(m_numRows * m_numCols * m_numPages == values.size(),
647 "Dimensions and the initialization array size do not match.");
648}
649
650template <class T>
651ValArray<T>::ValArray(size_t numRows, size_t numCols, size_t numPages, std::valarray<T>&& values)
652 : m_numRows{numRows},
653 m_numCols{numCols},
654 m_numPages{numPages}
655{
656 NS_ASSERT_MSG(m_numRows * m_numCols * m_numPages == values.size(),
657 "Dimensions and the initialization array size do not match.");
658 m_values = std::move(values);
659}
660
661template <class T>
662bool
664{
665 return EqualDims(rhs) &&
666 std::equal(std::begin(m_values), std::end(m_values), std::begin(rhs.m_values));
667}
668
669template <class T>
670bool
672{
673 return !((*this) == rhs);
674}
675
676template <class T>
677bool
679{
680 return EqualDims(rhs) && std::equal(std::begin(m_values),
681 std::end(m_values),
682 std::begin(rhs.m_values),
683 [tol](T lhsValue, T rhsValue) {
684 return lhsValue == rhsValue ||
685 std::abs(lhsValue - rhsValue) <= std::abs(tol);
686 });
687}
688
689template <class T>
690void
692{
693 NS_ASSERT_MSG(EqualDims(rhs),
694 "Dimensions mismatch: "
695 "lhs (rows, cols, pages) = ("
696 << m_numRows << ", " << m_numCols << ", " << m_numPages
697 << ") and "
698 "rhs (rows, cols, pages) = ("
699 << rhs.m_numRows << ", " << rhs.m_numCols << ", " << rhs.m_numPages << ")");
700}
701
702/**
703 * \brief Overloads output stream operator.
704 * \tparam T the type of the ValArray for which will be called this function
705 * \param os a reference to the output stream
706 * \param a the ValArray instance using type T
707 * \return a reference to the output stream
708 */
709template <class T>
710std::ostream&
711operator<<(std::ostream& os, const ValArray<T>& a)
712{
713 os << "\n";
714 for (size_t p = 0; p != a.GetNumPages(); ++p)
715 {
716 os << "Page " << p << ":\n";
717 for (size_t i = 0; i != a.GetNumRows(); ++i)
718 {
719 for (size_t j = 0; j != a.GetNumCols(); ++j)
720 {
721 os << "\t" << a(i, j, p);
722 }
723 os << "\n";
724 }
725 }
726 return os;
727}
728
729} // namespace ns3
730
731#endif // VAL_ARRAY_H
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
A template-based reference counting class.
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
T & operator()(size_t rowIndex, size_t colIndex)
Access operator for 2D ValArrays.
Definition val-array.h:423
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
ValArray(size_t numRows, size_t numCols, size_t numPages, std::valarray< T > &&values)
Constructor creates the 3D array of numRows x numCols x numPages dimensions, and moves std::valarray<...
Definition val-array.h:651
T & operator()(size_t rowIndex, size_t colIndex, size_t pageIndex)
Access operator, with bound-checking in debug profile.
Definition val-array.h:401
const T & operator()(size_t index) const
Single-element access operator() for 1D ValArrays.
Definition val-array.h:452
T & Elem(size_t row, size_t col, size_t page)
Alternative access operator to access a specific element.
Definition val-array.h:561
ValArray operator+(const ValArray< T > &rhs) const
operator+ definition for ValArray<T>.
Definition val-array.h:475
ValArray(std::valarray< T > &&values)
Constructor creates a single 1D array of values.size () elements and 1 column, and moves std::valarra...
Definition val-array.h:596
ValArray(const std::valarray< T > &values)
Constructor creates a single 1D array of values.size () elements and 1 column, and uses std::valarray...
Definition val-array.h:587
ValArray(const ValArray< T > &)=default
instruct the compiler to generate the implicitly declared copy constructor
ValArray(ValArray< T > &&)=default
instruct the compiler to generate the implicitly declared move constructor
const std::valarray< T > & GetValues() const
Returns underlying values.
Definition val-array.h:554
ValArray< T > & operator+=(const ValArray< T > &rhs)
operator+= definition for ValArray<T>.
Definition val-array.h:498
bool IsAlmostEqual(const ValArray< T > &rhs, T tol) const
Compare Valarray up to a given absolute tolerance.
Definition val-array.h:678
ValArray(size_t numRows, size_t numCols, std::valarray< T > &&values)
Constructor creates a single 2D array of numRows and numCols, and moves std::valarray<T> values to in...
Definition val-array.h:626
const T & Elem(size_t row, size_t col, size_t page) const
Alternative const access operator to access a specific element.
Definition val-array.h:568
bool operator!=(const ValArray< T > &rhs) const
operator!= definition for ValArray<T>.
Definition val-array.h:671
ValArray< T > & operator=(ValArray< T > &&)=default
Move assignment operator.
T & operator[](size_t index)
Single-element access operator[] that can be used to access a specific element of 1D ValArray.
Definition val-array.h:540
bool operator==(const ValArray< T > &rhs) const
operator== definition for ValArray<T>.
Definition val-array.h:663
size_t GetNumPages() const
Definition val-array.h:387
ValArray & operator=(const ValArray< T > &)=default
Copy assignment operator.
const T & operator()(size_t rowIndex, size_t colIndex, size_t pageIndex) const
Const access operator, with bound-checking in debug profile.
Definition val-array.h:412
size_t GetSize() const
Definition val-array.h:394
ValArray(const std::vector< T > &values)
Constructor creates a single 1D array of values.size () elements and 1 column, and uses values std::v...
Definition val-array.h:605
T & operator()(size_t index)
Single-element access operator() for 1D ValArrays.
Definition val-array.h:439
const T & operator[](size_t index) const
Const access operator that can be used to access a specific element of 1D ValArray.
Definition val-array.h:547
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
ValArray< T > & operator-=(const ValArray< T > &rhs)
operator-= definition for ValArray<T>.
Definition val-array.h:507
ValArray()=default
size_t GetNumRows() const
Definition val-array.h:373
ValArray(size_t numRows, size_t numCols=1, size_t numPages=1)
Constructor that creates "numPages" number of 2D arrays that are of dimensions "numRows"x"numCols",...
Definition val-array.h:578
ValArray(size_t numRows, size_t numCols, const std::valarray< T > &values)
Constructor creates a single 2D array of numRows and numCols, and uses std::valarray<T> values to ini...
Definition val-array.h:615
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
ValArray(size_t numRows, size_t numCols, size_t numPages, const std::valarray< T > &values)
Constructor creates the 3D array of numRows x numCols x numPages dimensions, and uses std::valarray<T...
Definition val-array.h:637
const T & operator()(size_t rowIndex, size_t colIndex) const
Const access operator for 2D ValArrays.
Definition val-array.h:431
const T * GetPagePtr(size_t pageIndex) const
Get a data pointer to a specific 2D array for use in linear algebra libraries.
Definition val-array.h:524
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 GetNumCols() const
Definition val-array.h:380
size_t m_numPages
The size of the third dimension, i.e., the number of 2D arrays.
Definition val-array.h:363
ValArray operator*(const T &rhs) const
Element-wise multiplication with a scalar value.
Definition val-array.h:465
ValArray operator-() const
unary operator- definition for ValArray<T>.
Definition val-array.h:491
virtual ~ValArray()=default
instruct the compiler to generate the implicitly declared destructor
ValArray operator-(const ValArray< T > &rhs) const
binary operator- definition for ValArray<T>.
Definition val-array.h:483
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
STL namespace.
ns3::SimpleRefCount declaration and template implementation.