scipy.linalg.sqrtm无法得到精确矩阵平方根的问题
矩阵平方根不唯一与scipy.linalg.sqrtm的行为
问题原因
矩阵的平方根不唯一——和实数的平方根有正负两个类似,满足C@C = B的矩阵C可以有多个。scipy.linalg.sqrtm默认返回的是主平方根:当B可对角化时,它会对B的特征值取非负平方根,再通过相似变换得到结果矩阵。
以你的例子来说:
- 矩阵A的特征值是
(5+√33)/2 ≈ 5.372和(5-√33)/2 ≈ -0.372,其中一个是负数。 - B=A²的特征值是A特征值的平方,即
≈28.86和≈0.138,都是正数。 sqrtm计算主平方根时,会对B的特征值取正平方根(也就是|A的特征值|),再重构矩阵,得到的C的特征值是≈5.372和≈0.372,和原矩阵A的特征值符号不同,因此C和A不是同一个矩阵,但平方后确实等于B。
解决方法:获取原矩阵A作为平方根
如果已知B是某个矩阵A的平方,且需要还原出A,可以通过特征分解的方式构造:
- 对原矩阵A做特征分解:
A = PDP⁻¹,其中D是A的特征值对角矩阵,P是特征向量矩阵。 - B的特征分解为
B = PD²P⁻¹,此时取D'=D(保留原特征值的符号),则C = PD'P⁻¹就是A,也就是B的一个平方根。
示例代码:
import numpy as np import scipy.linalg as la A = np.array([[1, 2], [3, 4]]) B = A @ A # 对A做特征分解 P, D = la.eig(A) # 构造B的平方根(还原A) C = P @ np.diag(D) @ la.inv(P) # 打印结果(因数值计算误差,会接近A) print(np.round(C, 4)) # 验证C@C等于B print(np.round(C @ C, 4))
如果不知道原矩阵A,但需要得到某个特定符号特征值的平方根,也可以先对B做特征分解,再根据需求调整特征值的符号,最后重构矩阵。
内容的提问来源于stack exchange,提问作者Aaditya Rudra
相关产品推荐
相关产品推荐

