使矩阵对称,就地与非对称

时间:2017-01-23 10:15:29

标签: python numpy matrix

我有一个应该是对称的矩阵(它是对称的倒数),但它并不完全是由于反演中的数值误差等。

所以,我添加了使矩阵对称的步骤(通过a = .5(a+a'),如果我就地进行了数字灾难(不合适的话)。代码:

import numpy as np

def check_sym(x):
    print("||a-a'||^2 = %e" % np.sum((x - x.T)**2))

# make a symmetric matrix
dim = 100
a = np.random.randn(dim,dim)
a = np.matmul(a, a.T)
b = a.copy()

check_sym(a)

print("symmetrizing in-place")
a += a.T
a *= .5
check_sym(a)

print("symmetrizing out-of-place")
b = .5 * (b + b.T)
check_sym(b)

输出是:

||a-a'||^2 = 1.184044e-26
symmetrizing in-place
||a-a'||^2 = 7.313593e+04
symmetrizing out-of-place
||a-a'||^2 = 0.000000e+00

请注意,对于较低尺寸(例如dim=10),问题不会出现。

编辑通过在就地版本之后查看a-a',可以获得更多信息: a minus a.transpose

1 个答案:

答案 0 :(得分:4)

错误来自第a += a.T行。这是就地操作的一个已知问题(我现在找不到适当的文档,但是引用了scipy lecture notes

  

换位是一种观点。

     

结果,以下代码是错误的,不会使矩阵对称:

a += a.T
     

它可以用于小型数组(因为缓冲),但是对于大型数组,则以不可预测的方式失败。

原因是a同时a.T正在更新a.Ta实际上正在发生变化(因为它是{{em> memoryview 的{{ 1}}),因此错误地更新了a的某些坐标。

如果要在适当的位置对齐矩阵,可以执行以下操作:

a = np.random.rand(4,4)
a[np.tril_indices_from(a)] = a.T[np.tril_indices_from(a)]

或者,如果你想坚持你的记谱法:

a += a.T.copy()

因为copy会创建a.T的临时副本,但不会更新。

相关问题