本文介绍了Kabsch算法原理,并用多个框架对算法进行了代码实现。
Kabsch Algorithm
Kabsch算法(又称Kabsch-Umeyama算法)是一种用于在两组对应点之间找到最佳刚体旋转的算法,目的是最小化两个点集之间的均方根误差(RMSD, Root Mean Square Deviation),该算法在分子模拟、图机器学习(or GNN)等领域中非常有用。
算法原理
Kabsch算法的目标是给定两个质心相同的点集,找到一个旋转矩阵
注意前提是点群的点已经是一一对应的
假设有两个任意点集
除基本对齐的要求外,有需要也可以为点集中的点加入权重
- 去质心化(Centering the Point Sets)
首先计算点集
通过减去质心坐标,将两个点群平移到相同的质心。
- 计算协方差矩阵(Covariance Matrix)幷进行奇异值分解(SVD)
通过两个去质心化点群的外积求得点群之间的协方差矩阵
然后对
再由下式即可求得旋转矩阵
此处要注意若行列式的值
例如当
- 进行Align
计算平移向量
然后可简单地求出RMSD:
代码实现
代码基于Python的PyTorch框架实现,同时也提供了NumPy和JAX框架,以及Rust的实现代码。
PyTorch实现
1 | import torch |
NumPy实现
1 | import numpy as np |
JAX实现
1 | import jax.numpy as jnp |
Rust实现
Cargo.toml中添加依赖项nalgebra:
1 | [dependencies] |
1 | use nalgebra::{Matrix3, Vector3, DMatrix, SVD}; |
测试
以乙醇为例,创建两个甲醇分子对象,进行对齐并计算
- 定义函数生成分子构象
1 | from rdkit import Chem |
- 生成乙醇原子的笛卡尔坐标作为点群
和
1 | mol1 = generate_methanol(42) |
1 | Number of atoms: 6 |
故意将随机种子固定是为了保证当前的原子次序是一一对应的。
- 随机对
进行旋转和平移
1 | def random_rotation_matrix(dim=3): |
1 | P: [[-0.35770023 0.00759022 -0.02148174] |
- 不对齐直接求
1 | def rmsd(P, Q): |
1 | 2.5456441356883777 |
- 使用Kabsch算法进行对齐并求得
1 | R_, t_, rmsd = kabsch_numpy(P, Q) |
1 | 1.881049755021318e-06 |
注意此处求得的旋转矩阵和开始QR分解随机生成的正交矩阵(
Scource Code
Github: An implementation of Kabsch algorithm.
参考文章
- Kabsch W. A discussion of the solution for the best rotation to relate two sets of vectors[J]. Acta Crystallographica Section A: Crystal Physics, Diffraction, Theoretical and General Crystallography, 1978, 34(5): 827-828.