我正在重写分子动力学时间序列的分析代码。由于必须分析大量时间步长(每次模拟运行 150 000 个),因此我的代码尽可能快是非常重要的。
旧代码非常慢(实际上它需要的时间是我的 300 到 500 倍),因为它是为分析几千个 PDB 文件而不是一堆不同的模拟(大约 60 个)而编写的,每个都有150 000 个时间步长。我知道在这种情况下 C 或 Fortran 将是瑞士军刀,但我对 c 的经验是.....
因此,我试图为我的 python 代码使用尽可能多的 numpy/scipy 例程。因为我有使用 mkl 加速分发 anaconda 的许可证,所以这是一个非常显着的加速。
现在我面临一个问题,我希望我能以您理解我的意思的方式解释它。
我有三个数组,每个数组的形状为 (n, 3, 20)。第一行是我的肽的所有残差,通常在 23 到 31 左右。第二行是 xyz 顺序的坐标,第三行是一些特定的时间步长。
现在我正在计算每个时间步的每个残差的扭转。我对于形状为 (n,3,1) 的数组的代码:
def fast_torsion(d1, d2, d3):
tt = dot(d1, np.cross(d2, d3))
tb = dot(d1, d1) * dot(d2, d2)
torsion = np.zeros([len(d1), 1])
for i in xrange(len(d1)):
if tb[i] != 0:
torsion[i] = tt[i]/tb[i]
return torsion
现在我尝试对具有扩展第三轴的数组使用相同的代码,但与使用 for 循环的原始慢速代码相比,叉积函数产生了错误的值。我用我的大数组尝试了这段代码,它比 for 循环解决方案快大约 10 到 20 倍,比旧代码快大约 200 倍。
我正在尝试的是 np.cross() 仅计算第二个(xyz)轴上的叉积并迭代其他两个轴。在第三轴较短的情况下,它可以正常工作,但对于大阵列,它仅适用于第一个时间步。我也尝试了轴设置,但我没有机会。
如果这是我的问题的唯一解决方案,我也可以使用 Cython 或 numba。
PS对不起我的英语我希望你能理解一切。