performance - 在matlab中对矩阵元素求和的有效(最快)方法

标签 performance matlab matrix sum

让矩阵 AA = magic(100);。我见过两种计算矩阵 A 的所有元素之和的方法。

sumOfA = sum(sum(A));

或者

sumOfA = sum(A(:));

其中一个比另一个更快(或更好地练习)吗?如果有的话是哪一个?或者它们都一样快?

最佳答案

对于性能和浮点精度哪个更重要,您似乎无法下定决心。

如果浮点精度是最重要的精度,那么您将分离正元素和负元素,对每个部分进行排序。然后按绝对值递增的顺序求和。是的,我知道,这比任何人都多,而且可能会浪费时间。

相反,请使用足够的精度,这样所犯的任何错误都将无关紧要。在测试等方面使用良好的数值实践,这样就不会产生问题。

就时间而言,对于一个 NxM 数组,

sum(A(:)) 将需要 N*M-1 次加法。

sum(sum(A)) 将需要 (N-1)*M + M-1 = N*M-1 次加法。

这两种方法都需要相同数量的添加,因此对于大型数组,即使解释器不够聪明,无法识别它们都是相同的操作,谁在乎呢?

这根本不是问题。不要小题大做,担心这个问题。

编辑:作为对 Amro 关于一种方法相对于另一种方法的错误的评论的回应,您几乎无法控制。添加将以不同的顺序完成,但无法保证哪个顺序更好。

A = randn(1000);
format long g

这两个解决方案非常接近。事实上,与 eps 相比,差别不大。

sum(A(:))
ans =
          945.760668102446

sum(sum(A))
ans =
          945.760668102449

sum(sum(A)) - sum(A(:))
ans =
      2.72848410531878e-12

eps(sum(A(:)))
ans =
      1.13686837721616e-13

假设您选择了我提到的分离和排序技巧。请注意负数部分和正数部分足够大,以至于精度会有所损失。

sum(sort(A(A<0),'descend'))
ans =
          -398276.24754782

sum(sort(A(A<0),'descend')) + sum(sort(A(A>=0),'ascend'))
ans =
            945.7606681037

因此,无论如何,您确实需要将这些片段累积到更高精度的数组中。我们可以试试这个:

[~,tags] = sort(abs(A(:)));
sum(A(tags))
ans =
          945.760668102446

即使在这些测试中也会出现一个有趣的问题。因为测试是在随机(正常)阵列上完成的,所以会有问题吗?本质上,我们可以将 sum(A(:)) 视为随机游走,醉汉游走。但是考虑总和(总和(A))。 sum(A) 的每个元素(即内部和)本身就是 1000 个正态偏差的总和。看看其中的几个:

sum(A)
ans =
  Columns 1 through 6
         -32.6319600960983          36.8984589766173          38.2749084367497          27.3297721091922          30.5600109446534          -59.039228262402
  Columns 7 through 12
          3.82231962760523          4.11017616179294         -68.1497901792032          35.4196443983385          7.05786623564426         -27.1215387236418
  Columns 13 through 18

当我们将它们相加时,会有精度损失。因此,作为 sum(A(:)) 的操作可能会稍微准确一些。是这样吗?如果我们使用更高的精度进行累加呢?所以首先,我将使用 double 对列求和,然后转换为 25 位小数精度,然后对行求和。 (我在这里只显示了 20 位数字,留下 5 位数字作为保护数字隐藏。)

sum(hpf(sum(A)))
ans =
945.76066810244807408

或者,直接转换为 25 位精度,然后对结果求和。

sum(hpf(A(:))
945.76066810244749807

所以 double 的两种形式在这里都同样错误,方向相反。最后,这一切都没有实际意义,因为与简单的变体 sum(A(:)) 或 sum(sum(A)) 相比,我展示的任何替代方案都耗时更多。只需选择其中之一,不用担心。

关于performance - 在matlab中对矩阵元素求和的有效(最快)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11279549/

相关文章:

performance - AWS DynamoDB 持久连接

python - num2cell() 的 python/numpy 等价物是什么?

c - 马氏距离反转协方差矩阵

matlab - 查找 3D 矩阵中第三维的最小绝对值并确保符号保持不变

java - 性能方面,Guava 库有多好?

python - 用于处理大整数的多个数字数组

javascript - 在 JavaScript 中仅使用表达式/不使用语句是否会降低性能?

matlab - 查找数列的索引

c++ - 需要神经网络 XOR 反向传播信息

c - 使用 CUDA 减少矩阵行