OpenMD 3.0
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 OpenMD;
6using namespace JAMA;
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 = max(rmsd_sq, RealType(0.0));
77 RealType rmsd = sqrt(rmsd_sq);
78 return rmsd;
79}
80
81RotMat3x3d RMSD::optimal_superposition(std::vector<Vector3d> mov,
82 Vector3d mov_com, Vector3d mov_to_ref) {
83 assert(mov.size() == ref_.size());
84 int n;
85 int n_vec = ref_.size();
86
87 /* calculate the centre of mass */
88 mov_com = V3Zero;
89
90 for (n = 0; n < n_vec; n++) {
91 mov_com += mov[n];
92 }
93
94 mov_com /= (RealType)n_vec;
95
96 mov_to_ref = ref_com - mov_com;
97
98 /* shift mov to center of mass */
99
100 for (n = 0; n < n_vec; n++) {
101 mov[n] -= mov_com;
102 }
103
104 /* initialize */
105 Mat3x3d R(0.0);
106
107 for (n = 0; n < n_vec; n++) {
108 /*
109 * correlation matrix R:
110 * R(i,j) = sum(over n): y(n,i) * x(n,j)
111 * where x(n) and y(n) are two vector sets
112 */
113
114 R += outProduct(mov[n], ref_[n]);
115 }
116
117 // Pack everything into Dynamic arrays for the SVD:
118 DynamicRectMatrix<RealType> Rtmp(3, 3, 0.0);
119 DynamicRectMatrix<RealType> vtmp(3, 3);
120 DynamicVector<RealType> stmp(3);
121 DynamicRectMatrix<RealType> wtmp(3, 3);
122
123 Rtmp.setSubMatrix(0, 0, R);
124 SVD<RealType> svd(Rtmp);
125
126 svd.getU(vtmp);
127 svd.getSingularValues(stmp);
128 svd.getV(wtmp);
129
130 Mat3x3d v;
131 Vector3d s;
132 Mat3x3d w;
133
134 vtmp.getSubMatrix(0, 0, v);
135 stmp.getSubVector(0, s);
136 wtmp.getSubMatrix(0, 0, w);
137
138 int is_reflection = (v.determinant() * w.determinant()) < 0.0;
139 if (is_reflection) s(2) = -s(2);
140
141 RotMat3x3d U = v * w;
142 return U;
143}
Real determinant() const
Returns the determinant of this matrix.
Real sum()
Returns the sum of all elements of this vector.
Definition Vector.hpp:369
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.