added missing header file
[alexxy/gromacs-rcore.git] / include / newfit.h
1 #ifndef NEWFIT_H
2 #define NEWFIT_H
3
4 #include "gromacs/math/vectypes.h"
5 #include "vector"
6
7 using gmx::RVec;
8
9 namespace NewFit {
10
11     void implement_fit(std::vector< RVec > &if_frame, RVec if_step, double if_A, double if_B, double if_C) {
12         for (int i = 0; i < if_frame.size(); i++) {
13             if_frame[i] += if_step;
14         }
15         for (int i = 0; i < if_frame.size(); i++) {
16             if_step[0] = if_frame[i][0];
17             if_step[1] = if_frame[i][1];
18             if_step[2] = if_frame[i][2];
19             if_frame[i][1] = if_step[1] * cos(if_A) - if_step[2] * sin(if_A);
20             if_frame[i][2] = if_step[1] * sin(if_A) + if_step[2] * cos(if_A);
21         }
22         for (int i = 0; i < if_frame.size(); i++) {
23             if_step[0] = if_frame[i][0];
24             if_step[1] = if_frame[i][1];
25             if_step[2] = if_frame[i][2];
26             if_frame[i][0] = if_step[0] * cos(if_B) + if_step[2] * sin(if_B);
27             if_frame[i][2] = - if_step[0] * sin(if_B) + if_step[2] * cos(if_B);
28         }
29         for (int i = 0; i < if_frame.size(); i++) {
30             if_step[0] = if_frame[i][0];
31             if_step[1] = if_frame[i][1];
32             if_step[2] = if_frame[i][2];
33             if_frame[i][0] = if_step[0] * cos(if_C) - if_step[1] * sin(if_C);
34             if_frame[i][1] = if_step[0] * sin(if_C) + if_step[1] * cos(if_C);
35         }
36     }
37
38     double F(double aix, double aiy, double aiz, double bix, double biy, double biz, double cA, double sA, double cB, double sB, double cC, double sC) {
39         return  gmx::square(aix + biy*(cA*sC - cC*sA*sB) - biz*(sA*sC + cA*cC*sB) - cB*cC*bix) +
40                 gmx::square(aiy - biy*(cA*cC + sA*sB*sC) + biz*(cC*sA - cA*sB*sC) - cB*sC*bix) +
41                 gmx::square(aiz + sB*bix - cA*cB*biz - cB*sA*biy) ;
42     }
43
44     double Fx(double temp1, double temp2, double temp3, double cB, double sB, double cC, double sC) {
45         return 2*sB*temp3 -
46                2*cB*cC*temp1 -
47                2*cB*sC*temp2 ;
48     }
49
50     double Fy(double temp1, double temp2, double temp3, double cA, double sA, double cB, double sB, double cC, double sC) {
51         return 2*(cA*sC - cC*sA*sB)*temp1 -
52                2*(cA*cC + sA*sB*sC)*temp2 -
53                2*cB*sA*temp3 ;
54     }
55
56     double Fz(double temp1, double temp2, double temp3, double cA, double sA, double cB, double sB, double cC, double sC) {
57         return 2*(cC*sA - cA*sB*sC)*temp2 -
58                2*(sA*sC + cA*cC*sB)*temp1 -
59                2*cA*cB*temp3 ;
60     }
61
62     double FA(double temp1, double temp2, double temp3, double biy_pl_y, double biz_pl_z, double cA, double sA, double cB, double sB, double cC, double sC) {
63         return 2*(biy_pl_y*(cC*sA - cA*sB*sC) + biz_pl_z*(cA*cC + sA*sB*sC))*temp2 -
64                2*(cA*cB*biy_pl_y - cB*sA*biz_pl_z)*temp3 -
65                2*(biy_pl_y*(sA*sC + cA*cC*sB) + biz_pl_z*(cA*sC - cC*sA*sB))*temp1 ;
66     }
67
68     double FB(double temp1, double temp2, double temp3, double bix_pl_x, double biy_pl_y, double biz_pl_z, double cA, double sA, double cB, double sB, double cC, double sC) {
69         return 2*(cB*bix_pl_x + sA*sB*biy_pl_y + cA*sB*biz_pl_z)*temp3 -
70                2*(cA*cB*cC*biz_pl_z - cC*sB*bix_pl_x + cB*cC*sA*biy_pl_y)*temp1 -
71                2*(cA*cB*sC*biz_pl_z - sB*sC*bix_pl_x + cB*sA*sC*biy_pl_y)*temp2 ;
72     }
73
74     double FC(double temp1, double temp2, double bix_pl_x, double biy_pl_y, double biz_pl_z, double cA, double sA, double cB, double sB, double cC, double sC) {
75         return 2*(biy_pl_y*(cA*cC + sA*sB*sC) - biz_pl_z*(cC*sA - cA*sB*sC) + cB*sC*bix_pl_x)*temp1 -
76                2*(biz_pl_z*(sA*sC + cA*cC*sB) - biy_pl_y*(cA*sC - cC*sA*sB) + cB*cC*bix_pl_x)*temp2 ;
77     }
78
79     double dist(std::vector< RVec > alfa, std::vector< RVec > beta, std::vector< std::pair< int, int > > cros) {
80         double distance = 0;
81         for (int i = 0; i < cros.size(); i++) {
82             distance += F(alfa[cros[i].first][0], alfa[cros[i].first][1], alfa[cros[i].first][2], beta[cros[i].second][0], beta[cros[i].second][1], beta[cros[i].second][2], 1, 0, 1, 0, 1, 0);
83         }
84         return distance;
85     }
86
87     void new_fit(std::vector< RVec > alfa, std::vector< RVec > &beta, std::vector< std::pair< int, int > > cros, double prec) {
88         double bx, by, bz;
89         RVec step;
90         double x1 = 0, y1 = 0, z1 = 0, A1 = 0, B1 = 0, C1 = 0;
91         double x2 = 0, y2 = 0, z2 = 0, A2 = 0, B2 = 0, C2 = 0;
92         double cA, sA, cB, sB, cC, sC, temp1, temp2, temp3;
93         double H1 = 0.00001, H2 = 0.00001, F1 = 0, F2 = 0;
94         do {
95             if (F1 > F2 || F1 == 0) {
96                 F1 = F2;
97             }
98             F2 = 0;
99             for (int i = 0; i < cros.size(); i++) {
100                 bx = beta[cros[i].second][0] + x1;
101                 by = beta[cros[i].second][1] + y1;
102                 bz = beta[cros[i].second][2] + z1;
103                 cA = cos(A1);
104                 sA = sin(A1);
105                 cB = cos(B1);
106                 sB = sin(B1);
107                 cC = cos(C1);
108                 sC = sin(C1);
109                 temp1 = alfa[cros[i].first][0] + by*(cA*sC - cC*sA*sB) - bz*(sA*sC + cA*cC*sB) - cB*cC*bx;
110                 temp2 = alfa[cros[i].first][1] - by*(cA*cC + sA*sB*sC) + bz*(cC*sA - cA*sB*sC) - cB*sC*bx;
111                 temp3 = alfa[cros[i].first][2] + sB*bx - cA*cB*bz - cB*sA*by;
112                 x2 += Fx(temp1, temp2, temp3,                     cB, sB, cC, sC);
113                 y2 += Fy(temp1, temp2, temp3,             cA, sA, cB, sB, cC, sC);
114                 z2 += Fz(temp1, temp2, temp3,             cA, sA, cB, sB, cC, sC);
115                 A2 += FA(temp1, temp2, temp3,     by, bz, cA, sA, cB, sB, cC, sC);
116                 B2 += FB(temp1, temp2, temp3, bx, by, bz, cA, sA, cB, sB, cC, sC);
117                 C2 += FC(temp1, temp2,        bx, by, bz, cA, sA, cB, sB, cC, sC);
118             }
119             if (std::max(std::fabs(H1*x2), std::max(std::fabs(H1*y2), std::fabs(H1*z2))) > 1) {
120                 H1 = 1 / std::max(std::fabs(H1*x2), std::max(std::fabs(H1*y2), std::fabs(H1*z2)));
121             }
122             x2 = x1 - H1 * x2;
123             y2 = y1 - H1 * y2;
124             z2 = z1 - H1 * z2;
125             if (std::max(std::fabs(H2*A2), std::max(std::fabs(H2*B2), std::fabs(H2*C2))) > M_PI/60) {
126                 H2 = M_PI/60 / std::max(std::fabs(H2*A2), std::max(std::fabs(H2*B2), std::fabs(H2*C2)));
127             }
128             A2 = A1 - H2 * A2;
129             if (std::fabs(A2) > M_PI) {
130                 A2 = 0;
131             }
132             B2 = B1 - H2 * B2;
133             if (std::fabs(B2) > M_PI) {
134                 B2 = 0;
135             }
136             C2 = C1 - H2 * C2;
137             if (std::fabs(C2) > M_PI) {
138                 C2 = 0;
139             }
140             for (int i = 0; i < cros.size(); i++) {
141                 cA = cos(A2);
142                 sA = sin(A2);
143                 cB = cos(B2);
144                 sB = sin(B2);
145                 cC = cos(C2);
146                 sC = sin(C2);
147                 F2 += F(alfa[cros[i].first][0], alfa[cros[i].first][1], alfa[cros[i].first][2], beta[cros[i].second][0] + x2, beta[cros[i].second][1] + y2, beta[cros[i].second][2] + z2, cA, sA, cB, sB, cC, sC);
148             }
149             if (F2 > F1 && F1 != 0) {
150                 H1 /= 10;
151                 H2 /= 10;
152             } else {
153                 x1 = x2;
154                 y1 = y2;
155                 z1 = z2;
156                 A1 = A2;
157                 B1 = B2;
158                 C1 = C2;
159                 x2 = 0;
160                 y2 = 0;
161                 z2 = 0;
162                 A2 = 0;
163                 B2 = 0;
164                 C2 = 0;
165             }
166         } while (std::fabs(F1 - F2) > prec/*0.00001*/);
167         step[0] = x1;
168         step[1] = y1;
169         step[2] = z1;
170         implement_fit(beta, step, A1, B1, C1);
171     }
172 }
173 #endif // NEWFIT_H