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