- in general implemented "new" knowledge of C++
authorAnatoly <Titov_AI@pnpi.nrcki.ru>
Tue, 29 Sep 2020 14:12:27 +0000 (17:12 +0300)
committerAnatoly <Titov_AI@pnpi.nrcki.ru>
Tue, 29 Sep 2020 14:12:27 +0000 (17:12 +0300)
- "int a = 0;" to "int a {0};"
- changed <where needed> data types to "size_t"
- added extra "const"s keywords
- removed extra coping of big chunks of data
- restructured fitting functions
- restructured some loops to "for (auto i : j )"
- changed tests to correspong to new code

src/domains.cpp
src/domaintests.cpp
src/domaintype.cpp
src/domaintype.h
src/newfit.cpp
src/newfit.h

index 589eadfd0d0694df64a5750c80599f2e00d19395..42afc1c5e3ce1795355e3da62869cc24f30049ca 100644 (file)
@@ -99,12 +99,12 @@ class Domains : public TrajectoryAnalysisModule
         Selection                                                               selec;
         std::vector< std::vector< std::pair< unsigned int, unsigned int > > >   fitPairs;
         unsigned int                                                            bone;
-        int                                                                     window                      = -1; // selectable
-        int                                                                     domain_min_size             = -1; // selectable
-        double                                                                  delta                       = -1; // selectable
-        double                                                                  epsi                        = -1; // selectable
-        int                                                                     twStep                      = -1; // selectable
-        int                                                                     DomainSearchingAlgorythm    = -1; // selectable
+        int                                                                     window                      {-1}; // selectable
+        int                                                                     domain_min_size             {-1}; // selectable
+        double                                                                  delta                       {-1}; // selectable
+        double                                                                  epsi                        {-1}; // selectable
+        int                                                                     twStep                      {-1}; // selectable
+        int                                                                     DomainSearchingAlgorythm    {-1}; // selectable
         // Copy and assign disallowed by base.
 };
 
@@ -181,21 +181,21 @@ Domains::initAnalysis(const TrajectoryAnalysisSettings &settings,
     reference.resize(0);
 
     if (top.hasFullTopology()) {
-        for (unsigned int i = 0; i < index.size(); i++) {
-            reference.push_back(top.x().at(index[i]));
+        for (const auto &i : index) {
+            reference.push_back(top.x().at(i));
         }
     }
 
-    // вычисление числа основных (от основа�� основа��ие) последовательностей
+    // вычисление числа основных (от основание) последовательностей
     // в идеале нужно брать все сочетания, но ограничиваемся последовательными наборами
     bone = static_cast< unsigned int >(index.size() - static_cast< unsigned int >(domain_min_size) + 1);
 
     // создание пар для фитирования структур
     fitPairs.resize(0);
     fitPairs.resize(bone);
-    for (unsigned int i = 0; i < bone; i++) {
+    for (size_t i = 0; i < bone; i++) {
         fitPairs[i].resize(0);
-        for (unsigned int j = 0; j < static_cast< unsigned int >(domain_min_size); j++) {
+        for (size_t j = 0; j < domain_min_size; j++) {
             fitPairs[i].push_back(std::make_pair(j + i, j + i));
         }
     }
@@ -211,7 +211,7 @@ void
 Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnalysisModuleData *pdata)
 {
     // считывания текущего фрейма траектории
-    for (unsigned int i = 0; i < index.size(); i++) {
+    for (size_t i = 0; i < index.size(); i++) {
         trajectory[i] = fr.x[index[i]];
     }
 
@@ -222,8 +222,8 @@ Domains::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnal
 
     // фитирование каждой копии
     #pragma omp parallel for ordered schedule(dynamic) firstprivate(reference)
-    for (unsigned int i = 0; i < bone; i++) { 
-        MyFitNew(reference, tsTemp[i], fitPairs[i], 0);
+    for (size_t i = 0; i < bone; i++) {
+        MyFitNew(reference, tsTemp[i], fitPairs[i], 0.000'001);
     }
     #pragma omp barrier
 
index bde152620e1b232c50e1e892edc5395a25f0a72c..eb8cb3c8f5e47bed59cd3d53c1f184ef9e034d2f 100644 (file)
@@ -9,32 +9,34 @@
 
 TEST( fitTests, fitTest_F )
 {
+    DVec a, b, angl;
+
     // расстояние по осям для направляющих векторов
-    ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, 0, 0), 2, 0.000001);
-    ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, 0, 0), 2, 0.000001);
-    ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, 0, 0), 2, 0.000001);
+    ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., 0., 0.}), 2, 0.000001);
+    ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., 0., 0.}), 2, 0.000001);
+    ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., 0., 0.}), 2, 0.000001);
 
     // расстояние по осям + повороты по осям для направляющих векторов
-    ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, M_PI, 0, 0), 2, 0.000001);
-    ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, M_PI, 0), 0, 0.000001);
-    ASSERT_NEAR(F(1, 0, 0, -1, 0, 0, 0, 0, M_PI), 0, 0.000001);
+    ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {M_PI, 0., 0.}), 2, 0.000001);
+    ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., M_PI, 0.}), 0., 0.000001);
+    ASSERT_NEAR(F({1, 0., 0.}, {-1, 0., 0.}, {0., 0., M_PI}), 0., 0.000001);
 
-    ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, M_PI, 0), 2, 0.000001);
-    ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, M_PI, 0, 0), 0, 0.000001);
-    ASSERT_NEAR(F(0, 1, 0, 0, -1, 0, 0, 0, M_PI), 0, 0.000001);
+    ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., M_PI, 0.}), 2, 0.000001);
+    ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {M_PI, 0., 0.}), 0., 0.000001);
+    ASSERT_NEAR(F({0., 1, 0.}, {0., -1, 0.}, {0., 0., M_PI}), 0., 0.000001);
 
-    ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, 0, M_PI), 2, 0.000001);
-    ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, 0, M_PI, 0), 0, 0.000001);
-    ASSERT_NEAR(F(0, 0, 1, 0, 0, -1, M_PI, 0, 0), 0, 0.000001);
+    ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., 0., M_PI}), 2, 0.000001);
+    ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {0., M_PI, 0.}), 0., 0.000001);
+    ASSERT_NEAR(F({0., 0., 1}, {0., 0., -1}, {M_PI, 0., 0.}), 0., 0.000001);
 
     // расстояние для сложного вектора
-    ASSERT_NEAR(F(1, 1, 1, -1, -1, -1, 0, 0, 0), std::sqrt(3) * 2, 0.000001);
-    ASSERT_NEAR(F(1, 1, 1, -1, 1, 1, 0, 0, 0), 2, 0.000001);
-    ASSERT_NEAR(F(1, 1, 1, -1, -1, 1, 0, 0, 0), std::sqrt(2) * 2, 0.000001);
+    ASSERT_NEAR(F({1, 1, 1}, {-1, -1, -1}, {0., 0., 0.}), std::sqrt(3) * 2, 0.000001);
+    ASSERT_NEAR(F({1, 1, 1}, {-1, 1, 1}, {0., 0., 0.}), 2, 0.000001);
+    ASSERT_NEAR(F({1, 1, 1}, {-1, -1, 1}, {0., 0., 0.}), std::sqrt(2) * 2, 0.000001);
 
     // расстояния для сложного вектора + повороты
