A Discrete-Event Network Simulator
API
val-array-test-suite.cc
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 #include "ns3/log.h"
21 #include "ns3/test.h"
22 #include "ns3/val-array.h"
23 
28 namespace ns3
29 {
30 namespace tests
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("ValArrayTest");
34 
40 template <class T>
41 class ValArrayTestCase : public TestCase
42 {
43  public:
45  ValArrayTestCase() = default;
51  ValArrayTestCase(const std::string& name);
52 
54  ~ValArrayTestCase() override;
77 
78  private:
79  void DoRun() override;
80 };
81 
82 template <class T>
83 ValArrayTestCase<T>::ValArrayTestCase(const std::string& name)
84  : TestCase(name)
85 {
86 }
87 
88 template <class T>
90 {
91 }
92 
93 template <class T>
94 void
96 {
97  ValArray<T> v1 = ValArray<T>(2, 3);
98  for (size_t i = 0; i < v1.GetNumRows(); ++i)
99  {
100  for (size_t j = 0; j < v1.GetNumCols(); ++j)
101  {
102  v1(i, j) = 1;
103  }
104  }
105 
106  ValArray<T> v2 = ValArray<T>(v1);
107  NS_TEST_ASSERT_MSG_EQ(v1.GetNumRows(), v2.GetNumRows(), "The number of rows are not equal.");
108  NS_TEST_ASSERT_MSG_EQ(v1.GetNumCols(), v2.GetNumCols(), "The number of cols are not equal.");
109 
110  // test copy constructor
111  for (size_t i = 0; i < v1.GetNumRows(); ++i)
112  {
113  for (size_t j = 0; j < v1.GetNumCols(); ++j)
114  {
115  NS_TEST_ASSERT_MSG_EQ(v1(i, j), v2(i, j), "The elements are not equal.");
116  }
117  }
118 
119  // test assign constructor
120  ValArray<T> v3 = v1;
121  NS_TEST_ASSERT_MSG_EQ(v1.GetNumRows(), v3.GetNumRows(), "The number of rows are not equal.");
122  NS_TEST_ASSERT_MSG_EQ(v1.GetNumCols(), v3.GetNumCols(), "The number of cols are not equal.");
123  for (size_t i = 0; i < v1.GetNumRows(); ++i)
124  {
125  for (size_t j = 0; j < v1.GetNumCols(); ++j)
126  {
127  NS_TEST_ASSERT_MSG_EQ(v1(i, j), v2(i, j), "The elements are not equal.");
128  }
129  }
130 
131  // test move assignment operator
132  ValArray<T> v4;
133  NS_LOG_INFO("v1 size before move: " << v1.GetSize());
134  NS_LOG_INFO("v4 size before move: " << v4.GetSize());
135  size_t v1size = v1.GetSize();
136  v4 = std::move(v1);
137  NS_LOG_INFO("v4 size after move: " << v4.GetSize());
138  NS_TEST_ASSERT_MSG_EQ(v1size, v4.GetSize(), "The number of elements are not equal.");
139  for (size_t i = 0; i < v4.GetNumRows(); ++i)
140  {
141  for (size_t j = 0; j < v4.GetNumCols(); ++j)
142  {
143  // Use v3 for comparison since it hasn't moved
144  NS_TEST_ASSERT_MSG_EQ(v3(i, j), v4(i, j), "The elements are not equal.");
145  }
146  }
147 
148  // test move constructor
149  NS_LOG_INFO("v3 size before move: " << v3.GetSize());
150  size_t v3size = v3.GetSize();
151  ValArray<T> v5(std::move(v3));
152  NS_TEST_ASSERT_MSG_EQ(v3size, v5.GetSize(), "The number of elements are not equal.");
153  for (size_t i = 0; i < v5.GetNumRows(); ++i)
154  {
155  for (size_t j = 0; j < v5.GetNumCols(); ++j)
156  {
157  // Use v4 for comparison since it hasn't moved
158  NS_TEST_ASSERT_MSG_EQ(v4(i, j), v5(i, j), "The elements are not equal.");
159  }
160  }
161 
162  // test constructor with initialization valArray
163  std::valarray<int> initArray1{0, 1, 2, 3, 4, 5, 6, 7};
164  std::valarray<T> valArray1(initArray1.size()); // length is 8 elements
165  for (size_t i = 0; i < initArray1.size(); i++)
166  {
167  valArray1[i] = static_cast<T>(initArray1[i]);
168  }
169  ValArray<T> v6 = ValArray<T>(2, 4, valArray1);
170 
171  // test constructor that moves valArray
172  NS_LOG_INFO("valarray1 size before move: " << valArray1.size());
173  ValArray<T> v11 = ValArray<T>(2, 4, std::move(valArray1));
174  NS_LOG_INFO("valarray1 size after move: " << valArray1.size());
175  NS_LOG_INFO("v11 size after move: " << v11.GetSize());
176 
177  // test whether column-major order was respected during the initialization and
178  // also in the access operator if we iterate over rows first we should find 0, 2, 4, 6, ...
179  std::valarray<int> initArray2{0, 2, 4, 6, 1, 3, 5, 7};
180  size_t testIndex = 0;
181  for (size_t i = 0; i < v6.GetNumRows(); ++i)
182  {
183  for (size_t j = 0; j < v6.GetNumCols(); ++j)
184  {
185  NS_TEST_ASSERT_MSG_EQ(v6(i, j),
186  static_cast<T>(initArray2[testIndex]),
187  "The values are not equal.");
188  testIndex++;
189  }
190  }
191 
192  // test constructor with initialization valArray for 3D array
193  std::valarray<int> initArray3{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7};
194  std::valarray<T> valArray2(initArray3.size()); // length is 8 elements
195  for (size_t i = 0; i < initArray3.size(); i++)
196  {
197  valArray2[i] = static_cast<T>(initArray3[i]);
198  }
199 
200  ValArray<T> v7 = ValArray<T>(2, 4, 2, valArray2);
201  // test whether column-major order was respected during the initialization and
202  // also in the access operator
203  // if we iterate over rows first we should find 0, 2, 4, 6, ...
204  std::valarray<int> initArray4{0, 2, 4, 6, 1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
205  testIndex = 0;
206  for (size_t p = 0; p < v7.GetNumPages(); ++p)
207  {
208  for (size_t i = 0; i < v7.GetNumRows(); ++i)
209  {
210  for (size_t j = 0; j < v7.GetNumCols(); ++j)
211  {
212  NS_TEST_ASSERT_MSG_EQ(v7(i, j, p),
213  static_cast<T>(initArray4[testIndex]),
214  "The values are not equal.");
215  testIndex++;
216  }
217  }
218  }
219 
220  // multiplication with a scalar value with 3D array
221  ValArray<T> v8 = v7 * (static_cast<T>(5.0));
222  for (size_t p = 0; p < v8.GetNumPages(); ++p)
223  {
224  for (size_t i = 0; i < v8.GetNumRows(); ++i)
225  {
226  for (size_t j = 0; j < v8.GetNumCols(); ++j)
227  {
228  NS_TEST_ASSERT_MSG_EQ(v7(i, j, p) * (static_cast<T>(5.0)),
229  v8(i, j, p),
230  "The values are not equal");
231  }
232  }
233  }
234 
235  NS_LOG_INFO("v8 = v7 * 5:" << v8);
236  // test +, - (binary, unary) operators
237  NS_LOG_INFO("v8 + v8" << v8 + v8);
238  NS_LOG_INFO("v8 - v8" << v8 - v8);
239  NS_LOG_INFO("-v8" << -v8);
240 
241  // test += and -= assignment operators
242  ValArray<T> v9(v8.GetNumRows(), v8.GetNumCols(), v8.GetNumPages());
243  v9 += v8;
244  NS_LOG_INFO("v9 += v8" << v9);
245  ValArray<T> v10(v8.GetNumRows(), v8.GetNumCols(), v8.GetNumPages());
246  v10 -= v8;
247  NS_LOG_INFO("v10 -= v8" << v10);
248 
249  // test == and != operators
250  NS_TEST_ASSERT_MSG_EQ(bool(v9 == v8), true, "Matrices v8 and v9 should be equal");
251  NS_TEST_ASSERT_MSG_EQ(bool(v10 == v8), false, "Matrices v8 and v10 should not be equal");
252  NS_TEST_ASSERT_MSG_EQ(bool(v10 != v8), true, "Matrices v8 and v10 should not be equal");
253  // test whether arrays are equal when they have different lengths
254  NS_TEST_ASSERT_MSG_NE(ValArray<int>(std::valarray({1, 2, 3})),
255  ValArray<int>(std::valarray({1, 2, 3, 4})),
256  "Arrays should not be equal, they have different dimensions.");
257 
258  // test the function IsAlmostEqual
259  v9(0, 0, 0) = v9(0, 0, 0) + static_cast<T>(1);
260  NS_TEST_ASSERT_MSG_EQ(v9.IsAlmostEqual(v8, 2) && (v9 != v8),
261  true,
262  "Matrices should be almost equal, but not equal.");
263 
264  // test the initialization with std::vector
265  ValArray<T> v12 = ValArray(std::vector<T>({1, 2, 3}));
266  NS_LOG_INFO("v12:" << v12);
267 }
268 
276 {
277  public:
280 };
281 
283  : TestSuite("val-array-test")
284 {
285  AddTestCase(new ValArrayTestCase<double>("Test ValArray<double>"));
286  AddTestCase(new ValArrayTestCase<std::complex<double>>("Test ValArray<std::complex<double>>"));
287  AddTestCase(new ValArrayTestCase<int>("Test ValArray<int>"));
288 }
289 
295 
296 } // namespace tests
297 } // namespace ns3
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
ValArray is a class to efficiently store 3D array.
Definition: val-array.h:80
bool IsAlmostEqual(const ValArray< T > &rhs, T tol) const
Compare Valarray up to a given absolute tolerance.
Definition: val-array.h:684
size_t GetNumPages() const
Definition: val-array.h:393
size_t GetSize() const
Definition: val-array.h:400
size_t GetNumRows() const
Definition: val-array.h:379
size_t GetNumCols() const
Definition: val-array.h:386
ValArray test case for testing ValArray class.
ValArrayTestCase()=default
Default constructor.
ValArrayTestCase< T > & operator=(const ValArrayTestCase< T > &)=default
Copy assignment operator.
ValArrayTestCase(ValArrayTestCase< T > &&)=default
Move constructor.
ValArrayTestCase(const ValArrayTestCase< T > &)=default
Copy constructor.
~ValArrayTestCase() override
Destructor.
ValArrayTestCase< T > & operator=(ValArrayTestCase< T > &&)=default
Move assignment operator.
void DoRun() override
Implementation to actually run this TestCase.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
static ValArrayTestSuite g_valArrayTestSuite
ValArrayTestSuite instance variable.
Every class exported by the ns3 library is enclosed in the ns3 namespace.