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
78template <class T>
79class ValArray : public SimpleRefCount<ValArray<T>>
80{
81 public:
82 // instruct the compiler to generate the default constructor
83 ValArray<T>() = default;
92 ValArray<T>(size_t numRows, size_t numCols = 1, size_t numPages = 1);
98 explicit ValArray<T>(const std::valarray<T>& values);
104 ValArray<T>(std::valarray<T>&& values);
110 explicit ValArray<T>(const std::vector<T>& values);
118 ValArray<T>(size_t numRows, size_t numCols, const std::valarray<T>& values);
126 ValArray<T>(size_t numRows, size_t numCols, std::valarray<T>&& values);
136 ValArray<T>(size_t numRows, size_t numCols, size_t numPages, const std::valarray<T>& values);
146 ValArray<T>(size_t numRows, size_t numCols, size_t numPages, std::valarray<T>&& values);
148 virtual ~ValArray<T>() = default;
150 ValArray<T>(const ValArray<T>&) = default;
158 ValArray<T>(ValArray<T>&&) = default;
168 size_t GetNumRows() const;
172 size_t GetNumCols() const;
176 size_t GetNumPages() const;
180 size_t GetSize() const;
188 T& operator()(size_t rowIndex, size_t colIndex, size_t pageIndex);
196 const T& operator()(size_t rowIndex, size_t colIndex, size_t pageIndex) const;
209 T& operator()(size_t rowIndex, size_t colIndex);
218 const T& operator()(size_t rowIndex, size_t colIndex) const;
230 T& operator()(size_t index);
236 const T& operator()(size_t index) const;
243 ValArray<T> operator*(const T& rhs) const;
249 ValArray<T> operator+(const ValArray<T>& rhs) const;
255 ValArray<T> operator-(const ValArray<T>& rhs) const;
260 ValArray<T> operator-() const;
278 bool operator==(const ValArray<T>& rhs) const;
284 bool operator!=(const ValArray<T>& rhs) const;
295 bool IsAlmostEqual(const ValArray<T>& rhs, T tol) const;
302 T* GetPagePtr(size_t pageIndex);
309 const T* GetPagePtr(size_t pageIndex) const;
315 bool EqualDims(const ValArray<T>& rhs) const;
321 void AssertEqualDims(const ValArray<T>& rhs) const;
332 T& operator[](size_t index);
340 const T& operator[](size_t index) const;
346 const std::valarray<T>& GetValues() const;
354 T& Elem(size_t row, size_t col, size_t page);
362 const T& Elem(size_t row, size_t col, size_t page) const;
363
364 protected:
365 size_t m_numRows =
366 0;
367 size_t m_numCols =
368 0;
369 size_t m_numPages = 0;
370 std::valarray<T> m_values;
371};
372
373/*************************************************
374 ** Class ValArray inline implementations
375 ************************************************/
376
377template <class T>
378inline size_t
380{
381 return m_numRows;
382};
383
384template <class T>
385inline size_t
387{
388 return m_numCols;
389};
390
391template <class T>
392inline size_t
394{
395 return m_numPages;
396};
397
398template <class T>
399inline size_t
401{
402 return m_values.size();
403}
404
405template <class T>
406inline T&
407ValArray<T>::operator()(size_t rowIndex, size_t colIndex, size_t pageIndex)
408{
409 NS_ASSERT_MSG(rowIndex < m_numRows, "Row index out of bounds");
410 NS_ASSERT_MSG(colIndex < m_numCols, "Column index out of bounds");
411 NS_ASSERT_MSG(pageIndex < m_numPages, "Pages index out of bounds");
412 size_t index = (rowIndex + m_numRows * (colIndex + m_numCols * pageIndex));
413 return m_values[index];
414};
415
416template <class T>
417inline const T&
418ValArray<T>::operator()(size_t rowIndex, size_t colIndex, size_t pageIndex) const
419{
420 NS_ASSERT_MSG(rowIndex < m_numRows, "Row index out of bounds");
421 NS_ASSERT_MSG(colIndex < m_numCols, "Column index out of bounds");
422 NS_ASSERT_MSG(pageIndex < m_numPages, "Pages index out of bounds");
423 size_t index = (rowIndex + m_numRows * (colIndex + m_numCols * pageIndex));
424 return m_values[index];
425};
426
427template <class T>
428inline T&
429ValArray<T>::operator()(size_t rowIndex, size_t colIndex)
430{
431 NS_ASSERT_MSG(m_numPages == 1, "Cannot use 2D access operator for 3D ValArray.");
432 return (*this)(rowIndex, colIndex, 0);
433};
434
435template <class T>
436inline const T&
437ValArray<T>::operator()(size_t rowIndex, size_t colIndex) const
438{
439 NS_ASSERT_MSG(m_numPages == 1, "Cannot use 2D access operator for 3D ValArray.");
440 return (*this)(rowIndex, colIndex, 0);
441};
442
443template <class T>
444inline T&
446{
447 NS_ASSERT_MSG(index < m_values.size(),
448 "Invalid index to 1D ValArray. The size of the array should be set through "
449 "constructor.");
450 NS_ASSERT_MSG(((m_numRows == 1 || m_numCols == 1) && (m_numPages == 1)) ||
451 (m_numRows == 1 && m_numCols == 1),
452 "Access operator allowed only for 1D ValArray.");
453 return m_values[index];
454};
455
456template <class T>
457inline const T&
458ValArray<T>::operator()(size_t index) const
459{
460 NS_ASSERT_MSG(index < m_values.size(),
461 "Invalid index to 1D ValArray.The size of the array should be set through "
462 "constructor.");
463 NS_ASSERT_MSG(((m_numRows == 1 || m_numCols == 1) && (m_numPages == 1)) ||
464 (m_numRows == 1 && m_numCols == 1),
465 "Access operator allowed only for 1D ValArray.");
466 return m_values[index];
467};
468
469template <class T>
470inline ValArray<T>
471ValArray<T>::operator*(const T& rhs) const
472{
473 return ValArray<T>(m_numRows,
474 m_numCols,
475 m_numPages,
476 m_values * std::valarray<T>(rhs, m_numRows * m_numCols * m_numPages));
477}
478
479template <class T>
480inline ValArray<T>
482{
483 AssertEqualDims(rhs);
484 return ValArray<T>(m_numRows, m_numCols, m_numPages, m_values + rhs.m_values);
485}
486
487template <class T>
488inline ValArray<T>
490{
491 AssertEqualDims(rhs);
492 return ValArray<T>(m_numRows, m_numCols, m_numPages, m_values - rhs.m_values);
493}
494
495template <class T>
496inline ValArray<T>
498{
499 return ValArray<T>(m_numRows, m_numCols, m_numPages, -m_values);
500}
501
502template <class T>
503inline ValArray<T>&
505{
506 AssertEqualDims(rhs);
507 m_values += rhs.m_values;
508 return *this;
509}
510
511template <class T>
512inline ValArray<T>&
514{
515 AssertEqualDims(rhs);
516 m_values -= rhs.m_values;
517 return *this;
518}
519
520template <class T>
521inline T*
522ValArray<T>::GetPagePtr(size_t pageIndex)
523{
524 NS_ASSERT_MSG(pageIndex < m_numPages, "Invalid page index.");
525 return &(m_values[m_numRows * m_numCols * pageIndex]);
526};
527
528template <class T>
529inline const T*
530ValArray<T>::GetPagePtr(size_t pageIndex) const
531{
532 NS_ASSERT_MSG(pageIndex < m_numPages, "Invalid page index.");
533 return &(m_values[m_numRows * m_numCols * pageIndex]);
534};
535
536template <class T>
537inline bool
539{
540 return (m_numRows == rhs.m_numRows) && (m_numCols == rhs.m_numCols) &&
541 (m_numPages == rhs.m_numPages);
542}
543
544template <class T>
545inline T&
547{
548 return (*this)(index);
549}
550
551template <class T>
552inline const T&
553ValArray<T>::operator[](size_t index) const
554{
555 return (*this)(index);
556}
557
558template <class T>
559inline const std::valarray<T>&
561{
562 return m_values;
563}
564
565template <class T>
566inline T&
567ValArray<T>::Elem(size_t row, size_t col, size_t page)
568{
569 return (*this)(row, col, page);
570};
571
572template <class T>
573inline const T&
574ValArray<T>::Elem(size_t row, size_t col, size_t page) const
575{
576 return (*this)(row, col, page);
577};
578
579/*************************************************
580 ** Class ValArray non-inline implementations
581 ************************************************/
582
583template <class T>
584ValArray<T>::ValArray(size_t numRows, size_t numCols, size_t numPages)
585 : m_numRows{numRows},
586 m_numCols{numCols},
587 m_numPages{numPages}
588{
590};
591
592template <class T>
593ValArray<T>::ValArray(const std::valarray<T>& values)
594 : m_numRows{values.size()},
595 m_numCols{1},
596 m_numPages{1},
597 m_values{values}
598{
599}
600
601template <class T>
602ValArray<T>::ValArray(std::valarray<T>&& values)
603 : m_numRows{values.size()},
604 m_numCols{1},
605 m_numPages{1},
606 m_values{std::move(values)}
607{
608}
609
610template <class T>
611ValArray<T>::ValArray(const std::vector<T>& values)
612 : m_numRows{values.size()},
613 m_numCols{1},
614 m_numPages{1}
615{
616 m_values.resize(values.size());
617 std::copy(values.begin(), values.end(), std::begin(m_values));
618}
619
620template <class T>
621ValArray<T>::ValArray(size_t numRows, size_t numCols, const std::valarray<T>& values)
622 : m_numRows{numRows},
623 m_numCols{numCols},
624 m_numPages{1},
625 m_values{values}
626{
627 NS_ASSERT_MSG(m_numRows * m_numCols == values.size(),
628 "Dimensions and the initialization array size do not match.");
629};
630
631template <class T>
632ValArray<T>::ValArray(size_t numRows, size_t numCols, std::valarray<T>&& values)
633 : m_numRows{numRows},
634 m_numCols{numCols},
635 m_numPages{1}
636{
637 NS_ASSERT_MSG(m_numRows * m_numCols == values.size(),
638 "Dimensions and the initialization array size do not match.");
639 m_values = std::move(values);
640};
641
642template <class T>
644 size_t numCols,
645 size_t numPages,
646 const std::valarray<T>& values)
647 : m_numRows{numRows},
648 m_numCols{numCols},
649 m_numPages{numPages},
650 m_values{values}
651{
652 NS_ASSERT_MSG(m_numRows * m_numCols * m_numPages == values.size(),
653 "Dimensions and the initialization array size do not match.");
654};
655
656template <class T>
657ValArray<T>::ValArray(size_t numRows, size_t numCols, size_t numPages, std::valarray<T>&& values)
658 : m_numRows{numRows},
659 m_numCols{numCols},
660 m_numPages{numPages}
661{
662 NS_ASSERT_MSG(m_numRows * m_numCols * m_numPages == values.size(),
663 "Dimensions and the initialization array size do not match.");
664 m_values = std::move(values);
665};
666
667template <class T>
668bool
670{
671 return EqualDims(rhs) &&
672 std::equal(std::begin(m_values), std::end(m_values), std::begin(rhs.m_values));
673}
674
675template <class T>
676bool
678{
679 return !((*this) == rhs);
680}
681
682template <class T>
683bool
685{
686 return EqualDims(rhs) && std::equal(std::begin(m_values),
687 std::end(m_values),
688 std::begin(rhs.m_values),
689 [tol](T lhsValue, T rhsValue) {
690 return lhsValue == rhsValue ||
691 std::abs(lhsValue - rhsValue) <= std::abs(tol);
692 });
693}
694
695template <class T>
696void
698{
699 NS_ASSERT_MSG(EqualDims(rhs),
700 "Dimensions mismatch: "
701 "lhs (rows, cols, pages) = ("
702 << m_numRows << ", " << m_numCols << ", " << m_numPages
703 << ") and "
704 "rhs (rows, cols, pages) = ("
705 << rhs.m_numRows << ", " << rhs.m_numCols << ", " << rhs.m_numPages << ")");
706}
707
715template <class T>
716std::ostream&
717operator<<(std::ostream& os, const ValArray<T>& a)
718{
719 os << "\n";
720 for (size_t p = 0; p != a.GetNumPages(); ++p)
721 {
722 os << "Page " << p << ":\n";
723 for (size_t i = 0; i != a.GetNumRows(); ++i)
724 {
725 for (size_t j = 0; j != a.GetNumCols(); ++j)
726 {
727 os << "\t" << a(i, j, p);
728 }
729 os << "\n";
730 }
731 }
732 return os;
733}
734
735} // namespace ns3
736
737#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:80
T * GetPagePtr(size_t pageIndex)
Get a data pointer to a specific 2D array for use in linear algebra libraries.
Definition: val-array.h:522
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:697
T & operator()(size_t rowIndex, size_t colIndex, size_t pageIndex)
Access operator, with bound-checking in debug profile.
Definition: val-array.h:407
T & Elem(size_t row, size_t col, size_t page)
Alternative access operator to access a specific element.
Definition: val-array.h:567
ValArray< T > operator+(const ValArray< T > &rhs) const
operator+ definition for ValArray<T>.
Definition: val-array.h:481
const std::valarray< T > & GetValues() const
Returns underlying values.
Definition: val-array.h:560
ValArray< T > & operator+=(const ValArray< T > &rhs)
operator+= definition for ValArray<T>.
Definition: val-array.h:504
bool IsAlmostEqual(const ValArray< T > &rhs, T tol) const
Compare Valarray up to a given absolute tolerance.
Definition: val-array.h:684
bool operator!=(const ValArray< T > &rhs) const
operator!= definition for ValArray<T>.
Definition: val-array.h:677
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:546
bool operator==(const ValArray< T > &rhs) const
operator== definition for ValArray<T>.
Definition: val-array.h:669
size_t GetNumPages() const
Definition: val-array.h:393
size_t GetSize() const
Definition: val-array.h:400
size_t m_numCols
The size of the second dimension, i.e., the number of columns of each 2D array.
Definition: val-array.h:367
std::valarray< T > m_values
The data values.
Definition: val-array.h:370
ValArray< T > & operator-=(const ValArray< T > &rhs)
operator-= definition for ValArray<T>.
Definition: val-array.h:513
ValArray()=default
ValArray< T > & operator=(const ValArray< T > &)=default
Copy assignment operator.
size_t GetNumRows() const
Definition: val-array.h:379
size_t m_numRows
The size of the first dimension, i.e., the number of rows of each 2D array.
Definition: val-array.h:365
bool EqualDims(const ValArray< T > &rhs) const
Checks whether rhs and lhs ValArray objects have the same dimensions.
Definition: val-array.h:538
size_t GetNumCols() const
Definition: val-array.h:386
size_t m_numPages
The size of the third dimension, i.e., the number of 2D arrays.
Definition: val-array.h:369
ValArray< T > operator*(const T &rhs) const
Element-wise multiplication with a scalar value.
Definition: val-array.h:471
ValArray< T > operator-() const
unary operator- definition for ValArray<T>.
Definition: val-array.h:497
#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.