-    ASSERT_NEAR(F(1, 1, 1, -1, -1, -1, M_PI, M_PI / 2, 0), 0, 0.000001);
-    ASSERT_NEAR(F(1, 1, 1, -1, 1, 1, 0, 0, -M_PI / 2), 0, 0.000001);
+    ASSERT_NEAR(F({1, 1, 1}, {-1, -1, -1}, {M_PI, M_PI / 2, 0.}), 0., 0.000001);
+    ASSERT_NEAR(F({1, 1, 1}, {-1, 1, 1}, {0., 0., -M_PI / 2}), 0., 0.000001);
 }
 
 TEST( fitTests, fitTest_searchF0xyzabc)
@@ -42,17 +44,18 @@ TEST( fitTests, fitTest_searchF0xyzabc)
     // шаблон - ещё под вопросом нужно ли и как сделать если да
 }
 
-void ApplyFitRoutine(std::vector< RVec > fr1, std::vector< RVec > fr2, std::vector< RVec > fr3, std::vector< std::pair< unsigned int, unsigned int > > testPairs, double x, double y, double z, double A, double B, double C, RVec &md1, RVec &md2) {
+void ApplyFitRoutine(const std::vector< RVec > &fr1, const std::vector< RVec > &fr2, const std::vector< std::pair< unsigned int, unsigned int > > &testPairs, const DVec &R, const DVec &angl, DVec &md1, DVec &md2) {
+    std::vector< RVec > fr3;
     fr3.resize(0);
     fr3 = fr2;
-    ApplyFit(fr3, x, y, z, A, B, C);
+    ApplyFit(fr3, R, angl);
     CalcMid(fr1, fr3, md1, md2, testPairs);
 }
 
 TEST( fitTests, fitTest_ApplyFit)
 {
-    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);
-
+    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);
+    DVec mid1(0., 0., 0.), mid2(0., 0., 0.), angl(0., 0., 0.);
 
     std::vector< RVec > testFrame1, testFrame2, testFrame3;
     testFrame1.resize(0);
@@ -60,46 +63,47 @@ TEST( fitTests, fitTest_ApplyFit)
     std::vector< std::pair< unsigned int, unsigned int > > testPairs;
     testPairs.resize(0);
 
-    for (unsigned int i = 0; i < 27; i++) {
+    for (size_t i = 0; i < 27; i++) {
         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
         testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
         testPairs.push_back(std::make_pair(i, i));
     }
 
-    ApplyFitRoutine(testFrame1, testFrame2, testFrame3, testPairs, 2, 2, 2, 0, 0, 0, mid1, mid2);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ApplyFitRoutine(testFrame1, testFrame2, testPairs, {2, 2, 2}, {0., 0., 0.}, mid1, mid2);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
 
-    ApplyFitRoutine(testFrame2, testFrame1, testFrame3, testPairs, 0, 0, 0, M_PI, 0, -M_PI / 2, mid1, mid2);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {M_PI, 0., -M_PI / 2}, mid1, mid2);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
 
-    ApplyFitRoutine(testFrame2, testFrame1, testFrame3, testPairs, 0, 0, 0, 0, M_PI, M_PI / 2, mid1, mid2);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {0., M_PI, M_PI / 2}, mid1, mid2);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
 
-    ApplyFitRoutine(testFrame2, testFrame1, testFrame3, testPairs, 0, 0, 0, M_PI, M_PI / 2, 0, mid1, mid2);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {M_PI, M_PI / 2, 0.}, mid1, mid2);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
 
-    ApplyFitRoutine(testFrame2, testFrame1, testFrame3, testPairs, 0, 0, 0, 3 * M_PI / 2, M_PI / 2, M_PI / 2, mid1, mid2);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ApplyFitRoutine(testFrame2, testFrame1, testPairs, {0., 0., 0.}, {3 * M_PI / 2, M_PI / 2, M_PI / 2}, mid1, mid2);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
 
     testFrame3.resize(0);
     testFrame3 = testFrame1;
