Numpy eigh返回非正规矩阵,如何获取纯旋转矩阵?
如何让numpy.linalg.eigh返回纯旋转矩阵(行列式为1)?
问题背景
你尝试用numpy.linalg.eigh的特征向量矩阵作为旋转矩阵,但发现它的行列式为-1(约-0.99999999999),属于包含反射的正交变换,而非纯旋转矩阵(行列式应为1)。验证代码如下:
import numpy as np GG = np.array([[2.0, 0.146, 0.0064], [0.146, -1.0, 0.0003], [0.0064, 0.0003, -1.0]]) vals, vecs = np.linalg.eigh(GG) np.linalg.det(vecs)
原因解释
这不是求解器的问题,是正交矩阵的数学特性:
np.linalg.eigh针对对称/Hermitian矩阵求解,返回的特征向量矩阵是正交矩阵(实数域下)。正交矩阵的行列式只能是1或-1:行列式为1对应纯旋转,为-1则是旋转加反射的组合。- 矩阵是否无迹和这个现象无关,你的示例矩阵迹为0只是巧合,不管矩阵迹如何,正交矩阵的行列式都可能是±1。
解决方法
要得到纯旋转矩阵,只需要将特征向量矩阵的任意一列乘以-1即可——因为行列式是多线性函数,某一列乘-1会让行列式整体变号,同时矩阵依然保持正交性,且不改变特征向量的有效性(特征向量乘以非零标量仍然是原特征值对应的特征向量)。
修改后的代码示例:
import numpy as np GG = np.array([[2.0, 0.146, 0.0064], [0.146, -1.0, 0.0003], [0.0064, 0.0003, -1.0]]) vals, vecs = np.linalg.eigh(GG) # 检查行列式,若为负则翻转任意一列 if np.linalg.det(vecs) < 0: vecs[:, 0] *= -1 # 选择第一列,选任意列都可以 print(np.linalg.det(vecs)) # 输出约1.0,满足纯旋转矩阵要求
内容的提问来源于stack exchange,提问作者Rodney Price
相关产品推荐
相关产品推荐

