A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
24/**
25 * \defgroup valArray-tests ValArray tests
26 * \ingroup core-tests
27 * \ingroup Matrices
28 */
29
30/**
31 * \file
32 * \ingroup valArray-tests
33 * ValArray test suite
34 */
35
36/**
37 * \file
38 * \ingroup core-tests
39 */
40
41namespace ns3
42{
43namespace tests
44{
45
46NS_LOG_COMPONENT_DEFINE("ValArrayTest");
47
48/**
49 * @ingroup valArray-tests
50 *
51 * @brief ValArray test case for testing ValArray class
52 *
53 * @tparam T the template parameter that can be a complex number, double or int
54 */
55template <class T>
57{
58 public:
59 /** Default constructor*/
60 ValArrayTestCase() = default;
61 /**
62 * Constructor
63 *
64 * \param [in] name reference name
65 */
66 ValArrayTestCase(const std::string& name);
67
68 /** Destructor. */
69 ~ValArrayTestCase() override;
70 /**
71 * \brief Copy constructor.
72 * Instruct the compiler to generate the implicitly declared copy constructor
73 */
75 /**
76 * \brief Copy assignment operator.
77 * Instruct the compiler to generate the implicitly declared copy assignment operator.
78 * \return A reference to this ValArrayTestCase
79 */
81 /**
82 * \brief Move constructor.
83 * Instruct the compiler to generate the implicitly declared move constructor
84 */
86 /**
87 * \brief Move assignment operator.
88 * Instruct the compiler to generate the implicitly declared copy constructor
89 * \return A reference to this ValArrayTestCase
90 */
92
93 private:
94 void DoRun() override;
95};
96
97template <class T>
99 : TestCase(name)
100{
101}
102
103template <class T>
105{
106}
107
108template <class T>
109void
111{
112 ValArray<T> v1 = ValArray<T>(2, 3);
113 for (size_t i = 0; i < v1.GetNumRows(); ++i)
114 {
115 for (size_t j = 0; j < v1.GetNumCols(); ++j)
116 {
117 v1(i, j) = 1;
118 }
119 }
120
121 ValArray<T> v2 = ValArray<T>(v1);
122 NS_TEST_ASSERT_MSG_EQ(v1.GetNumRows(), v2.GetNumRows(), "The number of rows are not equal.");
123 NS_TEST_ASSERT_MSG_EQ(v1.GetNumCols(), v2.GetNumCols(), "The number of cols are not equal.");
124
125 // test copy constructor
126 for (size_t i = 0; i < v1.GetNumRows(); ++i)
127 {
128 for (size_t j = 0; j < v1.GetNumCols(); ++j)
129 {
130 NS_TEST_ASSERT_MSG_EQ(v1(i, j), v2(i, j), "The elements are not equal.");
131 }
132 }
133
134 // test assign constructor
135 ValArray<T> v3 = v1;
136 NS_TEST_ASSERT_MSG_EQ(v1.GetNumRows(), v3.GetNumRows(), "The number of rows are not equal.");
137 NS_TEST_ASSERT_MSG_EQ(v1.GetNumCols(), v3.GetNumCols(), "The number of cols are not equal.");
138 for (size_t i = 0; i < v1.GetNumRows(); ++i)
139 {
140 for (size_t j = 0; j < v1.GetNumCols(); ++j)
141 {
142 NS_TEST_ASSERT_MSG_EQ(v1(i, j), v2(i, j), "The elements are not equal.");
143 }
144 }
145
146 // test move assignment operator
147 ValArray<T> v4;
148 NS_LOG_INFO("v1 size before move: " << v1.GetSize());
149 NS_LOG_INFO("v4 size before move: " << v4.GetSize());
150 size_t v1size = v1.GetSize();
151 v4 = std::move(v1);
152 NS_LOG_INFO("v4 size after move: " << v4.GetSize());
153 NS_TEST_ASSERT_MSG_EQ(v1size, v4.GetSize(), "The number of elements are not equal.");
154 for (size_t i = 0; i < v4.GetNumRows(); ++i)
155 {
156 for (size_t j = 0; j < v4.GetNumCols(); ++j)
157 {
158 // Use v3 for comparison since it hasn't moved
159 NS_TEST_ASSERT_MSG_EQ(v3(i, j), v4(i, j), "The elements are not equal.");
160 }
161 }
162
163 // test move constructor
164 NS_LOG_INFO("v3 size before move: " << v3.GetSize());
165 size_t v3size = v3.GetSize();
166 ValArray<T> v5(std::move(v3));
167 NS_TEST_ASSERT_MSG_EQ(v3size, v5.GetSize(), "The number of elements are not equal.");
168 for (size_t i = 0; i < v5.GetNumRows(); ++i)
169 {
170 for (size_t j = 0; j < v5.GetNumCols(); ++j)
171 {
172 // Use v4 for comparison since it hasn't moved
173 NS_TEST_ASSERT_MSG_EQ(v4(i, j), v5(i, j), "The elements are not equal.");
174 }
175 }
176
177 // test constructor with initialization valArray
178 std::valarray<int> initArray1{0, 1, 2, 3, 4, 5, 6, 7};
179 std::valarray<T> valArray1(initArray1.size()); // length is 8 elements
180 for (size_t i = 0; i < initArray1.size(); i++)
181 {
182 valArray1[i] = static_cast<T>(initArray1[i]);
183 }
184 ValArray<T> v6 = ValArray<T>(2, 4, valArray1);
185
186 // test constructor that moves valArray
187 NS_LOG_INFO("valarray1 size before move: " << valArray1.size());
188 ValArray<T> v11 = ValArray<T>(2, 4, std::move(valArray1));
189 NS_LOG_INFO("valarray1 size after move: " << valArray1.size());
190 NS_LOG_INFO("v11 size after move: " << v11.GetSize());
191
192 // test whether column-major order was respected during the initialization and
193 // also in the access operator if we iterate over rows first we should find 0, 2, 4, 6, ...
194 std::valarray<int> initArray2{0, 2, 4, 6, 1, 3, 5, 7};
195 size_t testIndex = 0;
196 for (size_t i = 0; i < v6.GetNumRows(); ++i)
197 {
198 for (size_t j = 0; j < v6.GetNumCols(); ++j)
199 {
200 NS_TEST_ASSERT_MSG_EQ(v6(i, j),
201 static_cast<T>(initArray2[testIndex]),
202 "The values are not equal.");
203 testIndex++;
204 }
205 }
206
207 // test constructor with initialization valArray for 3D array
208 std::valarray<int> initArray3{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7};
209 std::valarray<T> valArray2(initArray3.size()); // length is 8 elements
210 for (size_t i = 0; i < initArray3.size(); i++)
211 {
212 valArray2[i] = static_cast<T>(initArray3[i]);
213 }
214
215 ValArray<T> v7 = ValArray<T>(2, 4, 2, valArray2);
216 // test whether column-major order was respected during the initialization and
217 // also in the access operator
218 // if we iterate over rows first we should find 0, 2, 4, 6, ...
219 std::valarray<int> initArray4{0, 2, 4, 6, 1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
220 testIndex = 0;
221 for (size_t p = 0; p < v7.GetNumPages(); ++p)
222 {
223 for (size_t i = 0; i < v7.GetNumRows(); ++i)
224 {
225 for (size_t j = 0; j < v7.GetNumCols(); ++j)
226 {
227 NS_TEST_ASSERT_MSG_EQ(v7(i, j, p),
228 static_cast<T>(initArray4[testIndex]),
229 "The values are not equal.");
230 testIndex++;
231 }
232 }
233 }
234
235 // multiplication with a scalar value with 3D array
236 ValArray<T> v8 = v7 * (static_cast<T>(5.0));
237 for (size_t p = 0; p < v8.GetNumPages(); ++p)
238 {
239 for (size_t i = 0; i < v8.GetNumRows(); ++i)
240 {
241 for (size_t j = 0; j < v8.GetNumCols(); ++j)
242 {
243 NS_TEST_ASSERT_MSG_EQ(v7(i, j, p) * (static_cast<T>(5.0)),
244 v8(i, j, p),
245 "The values are not equal");
246 }
247 }
248 }
249
250 NS_LOG_INFO("v8 = v7 * 5:" << v8);
251 // test +, - (binary, unary) operators
252 NS_LOG_INFO("v8 + v8" << v8 + v8);
253 NS_LOG_INFO("v8 - v8" << v8 - v8);
254 NS_LOG_INFO("-v8" << -v8);
255
256 // test += and -= assignment operators
257 ValArray<T> v9(v8.GetNumRows(), v8.GetNumCols(), v8.GetNumPages());
258 v9 += v8;
259 NS_LOG_INFO("v9 += v8" << v9);
260 ValArray<T> v10(v8.GetNumRows(), v8.GetNumCols(), v8.GetNumPages());
261 v10 -= v8;
262 NS_LOG_INFO("v10 -= v8" << v10);
263
264 // test == and != operators
265 NS_TEST_ASSERT_MSG_EQ(bool(v9 == v8), true, "Matrices v8 and v9 should be equal");
266 NS_TEST_ASSERT_MSG_EQ(bool(v10 == v8), false, "Matrices v8 and v10 should not be equal");
267 NS_TEST_ASSERT_MSG_EQ(bool(v10 != v8), true, "Matrices v8 and v10 should not be equal");
268 // test whether arrays are equal when they have different lengths
269 NS_TEST_ASSERT_MSG_NE(ValArray<int>(std::valarray({1, 2, 3})),
270 ValArray<int>(std::valarray({1, 2, 3, 4})),
271 "Arrays should not be equal, they have different dimensions.");
272
273 // test the function IsAlmostEqual
274 v9(0, 0, 0) = v9(0, 0, 0) + static_cast<T>(1);
275 NS_TEST_ASSERT_MSG_EQ(v9.IsAlmostEqual(v8, 2) && (v9 != v8),
276 true,
277 "Matrices should be almost equal, but not equal.");
278
279 // test the initialization with std::vector
280 ValArray<T> v12 = ValArray(std::vector<T>({1, 2, 3}));
281 NS_LOG_INFO("v12:" << v12);
282}
283
284/**
285 * \ingroup valArray-tests
286 * ValArray test suite
287 *
288 * \brief The test checks the correct behaviour of ValArray class
289 */
291{
292 public:
293 /** Constructor. */
295};
296
298 : TestSuite("val-array-test")
299{
300 AddTestCase(new ValArrayTestCase<double>("Test ValArray<double>"));
301 AddTestCase(new ValArrayTestCase<std::complex<double>>("Test ValArray<std::complex<double>>"));
302 AddTestCase(new ValArrayTestCase<int>("Test ValArray<int>"));
303}
304
305/**
306 * \ingroup valArray-tests
307 * ValArrayTestSuite instance variable.
308 */
310
311} // namespace tests
312} // namespace ns3
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
ValArray is a class to efficiently store 3D array.
Definition: val-array.h:85
bool IsAlmostEqual(const ValArray< T > &rhs, T tol) const
Compare Valarray up to a given absolute tolerance.
Definition: val-array.h:689
size_t GetNumPages() const
Definition: val-array.h:398
size_t GetSize() const
Definition: val-array.h:405
size_t GetNumRows() const
Definition: val-array.h:384
size_t GetNumCols() const
Definition: val-array.h:391
ValArray test case for testing ValArray class.
ValArrayTestCase()=default
Default constructor.
ValArrayTestCase< T > & operator=(ValArrayTestCase< T > &&)=default
Move assignment operator.
ValArrayTestCase(ValArrayTestCase< T > &&)=default
Move constructor.
ValArrayTestCase(const ValArrayTestCase< T > &)=default
Copy constructor.
ValArrayTestCase< T > & operator=(const ValArrayTestCase< T > &)=default
Copy assignment operator.
~ValArrayTestCase() override
Destructor.
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:145
#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:565
static ValArrayTestSuite g_valArrayTestSuite
ValArrayTestSuite instance variable.
Every class exported by the ns3 library is enclosed in the ns3 namespace.