1

我在使用 Matlab 时遇到了一点问题,我认为这与 Matlab 的精度有关,但我真的很想解决这个问题。我有三个矩阵,一个f以 296x3118 的尺寸调用,另一个mapping.mean以 1x3118 的尺寸调用,最后一个mapping.M以 3118x100 的尺寸调用。
以下操作的结果应该是 1,但不是。生成的矩阵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
4

1 回答 1

3

您看到的是 MATLAB 中舍入错误的结果,可能来自大型矩阵运算的并行化。对于非常大的矩阵运算,MATLAB会自动切换到运算符的并行版本以提高速度,这意味着解决方案的各个部分都可以同时计算,然后在最后进行组合。由于不同部分可能迟早完成,或者由原始问题的不同部分组成,因此您可以获得不同的结果。

因为您的计算机仅使用少量位来表示您的数字(在您的 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)

于 2012-07-02T18:12:42.970 回答