-    ApplyFit(testFrame1, -1, -1, -1, M_PI, 0, -M_PI / 2);
-    ApplyFit(testFrame3, 0, 0, 0, M_PI, 0, -M_PI / 2);
-    ApplyFit(testFrame3, 1, 1, 1, 0, 0, 0);
-    ApplyFit(testFrame1, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
-    ApplyFit(testFrame3, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
+    ApplyFit(testFrame1, {-1, -1, -1}, {M_PI, 0., -M_PI / 2});
+    ApplyFit(testFrame3, {0., 0., 0.}, {M_PI, 0., -M_PI / 2});
+    ApplyFit(testFrame3, {1, 1, 1}, {0., 0., 0.});
+    ApplyFit(testFrame1, {2, 4, 8}, {M_PI / 6, M_PI / 6, M_PI / 6});
+    ApplyFit(testFrame3, {2, 4, 8}, {M_PI / 6, M_PI / 6, M_PI / 6});
     CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
-    ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+    ASSERT_NEAR((mid1 - mid2).norm(), 0., 0.000001);
     double testF = 0;
-    for (unsigned int i = 0; i < testFrame1.size(); i++) {
-        testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+    for (size_t i = 0; i < testFrame1.size(); i++) {
+        testF += F(testFrame1[i].toDVec(), testFrame3[i].toDVec(), angl);
     }
-    ASSERT_NEAR(testF, 0, 0.000001);
+    ASSERT_NEAR(testF, 0., 0.000001);
 }
 
 TEST( fitTests, fitTest_CalcMid)
 {
-    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);
+    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);
+    DVec mid1(0., 0., 0.), mid2(0., 0., 0.), angl(0., 0., 0.);
 
     std::vector< RVec > testFrame1, testFrame2;
     testFrame1.resize(0);
@@ -107,7 +111,7 @@ TEST( fitTests, fitTest_CalcMid)
     std::vector< std::pair< unsigned int, unsigned int > > testPairs;
     testPairs.resize(0);
 
-    for (unsigned int i = 0; i < 27; i++) {
+    for (size_t i = 0; i < 27; i++) {
         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
         testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
         testPairs.push_back(std::make_pair(i, i));
@@ -123,17 +127,21 @@ TEST( fitTests, fitTest_CalcMid)
     ASSERT_NEAR((mid1 - mid2).norm(), 2 * std::sqrt(3), 0.000'001);
 }
 
-void myFitNewRoutine(std::vector< RVec > fr1, std::vector< RVec > fr2, std::vector< std::pair< unsigned int, unsigned int > > testPairs, double prc, double &tF) {
+void myFitNewRoutine(const std::vector< RVec > &fr1, std::vector< RVec > fr2, const std::vector< std::pair< unsigned int, unsigned int > > &testPairs, double prc, double &tF) {
     MyFitNew(fr1, fr2, testPairs, prc);
     tF = 0;
-    for (unsigned int i = 0; i < fr1.size(); i++) {
-        tF += F(fr1[i][0], fr1[i][1], fr1[i][2], fr2[i][0], fr2[i][1], fr2[i][2], 0, 0, 0);
+    DVec angl(0., 0., 0.);
+    for (size_t i = 0; i < fr1.size(); i++) {
+        tF += F(fr1[i].toDVec(), fr2[i].toDVec(), angl);
     }
 }
 
 TEST( fitTests, fitTest_MyFitNew)
 {
-    RVec a(-2, -2, -2), x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1), x2(10, 0, 0), y2(0, 10, 0), z2(0, 0, 10), x3(11, 0, 0), y3(0, 11, 0), z3(0, 0, 11);
+    RVec a(-2, -2, -2);
+    RVec x1(1, 0, 0), y1(0, 1, 0), z1(0, 0, 1);
+    RVec x2(10, 0, 0), y2(0, 10, 0), z2(0, 0, 10);
+    RVec x3(11, 0, 0), y3(0, 11, 0), z3(0, 0, 11);
 
     std::vector< RVec > testFrame1, testFrame2;
     testFrame1.resize(0);
@@ -145,7 +153,7 @@ TEST( fitTests, fitTest_MyFitNew)
      * optimal 3x3x3 cubes fitting
     */
 
-    for (unsigned int i = 0; i < 27; i++) {
+    for (size_t i = 0; i < 27; i++) {
         testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
         testFrame2.push_back(testFrame1.back() + a);
         testPairs.push_back(std::make_pair(i, i));
@@ -154,45 +162,45 @@ TEST( fitTests, fitTest_MyFitNew)
     double testF = 0;
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
-    ASSERT_NEAR(testF, 0, 0.000001);
+    ASSERT_NEAR(testF, 0, 0.000'001);
 
-    ApplyFit(testFrame2, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+    ApplyFit(testFrame2, {7.153'4, 0.559'1, -3.141'5}, {M_PI / 23, M_PI / 17, M_PI / 2.2});
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 1, testF);
-    ASSERT_NEAR(testF, 0, 8.17);
+    ASSERT_NEAR(testF, 0, 15.21);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.1, testF);
-    ASSERT_NEAR(testF, 0, 2.32);
+    ASSERT_NEAR(testF, 0, 1.483);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.01, testF);
-    ASSERT_NEAR(testF, 0, 2.13);
+    ASSERT_NEAR(testF, 0, 0.987'2);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.001, testF);
-    ASSERT_NEAR(testF, 0, 0.202);
+    ASSERT_NEAR(testF, 0, 0.196'62);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'1, testF);
-    ASSERT_NEAR(testF, 0, 0.019'6);
+    ASSERT_NEAR(testF, 0, 0.019'24);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'01, testF);
-    ASSERT_NEAR(testF, 0, 0.019'6);
+    ASSERT_NEAR(testF, 0, 0.001'917'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
-    ASSERT_NEAR(testF, 0, 0.000'194);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'1, testF);
-    ASSERT_NEAR(testF, 0, 0.000'012'05);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'01, testF);
-    ASSERT_NEAR(testF, 0, 0.000'005'182);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'001, testF);
-    ASSERT_NEAR(testF, 0, 0.000'005'095);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'1, testF);
-    ASSERT_NEAR(testF, 0, 0.000'005'034);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'01, testF);
-    ASSERT_NEAR(testF, 0, 0.000'005'345);
+    ASSERT_NEAR(testF, 0, 0.000'048'1);
 
     /*
      * different sized 3x3x3 cubes fitting
@@ -200,7 +208,7 @@ TEST( fitTests, fitTest_MyFitNew)
 
     testFrame1.resize(0);
     testFrame2.resize(0);
-    for (unsigned int i = 0; i < 27; i++) {
+    for (size_t i = 0; i < 27; i++) {
         testFrame1.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
         testFrame2.push_back(x3 * static_cast< float >(i % 3) + y3 * static_cast< float >((i % 9) / 3) + z3 * static_cast< float >(i / 9));
     }
@@ -208,43 +216,43 @@ TEST( fitTests, fitTest_MyFitNew)
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
     ASSERT_NEAR(testF, 0, 36.827);
 
-    ApplyFit(testFrame2, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+    ApplyFit(testFrame2, {7.1534, 0.5591, -3.1415}, {M_PI / 23, M_PI / 17, M_PI / 2.2});
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 1, testF);
-    ASSERT_NEAR(testF, 0, 250.7);
+    ASSERT_NEAR(testF, 0, 255.42);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.1, testF);
-    ASSERT_NEAR(testF, 0, 249.9);
+    ASSERT_NEAR(testF, 0, 255.19);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.01, testF);
-    ASSERT_NEAR(testF, 0, 79.26);
+    ASSERT_NEAR(testF, 0, 97.41);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.001, testF);
-    ASSERT_NEAR(testF, 0, 53.71);
+    ASSERT_NEAR(testF, 0, 42.55);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'1, testF);
-    ASSERT_NEAR(testF, 0, 37.13);
+    ASSERT_NEAR(testF, 0, 37.84);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'01, testF);
-    ASSERT_NEAR(testF, 0, 36.9485);
+    ASSERT_NEAR(testF, 0, 37.183);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'001, testF);
-    ASSERT_NEAR(testF, 0, 36.9482);
+    ASSERT_NEAR(testF, 0, 36.886);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'1, testF);
-    ASSERT_NEAR(testF, 0, 36.8822);
+    ASSERT_NEAR(testF, 0, 36.885'3);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'01, testF);
-    ASSERT_NEAR(testF, 0, 36.8817);
+    ASSERT_NEAR(testF, 0, 36.885'21);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'001, testF);
-    ASSERT_NEAR(testF, 0, 36.878094);
+    ASSERT_NEAR(testF, 0, 36.885'21);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'1, testF);
-    ASSERT_NEAR(testF, 0, 36.878064);
+    ASSERT_NEAR(testF, 0, 36.885'21);
 
     myFitNewRoutine(testFrame1, testFrame2, testPairs, 0.000'000'000'01, testF);
-    ASSERT_NEAR(testF, 0, 36.878062);
+    ASSERT_NEAR(testF, 0, 36.885'21);
 
 }
 
@@ -267,7 +275,7 @@ TEST( domainTests, domainTest_setDefaults)
     RVec testA, testB;
     testA[0] = 0; testA[1] = 0; testA[2] = 0;
     testB[0] = 1; testB[1] = 1; testB[2] = 1;
-    for (unsigned int i = 0; i < 100; i++) {
+    for (size_t i = 0; i < 100; i++) {
         testIndex.push_back(i);
         testRef.push_back(testA + testB * static_cast< float >(i));
     }
@@ -287,7 +295,7 @@ TEST( domainTests, domainTest_setDefaults)
     ASSERT_EQ(testDomain.structIndex, testIndex);
 
     ASSERT_EQ(testDomain.ref.size(), testRef.size());
-    for (unsigned int i = 0; i < testRef.size(); i++) {
+    for (size_t i = 0; i < testRef.size(); i++) {
         ASSERT_EQ(testDomain.ref[i][0], testRef[i][0]);
         ASSERT_EQ(testDomain.ref[i][1], testRef[i][1]);
         ASSERT_EQ(testDomain.ref[i][2], testRef[i][2]);
@@ -313,16 +321,16 @@ TEST( domainTests, domainTest_update)
     testTraj2.resize(0);
     testTraj3.resize(0);
     RVec testA(1, 2, 3), testB(1, 0, 0), testC(0, 1, 0);
-    for (unsigned int i0 = 0; i0 < 1000; i0++) {
+    for (size_t i0 = 0; i0 < 1000; i0++) {
         testTraj1.resize(testTraj1.size() + 1);
         testTraj2.resize(testTraj2.size() + 1);
         testTraj3.resize(testTraj3.size() + 1);
-        for (unsigned int i1 = 0; i1 < 10; i1++) {
+        for (size_t i1 = 0; i1 < 10; i1++) {
             testTraj1.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
             testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB);
             testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB + static_cast< float >(i0) * testC);
         }
-        for (unsigned int i1 = 0; i1 < 10; i1++) {
+        for (size_t i1 = 0; i1 < 10; i1++) {
             testTraj1.back().push_back(static_cast< float >(i1) * testA - static_cast< float >(i0) * testB);
             testTraj2.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testC);
             testTraj3.back().push_back(static_cast< float >(i1) * testA + static_cast< float >(i0) * testB - static_cast< float >(i0) * testC);
@@ -332,7 +340,7 @@ TEST( domainTests, domainTest_update)
     testIndex.resize(0);
     std::vector< RVec > testRef;
     testRef.resize(0);
-    for (unsigned int i = 0; i < 20; i++) {
+    for (size_t i = 0; i < 20; i++) {
         testIndex.push_back(i);
         testRef.push_back(static_cast< float >(i % 10) * testA);
     }
@@ -351,7 +359,7 @@ TEST( domainTests, domainTest_update)
     testDomain3.setDefaults(testIndex, testRef, testWindowSize, testDomainMinimumSize, testDomainSearchAlgorythm, testTimeStepBetweenWindows, testSliceNum, testEpsilon, testDelta, testOutPutFileName3);
 
     std::vector< std::vector< RVec > > testTemp1, testTemp2, testTemp3;
-    for (unsigned int i = 0; i < 1000; i++) {
+    for (size_t i = 0; i < 1000; i++) {
         testTemp1.resize(0);
         testTemp2.resize(0);
         testTemp3.resize(0);
@@ -392,7 +400,7 @@ TEST( domainTests, domainTest_getDomains)
     testRef.resize(0);
 
     RVec testA(0, 0, 0), testB(1, 1, 1);
-    for (unsigned int i = 0; i < 100; i++) {
+    for (size_t i = 0; i < 100; i++) {
         testIndex.push_back(i);
         testRef.push_back(testA + testB * static_cast< float >(i));
     }
@@ -410,10 +418,10 @@ TEST( domainTests, domainTest_getDomains)
 
     testDomain.graph.resize(1);
     testDomain.graph.front().resize(testSliceNum);
-    for (unsigned int i1 = 0; i1 < testSliceNum; i1++) {
-        testDomain.setGraph(testDomain.graph.front()[i1], testRef);
-        for (unsigned int i2 = 0; i2 < testIndex.size(); i2++) {
-            for (unsigned int i3 = 0; i3 < testIndex.size(); i3++) {
+    for (size_t i1 = 0; i1 < testSliceNum; i1++) {
+        testDomain.setGraph(testDomain.graph.front()[i1]);
+        for (size_t i2 = 0; i2 < testIndex.size(); i2++) {
+            for (size_t i3 = 0; i3 < testIndex.size(); i3++) {
                 testDomain.graph.front()[i1][i2][i3].num = 4;
             }
         }
@@ -421,13 +429,13 @@ TEST( domainTests, domainTest_getDomains)
     testDomain.getDomains();
     ASSERT_EQ(testDomain.domains.size(), 0);
 
-    for (unsigned int i0 = 0; i0 < 3; i0++) {
+    for (int i0 = 0; i0 < 3; i0++) {
         testDomain.graph.resize(1);
         testDomain.graph.front().resize(testSliceNum);
-        for (unsigned int i1 = 0; i1 < testSliceNum; i1++) {
-            testDomain.setGraph(testDomain.graph.front()[i1], testRef);
-            for (unsigned int i2 = 0; i2 < testIndex.size(); i2++) {
-                for (unsigned int i3 = 0; i3 < testIndex.size(); i3++) {
+        for (size_t i1 = 0; i1 < testSliceNum; i1++) {
+            testDomain.setGraph(testDomain.graph.front()[i1]);
+            for (size_t i2 = 0; i2 < testIndex.size(); i2++) {
+                for (size_t i3 = 0; i3 < testIndex.size(); i3++) {
                     testDomain.graph.front()[i1][i2][i3].num = 100;
                 }
             }
index 9659d70a306b72b4492f9e158eb96393c5a44d32..535c75652fe81c9b076da9be185e0992689287f2 100644 (file)
@@ -7,7 +7,7 @@ domainType::~domainType() {}
 domainType::domainType() {}
 
 // конструктор класса для полноценной инициализации данных
-domainType::domainType(std::vector< unsigned long > index, const std::vector< RVec > reference,
+domainType::domainType(const std::vector< unsigned long > &index, const std::vector< RVec > &reference,
                     const int windowSize, const int domainMinimumSize,
                     const int domainSearchAlgorythm, const int timeStepBetweenWindowStarts,
                     const unsigned int sliceNum, const double epsilon, const double delta,
@@ -17,7 +17,7 @@ domainType::domainType(std::vector< unsigned long > index, const std::vector< RV
 
 // set numeric values to "-1" / string value to "" - if you want default settings
 // функция заполнения необходимыми данными для вычисления структурных доменов
-void domainType::setDefaults(std::vector< unsigned long > index, const std::vector< RVec > reference,
+void domainType::setDefaults(const std::vector< unsigned long > &index, const std::vector< RVec > &reference,
                         const int windowSize, const int domainMinimumSize,
                         const int domainSearchAlgorythm, const int timeStepBetweenWindows,
                         const unsigned int sliceNum, const double epsilon, const double delta,
@@ -39,27 +39,27 @@ void domainType::setDefaults(std::vector< unsigned long > index, const std::vect
 }
 
 // фукнция обновления данных для выделения структурных доменов
-void domainType::update(const std::vector< std::vector< RVec > > frame, const int frameNumber) {
+void domainType::update(const std::vector< std::vector< RVec > > &frame, const int frameNumber) {
     // громакс считает с нуля, проверял; инициализируем новое "окно"
     if ((frameNumber + 1) % ts == 1) {
         graph.resize(graph.size() + 1);
         graph.back().resize(structIndex.size() - static_cast< unsigned long >(dms) + 1);
-        for (unsigned i = 0; i < graph.front().size(); i++) {
-            setGraph(graph.back()[i], ref);
+        for (size_t i = 0; i < graph.front().size(); i++) {
+            setGraph(graph.back()[i]);
         }
     }
     // заполняем структуру данных для структурных доменов
-    for (unsigned int i = 0; i < graph.size(); i++) {
+    for (size_t i = 0; i < graph.size(); i++) {
         #pragma omp parallel for
-        for (unsigned long j = 0; j < graph.front().size(); j++) {
-            for (unsigned int k1 = 0; k1 < graph[i][j].size(); k1++) {
-                for (unsigned int k2 = k1; k2 < graph[i][j].size(); k2++) {
+        for (size_t j = 0; j < graph.front().size(); j++) {
+            for (size_t k1 = 0; k1 < graph[i][j].size(); k1++) {
+                for (size_t k2 = k1; k2 < graph[i][j].size(); k2++) {
                     if ((frame[j][k1] - frame[j][k2] - graph[i][j][k1][k2].radius).norm() <= static_cast< float >(eps)) {
-                        if (k1 == k2) {
+                        if (k1 != k2) {
                             graph[i][j][k1][k2].num++;
+                            graph[i][j][k2][k1].num++;
                         } else {
                             graph[i][j][k1][k2].num++;
-                            graph[i][j][k2][k1].num++;
                         }
                     }
                 }
@@ -79,27 +79,27 @@ void domainType::update(const std::vector< std::vector< RVec > > frame, const in
 }
 
 // инициализация матриц соотношений в структуре
-void domainType::setGraph(std::vector< std::vector< triple > > &smallGraph, const std::vector< RVec > reference) {
+void domainType::setGraph(std::vector< std::vector< triple > > &smallGraph) {
     smallGraph.resize(0);
-    smallGraph.resize(reference.size());
-    for (unsigned i = 0; i < reference.size(); i++) {
+    smallGraph.resize(ref.size());
+    for (size_t i = 0; i < ref.size(); i++) {
         smallGraph[i].resize(0);
-        smallGraph[i].resize(reference.size());
-        for (unsigned j = 0; j < reference.size(); j++) {
+        smallGraph[i].resize(ref.size());
+        for (size_t j = 0; j < ref.size(); j++) {
             smallGraph[i][j].num = 0;
-            smallGraph[i][j].radius = reference[i] - reference[j];
+            smallGraph[i][j].radius = ref[i] - ref[j];
             smallGraph[i][j].check = false;
         }
     }
 }
 
 // "зануление" элементов матриц вошедших в домен
-void domainType::deleteDomainFromGraph(std::vector< unsigned int > domain) {
-    for (unsigned int i = 0; i < graph.front().size(); i++) {
-        for (unsigned int j = 0; j < domain.size(); j++) {
-            for (unsigned int k = 0; k < graph.front()[i].size(); k++) {
-                graph.front()[i][domain[j]][k].check = false;
-                graph.front()[i][k][domain[j]].check = false;
+void domainType::deleteDomainFromGraph(const std::vector< unsigned int > &domain) {
+    for (auto &i : graph.front()) {
+        for (size_t j = 0; j < domain.size(); j++) {
+            for (size_t k = 0; k < i.size(); k++) {
+                i[domain[j]][k].check = false;
+                i[k][domain[j]].check = false;
             }
         }
     }
@@ -110,12 +110,12 @@ void domainType::deleteDomainFromGraph(std::vector< unsigned int > domain) {
     bool flag = false;
     domsizes.resize(0);
     domsizes.resize(graph.front().size());
-    for (unsigned int i = 0; i < graph.front().size(); i++) {
-        domsizes[i].resize(0); // ��азалось бы следующая строчка должна работать, но без этой выходит шляпа
+    for (size_t i = 0; i < graph.front().size(); i++) {
+        domsizes[i].resize(0); // ��еобходимо переопределять память
         domsizes[i].resize(graph.front()[i].size(), 0);
-        for (unsigned int j = 0; j < graph.front()[i].size(); j++) {
-            for (unsigned int k = 0; k < graph.front()[i][j].size(); k++) {
-                if (graph.front()[i][j][k].check) {
+        for (size_t j = 0; j < graph.front()[i].size(); j++) {
+            for (const auto &k : graph.front()[i][j]) {
+                if (k.check) {
                     domsizes[i][j]++;
                 }   
             }
@@ -130,11 +130,11 @@ void domainType::deleteDomainFromGraph(std::vector< unsigned int > domain) {
 // функция выделения доменов
 void domainType::getDomains() {
     // проверка элементов матриц на создание на их основе доменов
-    for (unsigned int i = 0; i < graph.front().size(); i++) {
-        for (unsigned int j = 0; j < graph.front()[i].size(); j++) {
-            for (unsigned int k = 0; k < graph.front()[i].size(); k++) {
-                if (graph.front()[i][j][k].num >= window * dlt) {
-                    graph.front()[i][j][k].check = true;
+    for (auto &i : graph.front()) {
+        for (auto &j : i) {         //  -> матрица соотношений в структуре всё на всё
+            for (auto &k : j) {     //  -> матрица соотношений в структуре всё на всё
+                if (k.num >= window * dlt) {
+                    k.check = true;
                 }
             }
         }
@@ -143,9 +143,9 @@ void domainType::getDomains() {
     // итеративное выделение доменов одним из двух(пока что) способов
     // в случае если цикл запустился, то гарантированно имеется домен для выделения
     while (searchDomainSizes()) {
-        unsigned int t1 = 0, t2 = 0;
-        for (unsigned int i = 0; i < domsizes.size(); i++) {
-            for (unsigned int j = 0; j < domsizes[i].size(); j++) {
+        size_t t1 = 0, t2 = 0;
+        for (size_t i = 0; i < domsizes.size(); i++) {
+            for (size_t j = 0; j < domsizes[i].size(); j++) {
                 if ((dsa == 0) && (domsizes[i][j] > domsizes[t1][t2])) {
                     // из-за физических ограничений по памяти в общем случае нельзя хранить всю подноготную данных на
                     // основе которых было полученно "вхождение" атомов в домен, потому мы только знаем, что размер
@@ -161,10 +161,9 @@ void domainType::getDomains() {
         }
         // выделяем найдённый домен
         domains.resize(domains.size() + 1);
-        for (unsigned int i = 0; i < graph.front()[t1][t2].size(); i++) {
+        for (size_t i = 0; i < graph.front()[t1][t2].size(); i++) {
             if (graph.front()[t1][t2][i].check) {
                 domains.back().push_back(i);
-
             }
         }
         //выход из поиска доменов при данном режиме обработки
@@ -189,14 +188,14 @@ void domainType::print(int currentFrame) {
     ndxFile = std::fopen(outPut.c_str(), "a+");
     slFile  = std::fopen(("selectionList-" + outPut.substr(0, outPut.size() - 4)).c_str(), "a+");
     int writeCount;
-    for (unsigned int i = 0; i < domains.size(); i++) {
+    for (size_t i = 0; i < domains.size(); i++) {
         // domain - стартовая позиция в фреймах - номер домена - минимальный размер домена -
         // константа тепловых колебаний (отклонения) - константа входимости (отклонения)
-        std::fprintf(ndxFile, "[domain-stPos-%06d-num-%03d-dms-%03d-epsi-%04.3f-delta-%04.3f]\n", currentFrame - window + 1, i + 1, dms, eps, dlt);
-        std::fprintf(slFile, "group %cdomain-stPos-%06d-num-%03d-dms-%03d-epsi-%04.3f-delta-%04.3f%c;\n", '"', currentFrame - window + 1, i + 1, dms, eps, dlt, '"');
+        std::fprintf(ndxFile, "[domain-stPos-%06d-num-%03lud-dms-%03d-epsi-%04.3f-delta-%04.3f]\n", currentFrame - window + 1, i + 1, dms, eps, dlt);
+        std::fprintf(slFile, "group %cdomain-stPos-%06d-num-%03lud-dms-%03d-epsi-%04.3f-delta-%04.3f%c;\n", '"', currentFrame - window + 1, i + 1, dms, eps, dlt, '"');
         writeCount = 0;
         std::printf("\n");
-        for (unsigned int j = 0; j < domains[i].size(); j++) {
+        for (size_t j = 0; j < domains[i].size(); j++) {
             writeCount++;
             if (writeCount > 20) {
                 writeCount -= 20;
index e041095dc1f36e52bafd49480ffa95856dfd2a21..45bf279c918f9b9255e5a29485b751168b0e1798 100644 (file)
@@ -25,7 +25,7 @@ class domainType {
         domainType();
 
         // конструктор класса для полноценной инициализации данных
-        domainType(std::vector< unsigned long > index, const std::vector< RVec > reference,
+        domainType(const std::vector< unsigned long > &index, const std::vector< RVec > &reference,
                     const int windowSize, const int domainMinimumSize,
                     const int domainSearchAlgorythm, const int timeStepBetweenWindowStarts,
                     const unsigned int sliceNum, const double epsilon, const double delta,
@@ -33,14 +33,14 @@ class domainType {
 
         // set numeric values to "-1" / string value to "" - if you want default settings
         // функция заполнения необходимыми данными для вычисления структурных доменов
-        void setDefaults(std::vector< unsigned long > index, const std::vector< RVec > reference,
+        void setDefaults(const std::vector< unsigned long > &index, const std::vector< RVec > &reference,
                         const int windowSize, const int domainMinimumSize,
                         const int domainSearchAlgorythm, const int timeStepBetweenWindows,
                         const unsigned int sliceNum, const double epsilon, const double delta,
                         const std::string outPutFileName);
 
         // фукнция обновления данных для выделения структурных доменов
-        void update(const std::vector< std::vector< RVec > > frame, const int frameNumber);
+        void update(const std::vector< std::vector< RVec > > &frame, const int frameNumber);
 
     private:
 
@@ -70,27 +70,27 @@ class domainType {
         // размеры доменов для каждой основной последовательности
         std::vector< std::vector< int > >                                       domsizes;
         // размер рассматриваемого окна в последовательных фреймах траектории
-        int                                                                     window      = 1000;             // selectable
+        int                                                                     window      {1000};             // selectable
         // счётчик эффективных последовательных обновлений структуры graph
-        int                                                                     updateCount = 0;
+        int                                                                     updateCount {0};
         // минимальный рассматриваемый размер домена - осмысленно брать 4+
-        int                                                                     dms         = 4;                // selectable
+        int                                                                     dms         {4};                // selectable
         // какой из алгоритмов выделения использовать 0 - от максимального домена к меньшим / 1 - самый большой домен (первый из равных) / 2 - от минимального домена к большим
-        int                                                                     dsa         = 0;                // selectable
+        int                                                                     dsa         {0};                // selectable
         // константа допустимых тепловых колебаний  относительно центра домена, находящегося в конкретном атоме структуры
-        double                                                                  eps         = 0.2;              // selectable
+        double                                                                  eps         {0.2};              // selectable
         // константа допустимой входимости атома в выделяемый домен, призвана сгладить резкую границу константы eps
-        double                                                                  dlt         = 0.95;             // selectable
+        double                                                                  dlt         {0.95};             // selectable
         // шаг между началами рассматриваемых окон на траектории в фреймах
-        int                                                                     ts          = window / 10;      // selectable
+        int                                                                     ts          {window / 10};      // selectable
         // название выходного файла для записи доменов, так же происходит создание selectionList для выделенных доменов
         std::string                                                             outPut      = "default.ndx";    // selectable
 
         // инициализация матриц соотношений в структуре
-        void setGraph(std::vector< std::vector< triple > > &smallGraph, const std::vector< RVec > reference);
+        void setGraph(std::vector< std::vector< triple > > &smallGraph);
 
         // "зануление" элементов матриц вошедших в домен
-        void deleteDomainFromGraph(std::vector< unsigned int > domain);
+        void deleteDomainFromGraph(const std::vector< unsigned int > &domain);
 
         // подсчёт размеров всех потенциально возможных доменов и проверка на наличие домена для выделения
         bool searchDomainSizes();
index e2db78b9366f995de9d80756e5fe5000b5bc4494..ea2be0e8d4fc6a3b1b97606e8572cd04e98a33db 100644 (file)
@@ -3,34 +3,36 @@
 // вычисление модуля расстояния между двумя точками, с учётом геометрического преобразования
 //
 // Казалось бы лучше связанные тройки векторами... =) это и к тому что ниже относится
-double F (double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C) {
-    return  sqrt(   pow(aix + biy_plus_y * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) - biz_plus_z * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - cos(B) * cos(C) * bix_plus_x, 2) +
-                    pow(aiy - biy_plus_y * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) + biz_plus_z * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) - cos(B) * sin(C) * bix_plus_x, 2) +
-                    pow(aiz + sin(B) * bix_plus_x - cos(A) * cos(B) * biz_plus_z - cos(B) * sin(A) * biy_plus_y, 2)  );
+double F (const DVec &ai, const DVec &biR, const DVec &angl) {
+    const double cosA {cos(angl[0])}, cosB {cos(angl[1])}, cosC {cos(angl[2])}, sinA {sin(angl[0])}, sinB {sin(angl[1])}, sinC {sin(angl[2])};
+    return  sqrt(   pow(ai[0] + biR[1] * (cosA * sinC - cosC * sinA * sinB) - biR[2] * (sinA * sinC + cosA * cosC * sinB) - cosB * cosC * biR[0], 2) +
+                    pow(ai[1] - biR[1] * (cosA * cosC + sinA * sinB * sinC) + biR[2] * (cosC * sinA - cosA * sinB * sinC) - cosB * sinC * biR[0], 2) +
+                    pow(ai[2] + sinB * biR[0] - cosA * cosB * biR[2] - cosB * sinA * biR[1], 2)  );
 }
 
 // вычисление функции F и её частных производных
-void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C) {
+void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, const RVec &ai, const RVec &biR, const DVec &angl) {
+    const double cosA {cos(angl[0])}, cosB {cos(angl[1])}, cosC {cos(angl[2])}, sinA {sin(angl[0])}, sinB {sin(angl[1])}, sinC {sin(angl[2])};
     double t01, t02, t03, t04, t05, t06, t07;
-    t01 = pow(aix + biy_plus_y * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) - biz_plus_z * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - cos(B) * cos(C) * bix_plus_x, 2);
-    t02 = pow(aiy - biy_plus_y * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) + biz_plus_z * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) - cos(B) * sin(C) * bix_plus_x, 2);
-    t03 = pow(aiz + sin(B) * bix_plus_x - cos(A) * cos(B) * biz_plus_z - cos(B) * sin(A) * biy_plus_y, 2);
+    t01 = pow(ai[0] + biR[1] * (cosA * sinC - cosC * sinA * sinB) - biR[2] * (sinA * sinC + cosA * cosC * sinB) - cosB * cosC * biR[0], 2);
+    t02 = pow(ai[1] - biR[1] * (cosA * cosC + sinA * sinB * sinC) + biR[2] * (cosC * sinA - cosA * sinB * sinC) - cosB * sinC * biR[0], 2);
+    t03 = pow(ai[2] + sinB * biR[0] - cosA * cosB * biR[2] - cosB * sinA * biR[1], 2);
     t04 = sqrt(t01 + t02 + t03);
-    t05 = (aix + biy_plus_y * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) - biz_plus_z * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - cos(B) * cos(C) * bix_plus_x);
-    t06 = (aiz + sin(B) * bix_plus_x - cos(A) * cos(B) * biz_plus_z - cos(B) * sin(A) * biy_plus_y);
-    t07 = (aiy - biy_plus_y * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) + biz_plus_z * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) - cos(B) * sin(C) * bix_plus_x);
+    t05 = (ai[0] + biR[1] * (cosA * sinC - cosC * sinA * sinB) - biR[2] * (sinA * sinC + cosA * cosC * sinB) - cosB * cosC * biR[0]);
+    t06 = (ai[2] + sinB * biR[0] - cosA * cosB * biR[2] - cosB * sinA * biR[1]);
+    t07 = (ai[1] - biR[1] * (cosA * cosC + sinA * sinB * sinC) + biR[2] * (cosC * sinA - cosA * sinB * sinC) - cosB * sinC * biR[0]);
     F += t04;
-    Fx += -(2 * cos(B) * cos(C) * t05 - 2 * sin(B) * t06 + 2 * cos(B) * sin(C) * t07) / (2 * t04);
-    Fy += -(2 * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) * t07 - 2 * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) * t05 + 2 * cos(B) * sin(A) * t06) / (2 * t04);
-    Fz += -(2 * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) * t05 - 2 * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) * t07 + 2 * cos(A) * cos(B) * t06) / (2 * t04);
-    Fa += -(2 * (cos(A) * cos(B) * biy_plus_y - cos(B) * sin(A) * biz_plus_z) * t06 -
-            2 * (biy_plus_y * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) + biz_plus_z * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C))) * t07 +
-            2 * (biy_plus_y * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) + biz_plus_z * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B))) * t05) / (2 * t04);
-    Fb += -(2 * (cos(A) * cos(B) * sin(C) * biz_plus_z - sin(B) * sin(C) * bix_plus_x + cos(B) * sin(A) * sin(C) * biy_plus_y) * t07 +
-            2 * (cos(A) * cos(B) * cos(C) * biz_plus_z - cos(C) * sin(B) * bix_plus_x + cos(B) * cos(C) * sin(A) * biy_plus_y) * t05 -
-            2 * (cos(B) * bix_plus_x + sin(A) * sin(B) * biy_plus_y + cos(A) * sin(B) * biz_plus_z) * t06) / (2 * t04);
-    Fc += (2 * (biy_plus_y * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) - biz_plus_z * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) + cos(B) * sin(C) * bix_plus_x) * t05 -
-            2 * (biz_plus_z * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - biy_plus_y * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) + cos(B) * cos(C) * bix_plus_x) * t07) / (2 * t04);
+    Fx += -(2 * cosB * cosC * t05 - 2 * sinB * t06 + 2 * cosB * sinC * t07) / (2 * t04);
+    Fy += -(2 * (cosA * cosC + sinA * sinB * sinC) * t07 - 2 * (cosA * sinC - cosC * sinA * sinB) * t05 + 2 * cosB * sinA * t06) / (2 * t04);
+    Fz += -(2 * (sinA * sinC + cosA * cosC * sinB) * t05 - 2 * (cosC * sinA - cosA * sinB * sinC) * t07 + 2 * cosA * cosB * t06) / (2 * t04);
+    Fa += -(2 * (cosA * cosB * biR[1] - cosB * sinA * biR[2]) * t06 -
+            2 * (biR[1] * (cosC * sinA - cosA * sinB * sinC) + biR[2] * (cosA * cosC + sinA * sinB * sinC)) * t07 +
+            2 * (biR[1] * (sinA * sinC + cosA * cosC * sinB) + biR[2] * (cosA * sinC - cosC * sinA * sinB)) * t05) / (2 * t04);
+    Fb += -(2 * (cosA * cosB * sinC * biR[2] - sinB * sinC * biR[0] + cosB * sinA * sinC * biR[1]) * t07 +
+            2 * (cosA * cosB * cosC * biR[2] - cosC * sinB * biR[0] + cosB * cosC * sinA * biR[1]) * t05 -
+            2 * (cosB * biR[0] + sinA * sinB * biR[1] + cosA * sinB * biR[2]) * t06) / (2 * t04);
+    Fc += (2 * (biR[1] * (cosA * cosC + sinA * sinB * sinC) - biR[2] * (cosC * sinA - cosA * sinB * sinC) + cosB * sinC * biR[0]) * t05 -
+            2 * (biR[2] * (sinA * sinC + cosA * cosC * sinB) - biR[1] * (cosA * sinC - cosC * sinA * sinB) + cosB * cosC * biR[0]) * t07) / (2 * t04);
     if (std::isnan(F)) {
         F = 0;
     }
@@ -57,31 +59,22 @@ void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double
 // применения геометрического преобразования: смещение на вектор (x, y, z) и повороты на градусы A, B, C относительно осей (x, y, z)
 //
 // А порядок поворотов какой?
-void ApplyFit (std::vector< RVec > &b, double x, double y, double z, double A, double B, double C) {
-    double t0 = 0, t1 = 0, t2 = 0;
-    for (unsigned int i = 0; i < b.size(); i++) {
-        t0 = static_cast< double >(b[i][0]);
-        t1 = static_cast< double >(b[i][1]);
-        t2 = static_cast< double >(b[i][2]);
-        b[i][0] = static_cast< float >((t2 + z) * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - (t1 + y) * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) + cos(B) * cos(C) * (t0 + x));
-        b[i][1] = static_cast< float >((t1 + y) * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) - (t2 + z) * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) + cos(B) * sin(C) * (t0 + x));
-        b[i][2] = static_cast< float >(cos(A) * cos(B) * (t2 + z) - sin(B) * (t0 + x) + cos(B) * sin(A) * (t1 + y));
+void ApplyFit (std::vector< RVec > &b, const DVec &R, const DVec &angl) {
+    DVec t(0., 0., 0.);
+    const double cosA {cos(angl[0])}, cosB {cos(angl[1])}, cosC {cos(angl[2])}, sinA {sin(angl[0])}, sinB {sin(angl[1])}, sinC {sin(angl[2])};
+    for (auto &i : b) {
+        t = i.toDVec();
+        i[0] = static_cast< float >((t[2] + R[2]) * (sinA * sinC + cosA * cosC * sinB) - (t[1] + R[1]) * (cosA * sinC - cosC * sinA * sinB) + cosB * cosC * (t[0] + R[0]));
+        i[1] = static_cast< float >((t[1] + R[1]) * (cosA * cosC + sinA * sinB * sinC) - (t[2] + R[2]) * (cosC * sinA - cosA * sinB * sinC) + cosB * sinC * (t[0] + R[0]));
+        i[2] = static_cast< float >(cosA * cosB * (t[2] + R[2]) - sinB * (t[0] + R[0]) + cosB * sinA * (t[1] + R[1]));
     }
 }
 
 // подсчёт геометрических центров множеств a и b на основе пар pairs
-void CalcMid (std::vector< RVec > a, std::vector< RVec > b, RVec &midA, RVec &midB, std::vector< std::pair< unsigned int, unsigned int > > pairs) {
-    midA[0] = 0;
-    midA[1] = 0;
-    midA[2] = 0;
-
-    midB[0] = 0;
-    midB[1] = 0;
-    midB[2] = 0;
-
-    for (unsigned int i = 0; i < pairs.size(); i++) {
-        midA += a[pairs[i].first];
-        midB += b[pairs[i].second];
+void CalcMid (const std::vector< RVec > &a, const std::vector< RVec > &b, DVec &midA, DVec &midB, const std::vector< std::pair< unsigned int, unsigned int > > &pairs) {
+    for (const auto &i : pairs) {
+        midA += a[i.first].toDVec();
+        midB += b[i.second].toDVec();
     }
     midA[0] /= pairs.size();
     midA[1] /= pairs.size();
@@ -93,51 +86,51 @@ void CalcMid (std::vector< RVec > a, std::vector< RVec > b, RVec &midA, RVec &mi
 }
 
 // функция фитирования фрейма b на фрейм a на основе пар pairs с "точностью" FtCnst
-void MyFitNew (std::vector< RVec > a, std::vector< RVec > &b, std::vector< std::pair< unsigned int, unsigned int > > pairs, long double FtCnst) {
-    double fx = 0, fy = 0, fz = 0, fa = 0, fb = 0, fc = 0;
-    long double f1 = 0, f2 = 0, l = 1;
-    RVec ma, mb;
-    CalcMid(a, b, ma, mb, pairs);
-    ma -= mb;
-    double x = static_cast< double >(ma[0]), y = static_cast< double >(ma[1]), z = static_cast< double >(ma[2]), A = 0, B = 0, C = 0;
+void MyFitNew (const std::vector< RVec > &a, std::vector< RVec > &b, const std::vector< std::pair< unsigned int, unsigned int > > &pairs, long double FtCnst) {
+    double fx {0.}, fy {0.}, fz {0.}, fa {0.}, fb {0.}, fc {0.};
+    long double f1 {0.}, f2 {0.}, l {1};
+    DVec tempA(0., 0., 0.), tempB(0., 0., 0.), tempC(0., 0., 0.), tempD(0., 0., 0.);
+    CalcMid(a, b, tempA, tempB, pairs);
+    tempA -= tempB;
     // поиск стартового отклонения множеств
-    for (unsigned int i = 0; i < pairs.size(); i++) {
-        f1 += F(static_cast< double >(a[pairs[i].first][0]), static_cast< double >(a[pairs[i].first][1]), static_cast< double >(a[pairs[i].first][2]),
-                static_cast< double >(b[pairs[i].second][0]) + x, static_cast< double >(b[pairs[i].second][1]) + y, static_cast< double >(b[pairs[i].second][2]) + z, A, B, C);
+    for (const auto &i : pairs) {
+        f1 += F(a[i.first].toDVec(), b[i.second].toDVec() + tempA, tempC);
     }
     if (FtCnst == 0) {
-        FtCnst = 0.000001; // почему именно столько?!
+        FtCnst = 0.000'001; // почему именно столько?!
     }
     if (f1 == 0) {
-        ApplyFit(b, x, y, z, A, B, C);
+        ApplyFit(b, tempA, tempC);
         return;
     } else {
         // поиск оптимального геометрического преобразования методом градиентного спуска
         while (f1 < f2  || f1 - f2 > FtCnst) {
-            f1 = 0; f2 = 0; fx = 0; fy = 0; fz = 0; fa = 0; fb = 0; fc = 0; l = 1;
+            f1 = 0.; f2 = 0.; fx = 0.; fy = 0.; fz = 0.; fa = 0.; fb = 0.; fc = 0.; l = 1;
             // поиск производных и отклонения при заданных параметрах
-            for (unsigned int i = 0; i < pairs.size(); i++) {
-                searchF0xyzabc(f1, fx, fy, fz, fa, fb, fc,
-                               static_cast< double >(a[pairs[i].first][0]), static_cast< double >(a[pairs[i].first][1]), static_cast< double >(a[pairs[i].first][2]),
-                               static_cast< double >(b[pairs[i].second][0]) + x, static_cast< double >(b[pairs[i].second][1]) + y,
-                               static_cast< double >(b[pairs[i].second][2]) + z, A, B, C);
+            for (const auto &i : pairs) {
+                searchF0xyzabc(f1, fx, fy, fz, fa, fb, fc, a[i.first], b[i.second] + tempA.toRVec(), tempC);
             }
             while (true) {
                 f2 = 0;
                 // поиск отклонения при новых параметрах
-                for (unsigned int i = 0; i < pairs.size(); i++) {
-                    f2 += F(static_cast< double >(a[pairs[i].first][0]), static_cast< double >(a[pairs[i].first][1]), static_cast< double >(a[pairs[i].first][2]),
-                            static_cast< double >(b[pairs[i].second][0]) + (x - l * fx), static_cast< double >(b[pairs[i].second][1]) + (y - l * fy),
-                            static_cast< double >(b[pairs[i].second][2]) + (z - l * fz), A - l * fa, B - l * fb, C - l * fc);
+                tempB[0] = tempA[0] - l * fx;
+                tempB[1] = tempA[1] - l * fy;
+                tempB[2] = tempA[2] - l * fz;
+                tempD[0] = tempC[0] - l * fa;
+                tempD[1] = tempC[1] - l * fb;
+                tempD[2] = tempC[2] - l * fc;
+                for (const auto &i : pairs) {
+                    f2 += F(a[i.first].toDVec(), b[i.second].toDVec() + tempB, tempD);
                 }
                 if (f2 < f1) {
-                    x -= l * fx; y -= l * fy; z -= l * fz; A -= l * fa; B -= l * fb; C -= l * fc;
+                    tempA = tempB;
+                    tempC = tempD;
                     break;
                 } else {
                     // по факту существует минимальное значение переменной типа double
                     // в случае его достижения дважды останавливаем цикл т.к. упёрлись в предел допустимой точности
                     // таким образом гарантируем выход из цикла
-                    if (l == DBL_MIN) { //DBL_TRUE_MIN
+                    if (l == DBL_MIN || l == 0.) { //DBL_TRUE_MIN
                         f2 = f1;
                         break;
                     }
@@ -145,6 +138,6 @@ void MyFitNew (std::vector< RVec > a, std::vector< RVec > &b, std::vector< std::
                 }
             }
         }
-        ApplyFit(b, x, y, z, A, B, C);
+        ApplyFit(b, tempA, tempC);
     }
 }
index 25beae1a7ed35329b5d008fa34080316344dd9ff..f03a591f77723512cd600d1b142fe782b992d01f 100644 (file)
 #include <cstdio>
 
 using gmx::RVec;
+using gmx::DVec;
 using namespace gmx;
 
 // вычисление модуля расстояния между двумя точками, с учётом геометрического преобразования
-double F (double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C);
+double F (const DVec &ai, const DVec &bi_plusR, const DVec &angl);
 
 // вычисление функции F и её частных производных
-void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C);
+void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, const RVec &ai, const RVec &biR, const DVec &angl);
 
 // применения геометрического преобразования: смещение на вектор (x, y, z) и повороты на градусы A, B, C относительно осей (x, y, z)
-void ApplyFit (std::vector< RVec > &b, double x, double y, double z, double A, double B, double C);
+void ApplyFit (std::vector< RVec > &b, const DVec &R, const DVec &angl);
 
 // подсчёт геометрических центров множеств a и b на основе пар pairs
-void CalcMid (std::vector< RVec > a, std::vector< RVec > b, RVec &midA, RVec &midB, std::vector< std::pair< unsigned int, unsigned int > > pairs);
+void CalcMid (const std::vector< RVec > &a, const std::vector< RVec > &b, DVec &midA, DVec &midB, const std::vector< std::pair< unsigned int, unsigned int > > &pairs);
 
 // функция фитирования фрейма b на фрейм a на основе пар pairs с "точностью" FtCnst
-void MyFitNew (std::vector< RVec > a, std::vector< RVec > &b, std::vector< std::pair< unsigned int, unsigned int > > pairs, long double FtCnst);
+void MyFitNew (const std::vector< RVec > &a, std::vector< RVec > &b, const std::vector< std::pair< unsigned int, unsigned int > > &pairs, long double FtCnst);
 
 #endif // NEWFIT_H