我有一个应该是对称的矩阵(它是对称的倒数),但它并不完全是由于反演中的数值误差等。
所以,我添加了使矩阵对称的步骤(通过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
),问题不会出现。
答案 0 :(得分:4)
错误来自第a += a.T
行。这是就地操作的一个已知问题(我现在找不到适当的文档,但是引用了scipy lecture notes:
换位是一种观点。
结果,以下代码是错误的,不会使矩阵对称:
a += a.T
它可以用于小型数组(因为缓冲),但是对于大型数组,则以不可预测的方式失败。
原因是a
同时a.T
正在更新a.T
,a
实际上正在发生变化(因为它是{{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
的临时副本,但不会更新。