工作矩阵平方根

时间:2010-11-21 15:42:40

标签: algorithm matrix math

我正试图取矩阵的平方根。这是找到矩阵B所以B*B=A。我找到的所有方法都没有给出有效的结果。

首先我在Wikipedia上找到了这个公式:

设置Y_0 = AZ_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]])

我不太了解矩阵平方根,但我认为必须有比上述更好的算法?

3 个答案:

答案 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,然后用矩阵指数返回旋转...无论如何你听起来很奇怪要求'通用矩阵平方根',您可能希望更深入地了解具体应用。