Python 如何对一组原子的主轴和转动惯量进行MDU分析?
我试图使用MDAnalysis(Python 如何对一组原子的主轴和转动惯量进行MDU分析?,python,python-3.x,physics,chemistry,mdanalysis,Python,Python 3.x,Physics,Chemistry,Mdanalysis,我试图使用MDAnalysis(MDAnalysis.\uuuuuu版本=0.17.0)API函数主轴()和惯性矩()来计算 这些矩阵用于一组选定原子,如中所述: 输出: center of mass [ 0.06873595 -0.04605918 -0.24643682] moment of inertia [[ 393842.2070687 -963.01376005 -6050.68541811] [ -963.01376005 474434.9289629 -
MDAnalysis.\uuuuuu版本=0.17.0
)API函数主轴()
和惯性矩()
来计算
这些矩阵用于一组选定原子,如中所述:
输出:
center of mass [ 0.06873595 -0.04605918 -0.24643682]
moment of inertia [[ 393842.2070687 -963.01376005 -6050.68541811]
[ -963.01376005 474434.9289629 -3902.61617054]
[ -6050.68541811 -3902.61617054 520207.91703069]]
principal axes [[-0.04680878 -0.08278738 0.99546732]
[ 0.01813292 -0.9964659 -0.08201778]
[-0.99873927 -0.01421157 -0.04814453]]
Lambda = U'IU [[ 519493.24344558 -4093.3268841 11620.96444297]
[ -4093.3268841 473608.1536763 7491.56715845]
[ 11620.96444297 7491.56715845 395383.6559404 ]]
这看起来是错误的,其中一个原因是U'IU
不是如中所述的对角线:
也许我需要把蛋白质和重心对齐,来计算惯性矩 问题是,在文档中,他们说
U'IU
,但U是来自CA.principal_axes()
的返回值的转置(请参见):
请确认:
>> I=[ 393842.2070687 -963.01376005 -6050.68541811 ; -963.01376005 474434.9289629 -3902.61617054; -6050.68541811 -3902.61617054 520207.91703069];
>> U=[-0.04680878 -0.08278738 0.99546732; 0.01813292 -0.9964659 -0.08201778;-0.99873927 -0.01421157 -0.04814453];
>> U*I*U'
ans =
1.0e+05 *
5.2082 0.0000 -0.0000
0.0000 4.7413 -0.0000
-0.0000 -0.0000 3.9354
上的教程中的文档原则上是正确的,但令人困惑的是,
AtomGroup.principal_axes()
的返回值不是矩阵U
,而是它的转置,U.T
:
AtomGroup.principal_axes()
方法返回一个数组[p1,p2,p3]
,其中主轴p1
,p2
,p3
是长度为3的数组;选择此布局作为行向量是为了方便(这样可以使用p1、p2、p3=ag.principal_axes()
)提取向量)。要形成一个矩阵U
,其中主轴是列向量,就像通常处理主轴一样,必须进行转置。例如:
import MDAnalysis
from MDAnalysis.tests.datafiles import PSF, DCD
import numpy as np
u = MDAnalysis.Universe(PSF, DCD)
CA = u.select_atoms("protein and name CA")
I = CA.moment_of_inertia()
UT = CA.principal_axes()
# transpose the row-vector layout UT = [p1, p2, p3]
U = UT.T
# test that U diagonalizes I
Lambda = U.T.dot(I.dot(U))
print(Lambda)
# check that it is diagonal (to machine precision)
print(np.allclose(Lambda - np.diag(np.diagonal(Lambda)), 0))
矩阵Lambda
应该是对角的(最后一次打印
应该显示True
):
最后,如果您想“手工”计算:
这将给出主轴作为列向量的
U
。计算lamdba的最后一行失败,因为numpy中的U*I
不是矩阵积,而是元素积。要计算矩阵积,您需要使用np.dot(U,I)
@MaxLinke true,但在使用np.matmul
时也需要这样做。我不知道我可以使用np.do
t进行矩阵乘法。这确实是个问题。我打开了一个程序来解决这个问题。谢谢你自己诊断。@MaxLinke不确定这是不是一个真正的问题,因为在消息来源中,他们说这是由于问题33而故意做的。请修复代码以复制使用np.matmul
好吗?很抱歉,自发布前起,该代码一定没有更新过。我们将更新文档。我也提出。谢谢您的反馈。@orbeckst谢谢您。我现在有点困惑。你能补充一个关于如何求转动惯量、主轴和特征值的答案吗?请注意,在本期中,我们需要使用np.matmul
或np.dot
,而不是所讨论的*
运算符。@0x90,感谢您注意到*
,我在这两期中将其替换为.dot()
。
>> I=[ 393842.2070687 -963.01376005 -6050.68541811 ; -963.01376005 474434.9289629 -3902.61617054; -6050.68541811 -3902.61617054 520207.91703069];
>> U=[-0.04680878 -0.08278738 0.99546732; 0.01813292 -0.9964659 -0.08201778;-0.99873927 -0.01421157 -0.04814453];
>> U*I*U'
ans =
1.0e+05 *
5.2082 0.0000 -0.0000
0.0000 4.7413 -0.0000
-0.0000 -0.0000 3.9354
import MDAnalysis
from MDAnalysis.tests.datafiles import PSF, DCD
import numpy as np
u = MDAnalysis.Universe(PSF, DCD)
CA = u.select_atoms("protein and name CA")
I = CA.moment_of_inertia()
UT = CA.principal_axes()
# transpose the row-vector layout UT = [p1, p2, p3]
U = UT.T
# test that U diagonalizes I
Lambda = U.T.dot(I.dot(U))
print(Lambda)
# check that it is diagonal (to machine precision)
print(np.allclose(Lambda - np.diag(np.diagonal(Lambda)), 0))
[[ 5.20816990e+05 -6.56706349e-10 -2.83491351e-12]
[-6.62283524e-10 4.74131234e+05 -2.06979926e-11]
[-6.56687024e-12 -2.07159142e-11 3.93536829e+05]]
True
values, evecs = np.linalg.eigh(I)
indices = np.argsort(values)
U = evecs[:, indices]