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

Ras*_*sto 9 performance matlab sum matrix

让我们A说矩阵A = magic(100);.我已经看到了两种计算矩阵所有元素之和的方法A.

sumOfA = sum(sum(A));
Run Code Online (Sandbox Code Playgroud)

要么

sumOfA = sum(A(:));
Run Code Online (Sandbox Code Playgroud)

其中一个比其他更快(或更好的练习)吗?如果是这样的话呢?或者他们都同样快?

小智 15

您似乎无法决定性能或浮点精度是否更重要.

如果浮点精度是最重要的准确度,那么您将分离正面和负面元素,对每个线段进行排序.然后按增加绝对值的顺序求和.是的,我知道,它的工作比任何人都多,而且可能浪费时间.

相反,使用足够的精度,以便所做的任何错误都是无关紧要的.使用关于测试等的良好数值实践,这样就不会产生任何问题.

就时间而言,对于NxM阵列,

sum(A(:))将需要添加N*M-1.

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

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

这根本不是问题.不要为了担心这个而在鼹鼠山上筑山.

编辑:响应Amro对一种方法的错误的评论而不是另一种方法,你几乎无法控制.添加将以不同的顺序完成,但无法确定哪个序列会更好.

A = randn(1000);
format long g
Run Code Online (Sandbox Code Playgroud)

这两种解决方案非常接近.事实上,与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
Run Code Online (Sandbox Code Playgroud)

假设你选择我提到的隔离和排序技巧.看到负面和正面部分足够大,会导致精度下降.

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

sum(sort(A(A<0),'descend')) + sum(sort(A(A>=0),'ascend'))
ans =
            945.7606681037
Run Code Online (Sandbox Code Playgroud)

所以你真的需要在更高精度的阵列中积累碎片.我们可以试试这个:

[~,tags] = sort(abs(A(:)));
sum(A(tags))
ans =
          945.760668102446
Run Code Online (Sandbox Code Playgroud)

即使在这些测试中也会出现一个有趣的问题.是否会出现问题,因为测试是在随机(正常)阵列上完成的?基本上,我们可以将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
Run Code Online (Sandbox Code Playgroud)

当我们添加它们时,将会失去精确度.因此,作为sum(A(:))的操作可能会稍微准确一些.是这样吗?如果我们使用更高的精度积累怎么办?首先,我将使用双精度在列中形成总和,然后转换为25位十进制精度,并对行求和.(我这里只显示了20位数字,隐藏了5位数字作为保护数字.)

sum(hpf(sum(A)))
ans =
945.76066810244807408
Run Code Online (Sandbox Code Playgroud)

或者,相反,立即转换为25位精度,然后对结果求和.

sum(hpf(A(:))
945.76066810244749807
Run Code Online (Sandbox Code Playgroud)

因此,双精度的两种形式在这里同样错误,方向相反.最后,这一切都没有实际意义,因为与简单的变量sum(A(:))或sum(sum(A))相比,我所展示的任何替代方案都要花费更多的时间.只需选择其中一个,不要担心.

  • @drasto您是否尝试过分析代码?你说你们之间"差别很小",只有一个.你看过别人吗?如果"大数据优化问题"中的"瓶颈"是矩阵元素的总和,我会感到非常惊讶. (2认同)