我正试图取矩阵的平方根。这是找到矩阵B
所以B*B=A
。我找到的所有方法都没有给出有效的结果。
首先我在Wikipedia上找到了这个公式:
设置Y_0 = A
和Z_0 = I
然后迭代:
Y_{k+1} = .5*(Y_k + Z_k^{-1}),
Z_{k+1} = .5*(Z_k + Y_k^{-1}).
然后Y
应收敛到B
。
然而在python中实现算法(使用numpy for inverse matrices),给了我垃圾结果:
>>> def denbev(Y,Z,n):
if n == 0: return Y,Z
return denbev(.5*(Y+Z**-1), .5*(Z+Y**-1), n-1)
>>> denbev(matrix('1,2;3,4'), matrix('1,0;0,1'), 3)[0]**2
matrix([[ 1.31969074, 1.85986159],
[ 2.78979239, 4.10948313]])
>>> denbev(matrix('1,2;3,4'), matrix('1,0;0,1'), 100)[0]**2
matrix([[ 1.44409972, 1.79685675],
[ 2.69528512, 4.13938485]])
正如你所看到的,迭代100次,得到更差的结果而不是迭代三次,并且没有一个结果在40%的误差范围内。
然后我尝试了scipy sqrtm方法,但情况更糟:
>>> scipy.linalg.sqrtm(matrix('1,2;3,4'))**2
array([[ 0.09090909+0.51425948j, 0.60606061-0.34283965j],
[ 1.36363636-0.77138922j, 3.09090909+0.51425948j]])
>>> scipy.linalg.sqrtm(matrix('1,2;3,4')**2)
array([[ 1.56669890+0.j, 1.74077656+0.j],
[ 2.61116484+0.j, 4.17786374+0.j]])
我不太了解矩阵平方根,但我认为必须有比上述更好的算法?
答案 0 :(得分:8)
(1)矩阵[1,2; 3,4]的平方根应该给出一些复杂的东西,因为该矩阵的特征值是负的。所以你的解决方案一开始就不正确。
(2)linalg.sqrtm返回一个数组,而不是一个矩阵。因此,使用*
乘以它们并不是一个好主意。在您的情况下,解决方案是正确的,但您没有看到它。
编辑尝试以下操作,您会看到它是正确的:
asmatrix(scipy.linalg.sqrtm(matrix('1,2;3,4')))**2
答案 1 :(得分:3)
你的矩阵[1 2; 3 4]不是正数,因此在真实矩阵的领域中没有解决问题的方法。
答案 2 :(得分:2)
你正在做的矩阵平方根的目的是什么?我怀疑实际应用矩阵确实可以是对称正定(例如协方差),所以你不应该遇到复数。
在这种情况下,您可以计算一个cholesky分解,如缩放LU分解,请参见此处:http://en.wikipedia.org/wiki/Cholesky_decomposition
另一个实际的例子是,如果你的矩阵是旋转,那么你可以先用矩阵日志进行分解,然后在日志空间中除以2,然后用矩阵指数返回旋转...无论如何你听起来很奇怪要求'通用矩阵平方根',您可能希望更深入地了解具体应用。