矩阵乘法给出两个不同的答案

时间:2013-12-09 15:59:55

标签: matlab matrix-multiplication

这是一些显示我一直看到的简单代码:

A = randn(1,5e6)+1i*randn(1,5e6);
B = randn(1,5e6)+1i*randn(1,5e6);

sum(A.*conj(B)) - A*B'
sum(A.*conj(B)) - mtimes(A,B')
A*B' - mtimes(A,B')

现在,底部显示的三种方法应该做同样的事情,所以答案应该是零,对吧?错误!差异很小,虽然不够小,我认为它们可以忽略不计。此外,随着A和B的长度增加,误差也会增加。

有谁知道这些方法之间的实际区别是什么?我知道代码中可能有快捷方式,但如果可能的话我想量化一下。 Matlab会在任何地方发布差异吗?我环顾四周,但没找到任何东西。

2 个答案:

答案 0 :(得分:5)

这可能与执行操作的顺序有关。例如,

sum(A.*conj(B)) - fliplr(A)*fliplr(B)'

给出的结果与

不同
sum(A.*conj(B)) - A*B'

或者,更引人注目的是,

A*B' - fliplr(A)*fliplr(B)'

给出非零结果,与测试的顺序相同。

所以我的赌注是,取决于方法(sum*),Matlab内部以不同的顺序执行操作,这可能会导致您观察到的不同舍入错误。

答案 1 :(得分:2)

考虑到每个数字的大小,对这个数字的简单操作的舍入误差是10 ^ -14

的顺序

你有5 * 10 ^ 6个数字,因此如果你真的不走运,那么舍入错误就会变成5 * 10 ^ -8。

您观察到的误差大小为10 ^ 10,远远超出预期范围。

请注意,差异不是由复数转置引起的,而是由和与矩阵乘积的乘积引起的。

A = randn(1,5e6)+1i*randn(1,5e6);
B = randn(1,5e6)+1i*randn(1,5e6);

B1 = conj(B); 
B2 = B';

isequal(B1(:),B2(:)) % This returns true

A*transpose(conj(B)) - A*B' % Hence this returns zero

sum(A.*transpose(B')) - A*B' % But this returns something like 1e-10

非复杂AB

会产生类似的效果
N=1e6;
A = 1:N; 
B=1:N;

(N * (N + 1) * (2*N + 1))/6 % This will give exactly the right answer
A*B' 
fliplr(A)*fliplr(B)'

请注意,两个最低答案彼此之间的差异只有几百个,而实际答案中它们实际上超过了2000个。如果这是一个问题,请考虑使用符号工具箱。这允许您以任意精度计算。