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
28namespace ns3
29{
30namespace tests
31{
32
33NS_LOG_COMPONENT_DEFINE("ValArrayTest");
34
40template <class T>
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
82template <class T>
84 : TestCase(name)
85{
86}
87
88template <class T>
90{
91}
92
93template <class T>
94void
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=(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: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.