OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
RMSD.cpp
1#include "math/RMSD.hpp"
2
3#include "math/SVD.hpp"
4
5using namespace JAMA;
6using namespace OpenMD;
7
8RealType RMSD::calculate_rmsd(std::vector<Vector3d> mov, Vector3d& mov_com,
9 Vector3d& mov_to_ref) {
10 assert(mov.size() == ref_.size());
11 int n;
12 int n_vec = ref_.size();
13
14 /* calculate the centre of mass */
15 mov_com = V3Zero;
16
17 for (n = 0; n < n_vec; n++) {
18 mov_com += mov[n];
19 }
20
21 mov_com /= (RealType)n_vec;
22
23 mov_to_ref = ref_com - mov_com;
24
25 /* shift mov to center of mass */
26
27 for (n = 0; n < n_vec; n++) {
28 mov[n] -= mov_com;
29 }
30
31 /* initialize */
32 Mat3x3d R(0.0);
33 RealType E0 = 0.0;
34
35 for (n = 0; n < n_vec; n++) {
36 /*
37 * E0 = 1/2 * sum(over n): y(n)*y(n) + x(n)*x(n)
38 */
39 E0 += dot(mov[n], mov[n]) + dot(ref_[n], ref_[n]);
40
41 /*
42 * correlation matrix R:
43 * R(i,j) = sum(over n): y(n,i) * x(n,j)
44 * where x(n) and y(n) are two vector sets
45 */
46
47 R += outProduct(mov[n], ref_[n]);
48 }
49 E0 *= 0.5;
50
51 // Pack everything into Dynamic arrays for the SVD:
52 DynamicRectMatrix<RealType> Rtmp(3, 3, 0.0);
53 DynamicRectMatrix<RealType> vtmp(3, 3);
54 DynamicVector<RealType> stmp(3);
55 DynamicRectMatrix<RealType> wtmp(3, 3);
56
57 Rtmp.setSubMatrix(0, 0, R);
58 SVD<RealType> svd(Rtmp);
59
60 svd.getU(vtmp);
61 svd.getSingularValues(stmp);
62 svd.getV(wtmp);
63
64 Mat3x3d v;
65 Vector3d s;
66 Mat3x3d w;
67
68 vtmp.getSubMatrix(0, 0, v);
69 stmp.getSubVector(0, s);
70 wtmp.getSubMatrix(0, 0, w);
71
72 int is_reflection = (v.determinant() * w.determinant()) < RealType(0.0);
73 if (is_reflection) s(2) = -s(2);
74
75 RealType rmsd_sq = (E0 - 2.0 * s.sum()) / (RealType)n_vec;
76 rmsd_sq = std::max(rmsd_sq, RealType(0.0));
77 RealType rmsd = std::sqrt(rmsd_sq);
78 return rmsd;
79}
80
81RotMat3x3d RMSD::optimal_superposition(std::vector<Vector3d> mov,
82 Vector3d& mov_com,
83 Vector3d& mov_to_ref) {
84 assert(mov.size() == ref_.size());
85 int n;
86 int n_vec = ref_.size();
87
88 /* calculate the centre of mass */
89 mov_com = V3Zero;
90
91 for (n = 0; n < n_vec; n++) {
92 mov_com += mov[n];
93 }
94
95 mov_com /= (RealType)n_vec;
96
97 mov_to_ref = ref_com - mov_com;
98
99 /* shift mov to center of mass */
100
101 for (n = 0; n < n_vec; n++) {
102 mov[n] -= mov_com;
103 }
104
105 /* initialize */
106 Mat3x3d R(0.0);
107
108 for (n = 0; n < n_vec; n++) {
109 /*
110 * correlation matrix R:
111 * R(i,j) = sum(over n): y(n,i) * x(n,j)
112 * where x(n) and y(n) are two vector sets
113 */
114
115 R += outProduct(mov[n], ref_[n]);
116 }
117
118 // Pack everything into Dynamic arrays for the SVD:
119 DynamicRectMatrix<RealType> Rtmp(3, 3, 0.0);
120 DynamicRectMatrix<RealType> vtmp(3, 3);
121 DynamicVector<RealType> stmp(3);
122 DynamicRectMatrix<RealType> wtmp(3, 3);
123
124 Rtmp.setSubMatrix(0, 0, R);
125 SVD<RealType> svd(Rtmp);
126
127 svd.getU(vtmp);
128 svd.getSingularValues(stmp);
129 svd.getV(wtmp);
130
131 Mat3x3d v;
132 Vector3d s;
133 Mat3x3d w;
134
135 vtmp.getSubMatrix(0, 0, v);
136 stmp.getSubVector(0, s);
137 wtmp.getSubMatrix(0, 0, w);
138
139 int is_reflection = (v.determinant() * w.determinant()) < 0.0;
140 if (is_reflection) s(2) = -s(2);
141
142 RotMat3x3d U = v * w;
143 return U;
144}
Real determinant() const
Returns the determinant of this matrix.
Real sum() const
Returns the sum of all elements of this vector.
Definition Vector.hpp:373
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.