Skip to content

Commit 30e3219

Browse files
authored
Massive tests update / Крупное обновление тестов
1. A unified infrastructure for tests has been developed. 2. Tests have gained independence from this library's interface. 3. Users have been given much more freedom in configuring the tests. 4. A new test (tstest_principals) has been added. 5. Improved logging and verbosity. 6. tstest_definition has been corrected in order to meet new development guidelines. ---------- 1. Разработана единая инфраструктура для всех тестов. 2. Тесты стали независимыми от интерфейса библиотеки. 3. Пользователям предоставлено больше возможностей для конфигурации тестов. 4. Добавлен новый тест (tstest_principals). 5. Улучшенные логи и текстовый вывод. 6. В tstest_definition внесены исправления с тем, что он соответствовал новым development guidelines.
2 parents 76c1fb4 + 47a0f07 commit 30e3219

21 files changed

+5714
-755
lines changed

CMakeLists.txt

Lines changed: 0 additions & 9 deletions
This file was deleted.

README.md

Lines changed: 288 additions & 95 deletions
Large diffs are not rendered by default.

tests/CMakeLists.txt

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/README.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
TsTests Usage and Development Guide
2+
===================================
3+
4+
5+
6+
7+
## Contents
8+
9+
* [Purpose of TsTests](#purpose-of-tstests)
10+
* [Return codes](#return-codes)
11+
* [Verbosity levels and logs](#verbosity-levels-and-logs)
12+
* [Optimisations for digital nets](#optimisations-for-digital-nets)
13+
* [`TsTestsInfo` structure](#tstestsinfo-structure)
14+
* [Available tests](#available-tests)
15+
* [1. `tstest_uniqueness`. Test for component-wise uniqueness](#1-tstest_uniqueness-test-for-component-wise-uniqueness)
16+
* [1.1. Description](#11-description)
17+
* [1.2. Limits of applicability](#12-limits-of-applicability)
18+
* [2. `tstest_definition`. Test for (t, m, s)-net definition](#2-tstest_definition-test-for-t-m-s-net-definition)
19+
* [2.1. Description](#21-description)
20+
* [2.2. Limits of applicability](#22-limits-of-applicability)
21+
* [3. `tstest_principals`. Test for principal components analysis](#3-tstest_principals-test-for-principal-components-analysis)
22+
* [3.1. Description](#31-description)
23+
* [3.2. Limits of applicability](#32-limits-of-applicability)
24+
* [Automatic tester](#automatic-tester)
25+
* [Development guidelines](#development-guidelines)
26+
27+
28+
29+
30+
## Purpose of TsTests
31+
32+
TsTests are created to verify properties of (t, m, s)-nets constructed with the help of (t, s)-sequences. Tests presented here have independent interface from the generator in this repository, so there should be no problems in using them for validating other programs. All files that are contained within this folder and its subfolders (except for `README.md` file and `automatic_tester` subfolder) are necessary for the correct operation of tests.
33+
All TsTests can be subdivided into two groups: *validation* tests and *analytical* tests. Validation tests are used to verify particular *hypothesis* for a given test case or, in other words, find the answer for a certain yes/no question. Analytical tests, on the other hand, are used to perform some form of calculation and analysis in order to present numeric *characteristics* for the given test case.
34+
TsTests view every point of net as a vector of `TSTESTS_COORDINATE_TYPE` floating-point values. `TSTESTS_COORDINATE_TYPE` **may** be redefined by user.
35+
36+
[^ to the top ^](#contents)
37+
38+
39+
40+
41+
## Return codes
42+
43+
TsTests use the following return codes defined in `util/common.hpp::TsTestsReturnCode`.
44+
45+
| Return code | Validation tests | Analytical tests |
46+
|:---------------------------------:|--------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
47+
| `TSTESTS_RETURNCODE_SUCCESS` | supposed to be used when test finishes its work successfully and tested hypothesis is found to be true | supposed to be used when test finishes its work successfully and all characteristics are found |
48+
| `TSTESTS_RETURNCODE_FAIL_GENERAL` | supposed to be used when a contradiction with the tested hypothesis has been discovered | supposed to be used when test is not able to calculate at least one characteristic |
49+
| `TSTESTS_RETURNCODE_FAIL_INPUT` | supposed to be used when input data is invalid | supposed to be used when input data is invalid |
50+
| `TSTESTS_RETURNCODE_FAIL_MEMORY` | supposed to be used when memory allocation fails | supposed to be used when memory allocation fails |
51+
52+
Each return code `r` **may** be printed into console in a form of human-readable string using `TSTESTS_PRINT_RETURNCODE(r)`.
53+
54+
[^ to the top ^](#contents)
55+
56+
57+
58+
59+
## Verbosity levels and logs
60+
61+
TsTests directly support 5 levels of verbosity that affect the amount of details to be included into logs. Information that is needed to be displayed on each verbosity level varies for validation tests and analytical tests.
62+
63+
| Verbosity level | Validation tests | Analytical tests |
64+
|:---------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
65+
| `0` | no logging is performed | no logging is performed |
66+
| `1` | `+`, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `-`, if `TSTESTS_RETURNCODE_FAIL_GENERAL` is returned; `- [!]` otherwise | `+`, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `-`, if `TSTESTS_RETURNCODE_FAIL_GENERAL` is returned; `- [!]` otherwise |
67+
| `2` | `+` and the short statement of verified hypothesis, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `-` and the short statement of unverified hypothesis, if `TSTESTS_RETURNCODE_FAIL_GENERAL` is returned; `- [!]` otherwise | `+`, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `-`, if `TSTESTS_RETURNCODE_FAIL_GENERAL` is returned; `- [!]` otherwise |
68+
| `3` | `Answer: POSITIVE.` and the full statement of verified hypothesis, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `Answer: NEGATIVE.` and the full statement of unverified hypothesis, if `TSTESTS_RETURNCODE_FAIL_GENERAL` is returned; `Answer: NEGATIVE.` and the full description of occured error otherwise | `Answer: POSITIVE.` and all calculated characteristics, if `TSTESTS_RETURNCODE_SUCCESS` is returned; `Answer: NEGATIVE.` and the full description of occured error otherwise |
69+
| `4` | logs of all intermediate steps followed by the information described for verbosity level `3` | logs of all intermediate steps followed by the information described for verbosity level `3` |
70+
71+
Verbosity level **can** be specified by defining the `TSTESTS_VERBOSITY_LEVEL n` macro where `n` **must** be replaced with one of the values described above. If verbosity level is not manually set, it is implied to be `0`.
72+
73+
[^ to the top ^](#contents)
74+
75+
76+
77+
78+
## Optimisations for digital nets
79+
80+
When testing the digital nets, one **may** apply certain optimisations to make calculations faster and more precise. These optimisations **can** be switched on by defining `TSTESTS_OPTIMISE_FOR_DIGITAL_NETS` macro. Note, that some tests **may** operate for digital nets only, some tests **may** operate for non-digital nets only. These peculiarities are stated in the description of each individual test.
81+
82+
[^ to the top ^](#contents)
83+
84+
85+
86+
87+
## `TsTestsInfo` structure
88+
89+
In order to pass parameters into TsTests, the `TsTestsInfo` structure **must** be used. Each structure represents a single test case. `TsTestsInfo` is defined in `util/common.hpp` and contains the following fields:
90+
91+
* `t` — expected defect of a given (t, m, s)-net (this value is verified by `tstest_definition`, see below for more info);
92+
* `m` — binary logarithm of the amount of points in a given (t, m, s)-net (net **must** consist of `2^m` points);
93+
* `s` — dimension of space;
94+
* `bitwidth` — number of bits used for points generation (applicable for digital nets only);
95+
* `next_point_getter` — a function that returns net's point by its index as a vector of `TSTESTS_COORDINATE_TYPE`;
96+
* `log_file``TSTESTS_LOG_IN_CONSOLE` or a valid `FILE` pointer to the opened file.
97+
98+
[^ to the top ^](#contents)
99+
100+
101+
102+
103+
## Available tests
104+
105+
The following tests are implemented.
106+
107+
#### 1. `tstest_uniqueness`. Test for component-wise uniqueness
108+
109+
###### 1.1. Description
110+
111+
*File*: `tstest_uniqueness.hpp`
112+
113+
*Signature*: `TsTestsReturnCode const tstest_uniqueness(TsTestsInfo *const test_info)`
114+
115+
*Type*: Validation test.
116+
117+
*Brief*: This test validates component-wise uniqueness of all generated points.
118+
119+
Validation of component-wise uniqueness is performed using bit arrays: one bit array per each dimension. This allows to reduce memory costs and, hence, extend the usage of this test on large-scaled data.
120+
121+
*Returns*:
122+
123+
* `TSTESTS_RETURNCODE_SUCCESS` in case of successful pass of the test;
124+
* `TSTESTS_RETURNCODE_FAIL_GENERAL` in case of existence of at least one repetetive coordinate for at least one component;
125+
* `TSTESTS_RETURNCODE_FAIL_INPUT` in case of invalidity of `test_info` pointer;
126+
* `TSTESTS_RETURNCODE_FAIL_MEMORY` in case of dynamic memory allocation fail.
127+
128+
###### 1.2. Limits of applicability
129+
130+
| Criterion | Value
131+
|----------------------------------|-------
132+
| Maximum advised `bitwidth` value | 32
133+
| Support of digital nets | supported
134+
| Support of non-digital nets | not supported
135+
136+
137+
#### 2. `tstest_definition`. Test for (t, m, s)-net definition
138+
139+
###### 2.1. Description
140+
141+
*File*: `tstest_definition.hpp`
142+
143+
*Signature*: `TsTestsReturnCode const tstest_definition(TsTestsInfo *const test_info)`
144+
145+
*Type*: Validation test.
146+
147+
*Brief*: This test validates the definition of (t, m, s)-net for the generated set of points.
148+
149+
Validation of definition is performed by calculation of points within each elementary interval. Counters of points occupy the least possible amount of memory due to bitwise packaging.
150+
151+
*Returns*:
152+
153+
* `TSTESTS_RETURNCODE_SUCCESS` in case of successful definition assertion;
154+
* `TSTESTS_RETURNCODE_FAIL_GENERAL` in case when generated points fail to meet the requirements of definition by not demonstrating the needed amount of points within at least one elementary interval;
155+
* `TSTESTS_RETURNCODE_FAIL_INPUT` in case of invalidity of `test_info` pointer or in case when generated points fail to meet the requirements of definition by improperly set `t` and `m` parameters;
156+
* `TSTESTS_RETURNCODE_FAIL_MEMORY` in case of dynamic memory allocation fail.
157+
158+
###### 2.2. Limits of applicability
159+
160+
| Criterion | Value
161+
|----------------------------------|-------
162+
| Maximum advised `bitwidth` value | 63
163+
| Support of digital nets | supported
164+
| Support of non-digital nets | supported
165+
166+
167+
#### 3. `tstest_principals`. Test for principal components analysis
168+
169+
###### 3.1. Description
170+
171+
*File*: `tstest_principals.hpp`
172+
173+
*Signature*: `TsTestsReturnCode const tstest_principals(TsTestsInfo *const test_info)`
174+
175+
*Type*: Analytical test.
176+
177+
*Brief*: This test performs the incremental principal component analysis for the set of generated points.
178+
179+
This test can be used to find the axes in multidimensional space along which the coordinates of points are variated the most. This is useful for recognising linear patterns in the mutual disposition of points.
180+
181+
*Returns*:
182+
183+
* `TSTESTS_RETURNCODE_SUCCESS` in case of successful completion of calculations;
184+
* `TSTESTS_RETURNCODE_FAIL_INPUT` in case of invalidity of `test_info` pointer;
185+
* `TSTESTS_RETURNCODE_FAIL_MEMORY` in case of dynamic memory allocation fail.
186+
187+
###### 3.2. Limits of applicability
188+
189+
| Criterion | Value
190+
|----------------------------------|-------
191+
| Maximum advised `bitwidth` value | 64
192+
| Support of digital nets | supported
193+
| Support of non-digital nets | supported
194+
195+
[^ to the top ^](#contents)
196+
197+
198+
199+
200+
## Automatic tester
201+
202+
`automatic_tester/automatic_tester.cpp` contains an automatic tester for `sequences::Niederreiter` generator from this repository. This program tests different nets one by one in the *s*-dimensional space where *s* is varied from 1 to 10. Tester **can** be built with the help of `automatic_tester/automatic_tester.mak` Make-file on Windows, if one uses GCC compilers, with the help of the following command line:
203+
204+
make -f automatic_tester.mak
205+
206+
Tester **can** be supplied with the following command line arguments:
207+
208+
* `-log f` — specifies file to write logs by its path `f`; log will be performed into console when this argument is omitted.
209+
210+
You **may** look through `automatic_tester/automatic_tester_log.txt` file to see the output of this program.
211+
212+
[^ to the top ^](#contents)
213+
214+
215+
216+
217+
## Development guidelines
218+
219+
Any developer who wishes to design a new TsTest **must** follow these guidelines in order to organically fit into their infrastructure.
220+
221+
* Any TsTest **must** return `TsTestsReturnCode const` value.
222+
* Return values **should** be construed in accordance with the [Return codes](#return-codes) section of this document.
223+
* Any TsTest **must** accept `TsTestsInfo *const` as its only argument.
224+
* Name of any TsTest **should** begin with `tstest_`.
225+
* The first line of code in any TsTest **must** be `TSTESTS_TEST_FUNCTION_BEGIN(name, log_file)` where `name` **must** be replaced with capitalised name of test function and `log_file` **must** be replaced with `TSTESTS_LOG_IN_CONSOLE` or a valid pointer to an opened `FILE`.
226+
* The line of code in any TsTest before any `return` **must** be `TSTESTS_TEST_FUNCTION_END`.
227+
* Any TsTest **must** provide logging for verbosity levels mentioned in the [Verbosity levels and logs](#verbosity-levels-and-logs) section of this document.
228+
* If any TsTest returns value in complete accordance with the [Return codes](#return-codes) section of this document, then its logging **must** be done in accordance with the [Verbosity levels and logs](#verbosity-levels-and-logs) section of this document.
229+
* Any TsTest **should** tend to use native logging abilities of TsTests infrastructure, specifically `PUSHLOGn(message)`, `PUSHLOGFn(format, ...)`, `APPENDLOG3(message)` and `APPENDLOGF3(format, ...)` macros where `n` **must** be replaced with corresponding verbosity level from `1` to `4`.
230+
* Any TsTest **should** be able to work with both digital and non-digital nets.
231+
* Any TsTest **must** be contained within a single `.hpp` file separately from other TsTests and any other unrelated code.
232+
233+
[^ to the top ^](#contents)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*!
2+
* \file main.cpp
3+
*
4+
* \author
5+
* Andrew Yeliseyev (Russian Technological University, KMBO-03-16, Russia, 2020)
6+
*/
7+
#include "../../include/niederreiter2.hpp"
8+
9+
10+
11+
#define TSTESTS_VERBOSITY_LEVEL 4 // Try setting this value to 0, 1, 2, 3 or 4
12+
#define TSTESTS_OPTIMISE_FOR_DIGITAL_NETS
13+
14+
#include "../tstest_uniqueness.hpp"
15+
#include "../tstest_definition.hpp"
16+
#include "../tstest_principals.hpp"
17+
18+
19+
20+
21+
22+
int main(int argc, char const *const argv[])
23+
{
24+
int log_manual = -1;
25+
26+
sequences::Niederreiter<uint32_t, 32> generator(1);
27+
28+
TsTestsInfo tests_info;
29+
FILE *out = TSTESTS_LOG_IN_CONSOLE;
30+
31+
uint8_t max_s = 10;
32+
std::vector<sequences::BasicInt> degrees = {1, 1, 2, 3, 3, 4, 4, 4, 5, 5};
33+
34+
/*
35+
* Interpret command line parameters
36+
*/
37+
{
38+
int arg_i = 1;
39+
while (arg_i < argc)
40+
{
41+
if (!strcmp(argv[arg_i], "-log") && (log_manual == -1))
42+
{
43+
if (arg_i + 1 < argc)
44+
{
45+
log_manual = arg_i + 1;
46+
arg_i += 2;
47+
continue;
48+
}
49+
else
50+
{
51+
printf("Invalid command line.\n");
52+
goto instant_death;
53+
}
54+
}
55+
printf("Invalid command line.\n");
56+
goto instant_death;
57+
}
58+
}
59+
if (log_manual > 0)
60+
{
61+
out = fopen(argv[log_manual], "w");
62+
if (out == NULL)
63+
{
64+
printf("File cannot be opened.\n");
65+
goto instant_death;
66+
}
67+
}
68+
69+
/*
70+
* Perform tests
71+
*/
72+
fprintf(out, "* * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
73+
fprintf(out, "* Automatic tester for Niederreiter sequences *\n");
74+
fprintf(out, "* Built on %s %s *\n", __DATE__, __TIME__);
75+
fprintf(out, "* * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
76+
for (uint8_t curr_s = 1; curr_s <= max_s; ++curr_s)
77+
{
78+
fprintf(out, "\n\n\n=== TESTS FOR %u-DIMENSIONAL NETS BEGIN ===\n", curr_s);
79+
for (uint8_t first_polynomial_i = 0; first_polynomial_i <= max_s - curr_s; ++first_polynomial_i)
80+
{
81+
std::vector<sequences::BasicInt> curr_degrees(curr_s);
82+
std::copy(degrees.begin() + first_polynomial_i, degrees.begin() + first_polynomial_i + curr_s, curr_degrees.begin());
83+
generator = sequences::Niederreiter<uint32_t, 32>(curr_degrees);
84+
uint8_t curr_m = 5 * ((generator.get_t() / 5) + 1);
85+
fprintf(out, "\n\n\nTest case #%u.%u. A priori parameters:\n", curr_s, first_polynomial_i + 1);
86+
fprintf(out, "\tm = %u\n", curr_m);
87+
fprintf(out, "\ts = %u\n", curr_s);
88+
fprintf(out, "Values to be verified:\n");
89+
fprintf(out, "\tt = %u\n\n", generator.get_t());
90+
91+
tests_info =
92+
{
93+
.t = (uint8_t) generator.get_t(),
94+
.m = curr_m,
95+
.s = (uint8_t) generator.get_s(),
96+
.bitwidth = 32,
97+
.next_point_getter = [&generator](uint64_t const point_i){return generator.get_point_real(point_i);},
98+
.log_file = out
99+
};
100+
101+
tstest_uniqueness(&tests_info);
102+
tstest_definition(&tests_info);
103+
tstest_principals(&tests_info);
104+
}
105+
}
106+
107+
fclose(out);
108+
109+
instant_death:
110+
111+
return 0;
112+
}

0 commit comments

Comments
 (0)