1 #include "domaintype.h"
4 #include "gtest/gtest.h"
8 // https://habr.com/ru/post/119090/
10 TEST( fitTests, fitTest_F )
14 // расстояние по осям для направляющих векторов
15 ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., 0., 0.}), 2, 0.000001);
16 ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., 0., 0.}), 2, 0.000001);
17 ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., 0., 0.}), 2, 0.000001);
19 // расстояние по осям + повороты по осям для направляющих векторов
20 ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {M_PI, 0., 0.}), 2, 0.000001);
21 ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., M_PI, 0.}), 0., 0.000001);
22 ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., 0., M_PI}), 0., 0.000001);
24 ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., M_PI, 0.}), 2, 0.000001);
25 ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {M_PI, 0., 0.}), 0., 0.000001);
26 ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., 0., M_PI}), 0., 0.000001);
28 ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., 0., M_PI}), 2, 0.000001);
29 ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., M_PI, 0.}), 0., 0.000001);
30 ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {M_PI, 0., 0.}), 0., 0.000001);
32 // расстояние для сложного вектора
33 ASSERT_NEAR(F({1, 1, 1}, {-1, -1, -1}, {0., 0., 0.}), std::sqrt(3) * 2, 0.000001);
34 ASSERT_NEAR(F({1, 1, 1}, {-1, 1, 1}, {0., 0., 0.}), 2, 0.000001);
35 ASSERT_NEAR(F({1, 1, 1}, {-1, -1, 1}, {0., 0., 0.}), std::sqrt(2) * 2, 0.000001);
37 // расстояния для сложного вектора + повороты
38 ASSERT_NEAR(F({1, 1, 1}, {-1, -1, -1}, {M_PI, M_PI / 2, 0.}), 0., 0.000001);
39 ASSERT_NEAR(F({1, 1, 1}, {-1, 1, 1}, {0., 0., -M_PI / 2}), 0., 0.000001);
42 TEST( fitTests, fitTest_searchF0xyzabc)
44 // шаблон - ещё под вопросом нужно ли и как сделать если да
47 void ApplyFitRoutine(const std::vector< RVec > &fr1, const std::vector< RVec > &fr2, const std::vector< std::pair< size_t, size_t > > &testPairs, const DVec &R, const DVec &angl, DVec &md1, DVec &md2) {
48 std::vector< RVec > fr3;
51 ApplyFit(fr3, R, angl);
52 CalcMid(fr1, fr3, md1, md2, testPairs);
55 TEST( fitTests, fitTest_ApplyFit)
57 RVec x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1), x2(-1, 0, 0), y2(0, -1, 0), z2(0, 0, -1);
58 DVec mid1(0., 0., 0.), mid2(0., 0., 0.), angl(0., 0., 0.);
60 std::vector< RVec > testFrame1, testFrame2, testFrame3;
63 std::vector< std::pair< size_t, size_t > > testPairs;
66 for (size_t i {0}; i < 27; ++i) {
67 testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
68 testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
69 testPairs.push_back(std::make_pair(i, i));
72 ApplyFitRoutine(testFrame1, testFrame2, testPairs, {2, 2, 2}, {0., 0., 0.}, mid1, mid2);
73 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
75 ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {M_PI, 0., -M_PI / 2}, mid1, mid2);
76 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
78 ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {0., M_PI, M_PI / 2}, mid1, mid2);
79 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
81 ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {M_PI, M_PI / 2, 0.}, mid1, mid2);
82 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
84 ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {3 * M_PI / 2, M_PI / 2, M_PI / 2}, mid1, mid2);
85 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
88 testFrame3 = testFrame1;
89 ApplyFit(testFrame1, {-1, -1, -1}, {M_PI, 0., -M_PI / 2});
90 ApplyFit(testFrame3, {0., 0., 0.}, {M_PI, 0., -M_PI / 2});
91 ApplyFit(testFrame3, {1, 1, 1}, {0., 0., 0.});
92 ApplyFit(testFrame1, {2, 4, 8}, {M_PI / 6, M_PI / 6, M_PI / 6});
93 ApplyFit(testFrame3, {2, 4, 8}, {M_PI / 6, M_PI / 6, M_PI / 6});
94 CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
95 ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
97 for (size_t i {0}; i < testFrame1.size(); ++i) {
98 testF += F(testFrame1[i].toDVec(), testFrame3[i].toDVec(), angl);
100 ASSERT_NEAR(testF, 0., 0.000001);
103 TEST( fitTests, fitTest_CalcMid)
105 RVec x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1), x2(-1, 0, 0), y2(0, -1, 0), z2(0, 0, -1);
106 DVec mid1(0., 0., 0.), mid2(0., 0., 0.), angl(0., 0., 0.);
108 std::vector< RVec > testFrame1, testFrame2;
109 testFrame1.resize(0);
110 testFrame2.resize(0);
111 std::vector< std::pair< size_t, size_t > > testPairs;
114 for (size_t i {0}; i < 27; ++i) {
115 testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
116 testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
117 testPairs.push_back(std::make_pair(i, i));
120 CalcMid(testFrame1, testFrame1, mid1, mid2, testPairs);
121 ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000'001);
123 CalcMid(testFrame2, testFrame2, mid1, mid2, testPairs);
124 ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000'001);
126 CalcMid(testFrame1, testFrame2, mid1, mid2, testPairs);
127 ASSERT_NEAR((mid1 - mid2).norm(), 2 * std::sqrt(3), 0.000'001);
130 void myFitNewRoutine(const std::vector< RVec > &fr1, std::vector< RVec > fr2, const std::vector< std::pair< size_t, size_t > > &testPairs, double prc, double &tF) {
131 MyFitNew(fr1, fr2, testPairs, prc);
133 DVec angl(0., 0., 0.);
134 for (size_t i {0}; i < fr1.size(); ++i) {
135 tF += F(fr1[i].toDVec(), fr2[i].toDVec(), angl);
139 TEST( fitTests, fitTest_MyFitNew)
142 RVec x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1);
143 RVec x2(10, 0, 0), y2(0, 10, 0), z2(0, 0, 10);
144 RVec x3(11, 0, 0), y3(0, 11, 0), z3(0, 0, 11);
146 std::vector< RVec > testFrame1, testFrame2;
147 testFrame1.resize(0);
148 testFrame2.resize(0);
149 std::vector< std::pair< size_t, size_t > > testPairs;
153 * optimal 3x3x3 cubes fitting
156 for (size_t i {0}; i < 27; ++i) {
157 testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
158 testFrame2.push_back(testFrame1.back() + a);
159 testPairs.push_back(std::make_pair(i, i));
164 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
165 ASSERT_NEAR(testF, 0, 0.000'001);
167 ApplyFit(testFrame2, {7.153'4, 0.559'1, -3.141'5}, {M_PI / 23, M_PI / 17, M_PI / 2.2});
169 myFitNewRoutine(testFrame1, testFrame2, testPairs, 1, testF);
170 ASSERT_NEAR(testF, 0, 38.305);
172 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.1, testF);
173 ASSERT_NEAR(testF, 0, 2.313);
175 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.01, testF);
176 ASSERT_NEAR(testF, 0, 2.119);
178 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.001, testF);
179 ASSERT_NEAR(testF, 0, 0.026);
181 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'1, testF);
182 ASSERT_NEAR(testF, 0, 0.019'76);
184 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'01, testF);
185 ASSERT_NEAR(testF, 0, 0.019'76);
187 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
188 ASSERT_NEAR(testF, 0, 0.000'054);
190 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'1, testF);
191 ASSERT_NEAR(testF, 0, 0.000'054);
193 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'01, testF);
194 ASSERT_NEAR(testF, 0, 0.000'054);
196 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'001, testF);
197 ASSERT_NEAR(testF, 0, 0.000'054);
199 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'1, testF);
200 ASSERT_NEAR(testF, 0, 0.000'054);
202 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'01, testF);
203 ASSERT_NEAR(testF, 0, 0.000'054);
206 * different sized 3x3x3 cubes fitting
209 testFrame1.resize(0);
210 testFrame2.resize(0);
211 for (size_t i {0}; i < 27; ++i) {
212 testFrame1.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
213 testFrame2.push_back(x3 * static_cast< float >(i % 3) + y3 * static_cast< float >((i % 9) / 3) + z3 * static_cast< float >(i / 9));
216 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
217 ASSERT_NEAR(testF, 0, 36.827);
219 ApplyFit(testFrame2, {7.1534, 0.5591, -3.1415}, {M_PI / 23, M_PI / 17, M_PI / 2.2});
221 myFitNewRoutine(testFrame1, testFrame2, testPairs, 1, testF);
222 ASSERT_NEAR(testF, 0, 250.665);
224 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.1, testF);
225 ASSERT_NEAR(testF, 0, 249.856);
227 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.01, testF);
228 ASSERT_NEAR(testF, 0, 248.364);
230 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.001, testF);
231 ASSERT_NEAR(testF, 0, 246.780);
233 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'1, testF);
234 ASSERT_NEAR(testF, 0, 227.930);
236 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'01, testF);
237 ASSERT_NEAR(testF, 0, 36.953);
239 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
240 ASSERT_NEAR(testF, 0, 36.953);
242 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'1, testF);
243 ASSERT_NEAR(testF, 0, 36.885);
245 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'01, testF);
246 ASSERT_NEAR(testF, 0, 36.884'71);
248 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'001, testF);
249 ASSERT_NEAR(testF, 0, 36.884'71);
251 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'1, testF);
252 ASSERT_NEAR(testF, 0, 36.884'71);
254 myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'01, testF);
255 ASSERT_NEAR(testF, 0, 36.884'71);
259 // т.к. домены это класс с кучей приватных функций ещё под вопросом как их тестить
260 // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#testing-private-code
267 TEST( domainTests, domainTest_setDefaults)
269 domainType testDomain;
270 std::vector< size_t > testIndex;
272 std::vector< RVec > testRef;
275 RVec testA(0., 0., 0.), testB(1., 1., 1.);
276 for (size_t i {0}; i < 100; ++i) {
277 testIndex.push_back(i);
278 testRef.push_back(testA + testB * static_cast< float >(i));
281 int testWindowSize {500};
282 int testDomainMinimumSize {5};
283 int testDomainSearchAlgorythm {1};
284 int testTimeStepBetweenWindows {100};
285 size_t testSliceNum {testIndex.size() - testDomainMinimumSize + 1};
286 double testEpsilon {1.5};
287 double testDelta {0.98};
288 std::string testOutPutFileName {"testString"};
290 testDomain.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName);
292 ASSERT_EQ(testDomain.graph.size(), 0);
293 ASSERT_EQ(testDomain.structIndex, testIndex);
295 ASSERT_EQ(testDomain.refTable.size(), testRef.size());
296 for (size_t j {0}; j < testRef.size(); ++j) {
297 for (size_t i {0}; i < testRef.size(); ++i) {
298 ASSERT_NEAR(testDomain.refTable[j][i].norm(), (testRef[i] - testRef[j]).norm(), 0.000'01);
302 ASSERT_EQ(testDomain.eps, testEpsilon);
303 ASSERT_EQ(testDomain.dlt, testDelta);
304 ASSERT_EQ(testDomain.window, testWindowSize);
305 ASSERT_EQ(testDomain.dms, testDomainMinimumSize);
306 ASSERT_EQ(testDomain.dsa, testDomainSearchAlgorythm);
307 ASSERT_EQ(testDomain.ts, testTimeStepBetweenWindows);
308 ASSERT_EQ(testDomain.outPut, testOutPutFileName);
309 ASSERT_EQ(testDomain.domsizes.size(), testSliceNum);
310 ASSERT_EQ(testDomain.updateCount, 0);
313 TEST( domainTests, domainTest_update)
315 std::vector< std::vector< RVec > > testTraj1, testTraj2, testTraj3;
319 RVec testA(1, 2, 3), testB(1, 0, 0), testC(0, 1, 0);
320 for (size_t i0 {0}; i0 < 1000; ++i0) {
321 testTraj1.resize(testTraj1.size() + 1);
322 testTraj2.resize(testTraj2.size() + 1);
323 testTraj3.resize(testTraj3.size() + 1);
324 for (size_t i1 {0}; i1 < 10; ++i1) {
325 testTraj1.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
326 testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
327 testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB + static_cast< float >(i0) * testC);
329 for (size_t i1 {0}; i1 < 10; ++i1) {
330 testTraj1.back().push_back(static_cast< float >(i1) * testA - static_cast< float >(i0) * testB);
331 testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testC);
332 testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB - static_cast< float >(i0) * testC);
335 std::vector< size_t > testIndex;
337 std::vector< RVec > testRef;
339 for (size_t i {0}; i < 20; ++i) {
340 testIndex.push_back(i);
341 testRef.push_back(static_cast< float >(i % 10) * testA);
343 int testWindowSize {500};
344 int testDomainMinimumSize {4};
345 int testDomainSearchAlgorythm {0};
346 int testTimeStepBetweenWindows {100};
347 size_t testSliceNum {testIndex.size() - testDomainMinimumSize + 1};
348 double testEpsilon {1.5};
349 double testDelta {0.98};
350 std::string testOutPutFileName1 {"testString1.ndx"}, testOutPutFileName2 {"testString2.ndx"}, testOutPutFileName3 {"testString3.ndx"};
352 domainType testDomain1, testDomain2, testDomain3;
353 testDomain1.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName1);
354 testDomain2.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName2);
355 testDomain3.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName3);
357 std::vector< std::vector< RVec > > testTemp1, testTemp2, testTemp3;
358 for (size_t i {0}; i < 1000; ++i) {
362 testTemp1.resize(testSliceNum, testTraj1[i]);
363 testTemp2.resize(testSliceNum, testTraj2[i]);
364 testTemp3.resize(testSliceNum, testTraj3[i]);
365 testDomain1.update(testTemp1, i);
366 testDomain2.update(testTemp2, i);
367 testDomain3.update(testTemp3, i);
375 TEST( domainTests, domainTest_setGraph)
377 // данную функцию тестировать смысла нет, слишком простой функционал
380 TEST( domainTests, domainTest_deleteDomainFromGraph)
382 // данную функцию тестировать смысла нет, слишком простой функционал
385 TEST( domainTests, domainTest_searchDomainSizes)
387 // данную функцию тестировать смысла нет, слишком простой функционал
390 TEST( domainTests, domainTest_getDomains)
392 domainType testDomain;
393 std::vector< unsigned long > testIndex;
395 std::vector< RVec > testRef;
398 RVec testA(0, 0, 0), testB(1, 1, 1);
399 for (size_t i {0}; i < 100; ++i) {
400 testIndex.push_back(i);
401 testRef.push_back(testA + testB * static_cast< float >(i));
404 int testWindowSize {100};
405 int testDomainMinimumSize {5};
406 int testDomainSearchAlgorythm {0};
407 int testTimeStepBetweenWindows {100};
408 size_t testSliceNum {testIndex.size() - testDomainMinimumSize + 1};
409 double testEpsilon {1.5};
410 double testDelta {0.98};
411 std::string testOutPutFileName {"testString"};
413 testDomain.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName);
415 testDomain.graph.resize(1);
416 testDomain.graph.front().resize(testSliceNum);
417 for (size_t i1 {0}; i1 < testSliceNum; ++i1) {
418 testDomain.setGraph(testDomain.graph.front()[i1]);
419 for (size_t i2 {0}; i2 < testIndex.size(); ++i2) {
420 for (size_t i3 {0}; i3 < testIndex.size(); ++i3) {
421 testDomain.graph.front()[i1][i2][i3].num = 4;
425 testDomain.getDomains();
426 ASSERT_EQ(testDomain.domains.size(), 0);
428 for (int i0 {0}; i0 < 3; ++i0) {
429 testDomain.graph.resize(1);
430 testDomain.graph.front().resize(testSliceNum);
431 for (size_t i1 {0}; i1 < testSliceNum; ++i1) {
432 testDomain.setGraph(testDomain.graph.front()[i1]);
433 for (size_t i2 {0}; i2 < testIndex.size(); ++i2) {
434 for (size_t i3 {0}; i3 < testIndex.size(); ++i3) {
435 testDomain.graph.front()[i1][i2][i3].num = 100;
440 testDomain.getDomains();
441 ASSERT_EQ(testDomain.domains.size(), 1);
445 // сделать непересекающиеся - выделить
446 // пересекающиеся - выделить
447 // ещё подумать что это такое и как это выделяется
450 TEST( domainTests, domainTest_print)
452 // данную функцию тестировать смысла нет, слишком простой функционал
453 // или в целом не сильно понятно имеется ли смысл в этом
456 int main(int argc, char *argv[]) {
457 ::testing::InitGoogleTest( &argc, argv );
458 return RUN_ALL_TESTS();