标题已经说明了。如果我需要找到矩阵的逆矩阵,我是否应该使用 A\eye(size(A))
而不是 inv(A)
?
在你问之前:是的,我真的需要逆,不仅仅是为了计算。
附言:
isequal(inv(A), A\eye(size(A)))
ans =
0
那么哪个更精确呢?
更新:此问题已关闭,因为它似乎与问题“why is inv in MATLAB so slow and inaccurate”重复。这个问题在这里有很大的不同,因为它没有解决速度,也没有解决函数 inv
的准确性,而是 inv
和 .\eye
计算的差异矩阵的真逆。
让我们暂时忽略性能(速度)和最佳实践。
eps(n)
是在 MATLAB 中返回从 n
到下一个更大的 double 的距离的命令。因此,eps(1) = 2.2204e-16
表示 1
之后的第一个数字是 1 + 2.2204e-16
。同样,eps(3000) = 4.5475e-13
。现在,让我们看看您的计算精度:
n = 100;
A = rand(n);
inv_A_1 = inv(A);
inv_A_2 = A \ eye(n);
max(max(abs(inv_A_1-inv_A_2)))
ans =
1.6431e-14
eps(127) = 1.4211e-14
eps(128) = 2.8422e-14
对于整数,您可以使用的精度高于两个矩阵之间最大差值的最大数字是 127。
现在,让我们检查一下当我们尝试从两个逆矩阵重新创建单位矩阵时的准确性。
error_1 = max(max(abs((A\eye(size(A))*A) - eye(size(A)))))
error_1 =
3.1114e-14
error_2 = max(max(abs((inv(A)*A) - eye(size(A)))))
error_2 =
2.3176e-14
精度高于两种方法最大差值的最大整数是 255。
总而言之,inv(A)
更准确,但是一旦您开始使用逆矩阵,它们就所有预期目的而言都是相同的。
现在,让我们看看这两种方法的性能:
n = fix(logspace(1,3,40));
for i = 1:numel(n)
A = rand(round(n(i)));
t1(i) = timeit(@()inv(A));
t2(i) = timeit(@()A\eye(n(i)));
end
loglog(n,[t1;t2])
这两种方法中哪一种最快取决于矩阵大小。例如,对于 n = 255
,使用 inv
速度较慢,但对于 n = 256
则更快。
总而言之,根据对您来说重要的事情来选择方法。对于大多数预期目的,这两种方法是相同的。
请注意 svd
和 pinv
如果您使用的是缩放比例很低的矩阵,则可能会感兴趣。如果它真的很重要,您应该考虑 Symbolic toolbox .
我知道你说过你“实际上需要逆”,但我不能不说:使用 inv(A)*b
从来都不是求解线性方程的最佳方法!我不会进一步解释,因为我想你已经知道了。