相同的矩阵运算在Matlab中返回不同的结果

时间:2012-07-02 16:47:51

标签: matlab floating-point-precision

我对Matlab有一点问题,我认为它与Matlab精度有关,但我真的想解决这个问题。我有三个矩阵,一个名为f,维度为296x3118,另一个名为mapping.mean,维度为1x3118,最后一个名为mapping.M,维度为3118x100。 以下操作的结果应该是一个,但事实并非如此。生成的矩阵f_s_1f_s_2的值仅在10 ^ -12的范围内不同。有没有人知道为什么,或者如何解决这个问题?

f_s_1 = ((f(1:296,:)-repmat(mapping.mean,296,1))*mapping.M)';
f_s_2 = ((f(1:295,:)-repmat(mapping.mean,295,1))*mapping.M)';
isequal(f_s_1(:,1:295),f_s_2)

ans =

 0

1 个答案:

答案 0 :(得分:3)

您所看到的是MATLAB中Round-off error的结果,可能来自大型矩阵运算的并行化。对于非常大的矩阵运算,MATLAB automatically switches to a parallel version of the operator to increase speed这意味着解决方案的所有部分可以同时计算,然后在最后进行组合。由于不同的部分可能迟早完成或由原始问题的不同部分组成,因此可以得到不同的结果。

因为您的计算机仅使用少量位来表示您的数字(在您的matlab版本上它可能使用64位),您通常会在执行操作时将一小部分十进制数切掉。事实上,当你将一个非常大的数字添加到一个非常小的数字时,计算机可能只返回非常大的数字,因为没有“空间”代表较小的数字。

例如,尝试运行以下代码:

mybase = 1e17;

sum1 = mybase + sum(1e-4*ones(2^14,1)) - mybase
sum2 = mybase - mybase + sum(1e-4*ones(2^14,1))

你应该得到:

sum1 =

     0


sum2 =

    1.6384

即使总和只是重新排列,它们也会产生不同的数字。如果你玩它,你会发现MATLAB从左到右添加数字,当数字的大小差别很大时,问题就开始出现了。由于1.6384是1e17的一小部分,我们可能认为它根本没有真正的错误......但显然答案是错误的,都是因为我们总和的顺序。

为什么这里有关系?正如我们之前提到的,如果MATLAB选择并行化操作,那么问题的每个部分将同时计算然后组合。根据许多事情(问题规模,计算机正在做的其他事情等),可能会以不同的顺序添加这些部分。这意味着结果会略有不同。如果你在我的版本(R2012a)上将矩阵设置为相同的大小,那么你可能得到相同的答案......或者你可能没有。此外,它将取决于大小。

此行为是“功能”,即使使用maxNumCompThreads(1)

,我也会得到相同的答案