- changed from RVec[0/1/2] to RVec(x, y, z)
[alexxy/gromacs-domains.git] / src / domaintests.cpp
1 #include "domaintype.h"
2 #include "newfit.h"
3
4 #include "gtest/gtest.h"
5
6 #include <iostream>
7
8 // https://habr.com/ru/post/119090/
9
10 TEST( fitTests, fitTest_F )
11 {
12     // расстояние по осям для направляющих векторов
13     ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, 0, 0), 2, 0.000001);
14     ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, 0, 0), 2, 0.000001);
15     ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, 0, 0), 2, 0.000001);
16
17     // расстояние по осям + повороты по осям для направляющих векторов
18     ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, M_PI, 0, 0), 2, 0.000001);
19     ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, M_PI, 0), 0, 0.000001);
20     ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, 0, M_PI), 0, 0.000001);
21
22     ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, M_PI, 0), 2, 0.000001);
23     ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, M_PI, 0, 0), 0, 0.000001);
24     ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, 0, M_PI), 0, 0.000001);
25
26     ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, 0, M_PI), 2, 0.000001);
27     ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, M_PI, 0), 0, 0.000001);
28     ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, M_PI, 0, 0), 0, 0.000001);
29
30     // расстояние для сложного вектора
31     ASSERT_NEAR(F(1, 1, 1, -1, -1, -1, 0, 0, 0), std::sqrt(3) * 2, 0.000001);
32     ASSERT_NEAR(F(1, 1, 1, -1, 1, 1, 0, 0, 0), 2, 0.000001);
33     ASSERT_NEAR(F(1, 1, 1, -1, -1, 1, 0, 0, 0), std::sqrt(2) * 2, 0.000001);
34
35     // расстояния для сложного вектора + повороты
36     ASSERT_NEAR(F(1, 1, 1, -1, -1, -1, M_PI, M_PI / 2, 0), 0, 0.000001);
37     ASSERT_NEAR(F(1, 1, 1, -1, 1, 1, 0, 0, -M_PI / 2), 0, 0.000001);
38 }
39
40 TEST( fitTests, fitTest_searchF0xyzabc)
41 {
42     // шаблон - ещё под вопросом нужно ли и как сделать если да
43 }
44
45 TEST( fitTests, fitTest_ApplyFit)
46 {
47     RVec mid1, mid2, x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1), x2(-1, 0, 0), y2(0, -1, 0), z2(0, 0, -1);
48
49
50     std::vector< RVec > testFrame1, testFrame2, testFrame3;
51     testFrame1.resize(0);
52     testFrame2.resize(0);
53     std::vector< std::pair< unsigned int, unsigned int > > testPairs;
54     testPairs.resize(0);
55
56     for (unsigned int i = 0; i < 27; i++) {
57         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
58         testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
59         testPairs.push_back(std::make_pair(i, i));
60     }
61
62     testFrame3.resize(0);
63     testFrame3 = testFrame2;
64     ApplyFit(testFrame3, 2, 2, 2, 0, 0, 0);
65     CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
66     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
67
68     testFrame3.resize(0);
69     testFrame3 = testFrame1;
70     ApplyFit(testFrame3, 0, 0, 0, M_PI, 0, -M_PI / 2);
71     CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
72     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
73
74     testFrame3.resize(0);
75     testFrame3 = testFrame1;
76     ApplyFit(testFrame3, 0, 0, 0, 0, M_PI, M_PI / 2);
77     CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
78     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
79
80     testFrame3.resize(0);
81     testFrame3 = testFrame1;
82     ApplyFit(testFrame3, 0, 0, 0, M_PI, M_PI / 2, 0);
83     CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
84     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
85
86     testFrame3.resize(0);
87     testFrame3 = testFrame1;
88     ApplyFit(testFrame3, 0, 0, 0, 3 * M_PI / 2, M_PI / 2, M_PI / 2);
89     CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
90     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
91
92     testFrame3.resize(0);
93     testFrame3 = testFrame1;
94     ApplyFit(testFrame1, -1, -1, -1, M_PI, 0, -M_PI / 2);
95     ApplyFit(testFrame3, 0, 0, 0, M_PI, 0, -M_PI / 2);
96     ApplyFit(testFrame3, 1, 1, 1, 0, 0, 0);
97     ApplyFit(testFrame1, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
98     ApplyFit(testFrame3, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
99     CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
100     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
101     double testF = 0;
102     for (unsigned int i = 0; i < testFrame1.size(); i++) {
103         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
104     }
105     ASSERT_NEAR(testF, 0, 0.000001);
106 }
107
108 TEST( fitTests, fitTest_CalcMid)
109 {
110     RVec mid1, mid2, x1, y1, z1, x2, y2, z2;
111
112     x1[0] = 1; x1[1] = 0; x1[2] = 0;
113     y1[0] = 0; y1[1] = 1; y1[2] = 0;
114     z1[0] = 0; z1[1] = 0; z1[2] = 1;
115
116     x2[0] = -1; x2[1] = 0; x2[2] = 0;
117     y2[0] = 0; y2[1] = -1; y2[2] = 0;
118     z2[0] = 0; z2[1] = 0; z2[2] = -1;
119
120     std::vector< RVec > testFrame1, testFrame2;
121     testFrame1.resize(0);
122     testFrame2.resize(0);
123     std::vector< std::pair< unsigned int, unsigned int > > testPairs;
124     testPairs.resize(0);
125
126     for (unsigned int i = 0; i < 27; i++) {
127         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
128         testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
129         testPairs.push_back(std::make_pair(i, i));
130     }
131
132     CalcMid(testFrame1, testFrame1, mid1, mid2, testPairs);
133     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
134
135     CalcMid(testFrame2, testFrame2, mid1, mid2, testPairs);
136     ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
137
138     CalcMid(testFrame1, testFrame2, mid1, mid2, testPairs);
139     ASSERT_NEAR((mid1 - mid2).norm(), 2 * std::sqrt(3), 0.000001);
140 }
141
142 TEST( fitTests, fitTest_MyFitNew)
143 {
144     RVec a, x1, y1, z1;
145
146     x1[0] = 1; x1[1] = 0; x1[2] = 0;
147     y1[0] = 0; y1[1] = 1; y1[2] = 0;
148     z1[0] = 0; z1[1] = 0; z1[2] = 1;
149
150     a[0] = -2; a[1] = -2; a[2] = -2;
151
152     std::vector< RVec > testFrame1, testFrame2, testFrame3;
153     testFrame1.resize(0);
154     testFrame2.resize(0);
155     testFrame3.resize(0);
156     std::vector< std::pair< unsigned int, unsigned int > > testPairs;
157     testPairs.resize(0);
158
159     for (unsigned int i = 0; i < 27; i++) {
160         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
161         testFrame2.push_back(testFrame1.back() + a);
162         testPairs.push_back(std::make_pair(i, i));
163     }
164
165     testFrame3 = testFrame2;
166     MyFitNew(testFrame1, testFrame3, testPairs, 0);
167     double testF = 0;
168     for (unsigned int i = 0; i < testFrame1.size(); i++) {
169         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
170     }
171     ASSERT_NEAR(testF, 0, 0.000001);
172
173     testFrame3.resize(0);
174     testFrame3 = testFrame2;
175     ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
176     MyFitNew(testFrame1, testFrame3, testPairs, 0.000001);
177     testF = 0;
178     for (unsigned int i = 0; i < testFrame1.size(); i++) {
179         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
180     }
181     ASSERT_NEAR(testF, 0, 0.01);
182
183     testFrame3.resize(0);
184     testFrame3 = testFrame2;
185     ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
186     MyFitNew(testFrame1, testFrame3, testPairs, 0.0000001);
187     testF = 0;
188     for (unsigned int i = 0; i < testFrame1.size(); i++) {
189         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
190     }
191     ASSERT_NEAR(testF, 0, 0.001);
192
193     testFrame3.resize(0);
194     testFrame3 = testFrame2;
195     ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
196     MyFitNew(testFrame1, testFrame3, testPairs, 0.0000001);
197     testF = 0;
198     for (unsigned int i = 0; i < testFrame1.size(); i++) {
199         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
200     }
201     ASSERT_NEAR(testF, 0, 0.0001);
202
203     testFrame3.resize(0);
204     testFrame3 = testFrame2;
205     ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
206     MyFitNew(testFrame1, testFrame3, testPairs, 0.00000001);
207     testF = 0;
208     for (unsigned int i = 0; i < testFrame1.size(); i++) {
209         testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
210     }
211     ASSERT_NEAR(testF, 0, 0.00001);
212
213 }
214
215 // т.к. домены это класс с кучей приватных функций ещё под вопросом как их тестить
216 // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#testing-private-code
217 // FRIEND_TEST
218
219 //
220 // public API tests
221 //
222
223 TEST( domainTests, domainTest_setDefaults)
224 {
225     domainType testDomain;
226     std::vector< unsigned long > testIndex;
227     testIndex.resize(0);
228     std::vector< RVec > testRef;
229     testRef.resize(0);
230
231     RVec testA, testB;
232     testA[0] = 0; testA[1] = 0; testA[2] = 0;
233     testB[0] = 1; testB[1] = 1; testB[2] = 1;
234     for (unsigned int i = 0; i < 100; i++) {
235         testIndex.push_back(i);
236         testRef.push_back(testA + testB * static_cast< float >(i));
237     }
238
239     int testWindowSize = 500;
240     int testDomainMinimumSize = 5;
241     int testDomainSearchAlgorythm = 1;
242     int testTimeStepBetweenWindows = 100;
243     unsigned int testSliceNum = testIndex.size() - testDomainMinimumSize + 1;
244     double testEpsilon = 1.5;
245     double testDelta = 0.98;
246     std::string testOutPutFileName = "testString";
247
248     testDomain.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName);
249
250     ASSERT_EQ(testDomain.graph.size(), 0);
251     ASSERT_EQ(testDomain.structIndex, testIndex);
252
253     ASSERT_EQ(testDomain.ref.size(), testRef.size());
254     for (unsigned int i = 0; i < testRef.size(); i++) {
255         ASSERT_EQ(testDomain.ref[i][0], testRef[i][0]);
256         ASSERT_EQ(testDomain.ref[i][1], testRef[i][1]);
257         ASSERT_EQ(testDomain.ref[i][2], testRef[i][2]);
258         //ASSERT_EQ(testDomain.ref[i], testRef[i]); not working probably due to std::vector< ->float[3]<- > frame;
259     }
260     //ASSERT_EQ(testDomain.ref, testRef); not working
261
262     ASSERT_EQ(testDomain.eps, testEpsilon);
263     ASSERT_EQ(testDomain.dlt, testDelta);
264     ASSERT_EQ(testDomain.window, testWindowSize);
265     ASSERT_EQ(testDomain.dms, testDomainMinimumSize);
266     ASSERT_EQ(testDomain.dsa, testDomainSearchAlgorythm);
267     ASSERT_EQ(testDomain.ts, testTimeStepBetweenWindows);
268     ASSERT_EQ(testDomain.outPut, testOutPutFileName);
269     ASSERT_EQ(testDomain.domsizes.size(), testSliceNum);
270     ASSERT_EQ(testDomain.updateCount, 0);
271 }
272
273 TEST( domainTests, domainTest_update)
274 {
275     std::vector< std::vector< RVec > > testTraj1, testTraj2, testTraj3;
276     testTraj1.resize(0);
277     testTraj2.resize(0);
278     testTraj3.resize(0);
279     RVec testA(1, 2, 3), testB(1, 0, 0), testC(0, 1, 0);
280     for (unsigned int i0 = 0; i0 < 1000; i0++) {
281         testTraj1.resize(testTraj1.size() + 1);
282         testTraj2.resize(testTraj2.size() + 1);
283         testTraj3.resize(testTraj3.size() + 1);
284         for (unsigned int i1 = 0; i1 < 10; i1++) {
285             testTraj1.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
286             testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
287             testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB + static_cast< float >(i0) * testC);
288         }
289         for (unsigned int i1 = 0; i1 < 10; i1++) {
290             testTraj1.back().push_back(static_cast< float >(i1) * testA - static_cast< float >(i0) * testB);
291             testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testC);
292             testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB - static_cast< float >(i0) * testC);
293         }
294     }
295
296     std::vector< unsigned long > testIndex;
297     testIndex.resize(0);
298     std::vector< RVec > testRef;
299     testRef.resize(0);
300     for (unsigned int i = 0; i < 20; i++) {
301         testIndex.push_back(i);
302         testRef.push_back(static_cast< float >(i % 10) * testA);
303     }
304     int testWindowSize = 100;
305     int testDomainMinimumSize = 4;
306     int testDomainSearchAlgorythm = 0;
307     int testTimeStepBetweenWindows = 100;
308     unsigned int testSliceNum = testIndex.size() - testDomainMinimumSize + 1;
309     double testEpsilon = 1.5;
310     double testDelta = 0.98;
311     std::string testOutPutFileName1 = "testString1.ndx", testOutPutFileName2 = "testString2.ndx", testOutPutFileName3 = "testString3.ndx";
312
313     domainType testDomain1, testDomain2, testDomain3;
314     testDomain1.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName1);
315     testDomain2.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName2);
316     testDomain3.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName3);
317
318     std::vector< std::vector< RVec > > testTemp1, testTemp2, testTemp3;
319
320     for (unsigned int i = 0; i < 1000; i++) {
321         testTemp1.resize(0);
322         testTemp2.resize(0);
323         testTemp3.resize(0);
324         testTemp1.resize(testSliceNum, testTraj1[i]);
325         testTemp2.resize(testSliceNum, testTraj2[i]);
326         testTemp3.resize(testSliceNum, testTraj3[i]);
327         testDomain1.update(testTemp1, i);
328         testDomain2.update(testTemp2, i);
329         testDomain3.update(testTemp3, i);
330     }
331 }
332
333 //
334 // private API tests
335 //
336
337 TEST( domainTests, domainTest_setGraph)
338 {
339     // данную функцию тестировать смысла нет, слишком простой функционал
340 }
341
342 TEST( domainTests, domainTest_deleteDomainFromGraph)
343 {
344     // данную функцию тестировать смысла нет, слишком простой функционал
345 }
346
347 TEST( domainTests, domainTest_searchDomainSizes)
348 {
349     // данную функцию тестировать смысла нет, слишком простой функционал
350 }
351
352 TEST( domainTests, domainTest_getDomains)
353 {
354     domainType testDomain;
355     std::vector< unsigned long > testIndex;
356     testIndex.resize(0);
357     std::vector< RVec > testRef;
358     testRef.resize(0);
359
360     RVec testA(0, 0, 0), testB(1, 1, 1);
361     for (unsigned int i = 0; i < 100; i++) {
362         testIndex.push_back(i);
363         testRef.push_back(testA + testB * static_cast< float >(i));
364     }
365
366     int testWindowSize = 100;
367     int testDomainMinimumSize = 5;
368     int testDomainSearchAlgorythm = 0;
369     int testTimeStepBetweenWindows = 100;
370     unsigned int testSliceNum = testIndex.size() - testDomainMinimumSize + 1;
371     double testEpsilon = 1.5;
372     double testDelta = 0.98;
373     std::string testOutPutFileName = "testString";
374
375     testDomain.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName);
376
377     testDomain.graph.resize(1);
378     testDomain.graph.front().resize(testSliceNum);
379     for (unsigned int i1 = 0; i1 < testSliceNum; i1++) {
380         testDomain.setGraph(testDomain.graph.front()[i1], testRef);
381         for (unsigned int i2 = 0; i2 < testIndex.size(); i2++) {
382             for (unsigned int i3 = 0; i3 < testIndex.size(); i3++) {
383                 testDomain.graph.front()[i1][i2][i3].num = 4;
384             }
385         }
386     }
387     testDomain.getDomains();
388     ASSERT_EQ(testDomain.domains.size(), 0);
389
390     for (unsigned int i0; i0 < 3; i0++) {
391         testDomain.graph.resize(1);
392         testDomain.graph.front().resize(testSliceNum);
393         for (unsigned int i1 = 0; i1 < testSliceNum; i1++) {
394             testDomain.setGraph(testDomain.graph.front()[i1], testRef);
395             for (unsigned int i2 = 0; i2 < testIndex.size(); i2++) {
396                 for (unsigned int i3 = 0; i3 < testIndex.size(); i3++) {
397                     testDomain.graph.front()[i1][i2][i3].num = 100;
398                 }
399             }
400         }
401         testDomain.dsa = i0;
402         testDomain.getDomains();
403         ASSERT_EQ(testDomain.domains.size(), 1);
404     }
405
406     // шаблон
407     // сделать непересекающиеся - выделить
408     // пересекающиеся - выделить
409     // ещё подумать что это такое и как это выделяется
410 }
411
412 TEST( domainTests, domainTest_print)
413 {
414     // данную функцию тестировать смысла нет, слишком простой функционал
415     // или в целом не сильно понятно имеется ли смысл в этом
416 }
417
418 int main(int argc, char *argv[]) {
419     ::testing::InitGoogleTest( &argc, argv );
420     return RUN_ALL_TESTS();
421 }