在MATLAB中高效(最快)求和矩阵元素的方法 [英] Efficient (fastest) way to sum elements of matrix in matlab

查看:720
本文介绍了在MATLAB中高效(最快)求和矩阵元素的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Lets have matrix A say A = magic(100);. I have seen 2 ways of computing sum of all elements of matrix A.

sumOfA = sum(sum(A));

sumOfA = sum(A(:));

其中一个比另一个更快(或更好的实践)吗?如果是这样,那是哪一个?还是两者都一样快?

Is one of them faster (or better practise) then other? If so which one is it? Or are they both equally fast?

推荐答案

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

It seems that you can't make up your mind about whether performance or floating point accuracy is more important.

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

If floating point accuracy were of paramount accuracy, then you would segregate the positive and negative elements, sorting each segment. Then sum in order of increasing absolute value. Yeah, I know, its more work than anyone would do, and it probably will be a waste of time.

相反,请使用足够的精度,以免发生任何错误.使用有关测试等的良好数字惯例,以免产生任何问题.

Instead, use adequate precision such that any errors made will be irrelevant. Use good numerical practices about tests, etc, such that there are no problems generated.

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

As far as the time goes, for an NxM array,

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

sum(A(:)) will require N*M-1 additions.

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

sum(sum(A)) will require (N-1)*M + M-1 = N*M-1 additions.

这两种方法都需要相同数量的加法运算,所以对于大型数组,即使解释器不够聪明,无法识别出它们都是同一个op,谁在乎呢?

Either method requires the same number of adds, so for a large array, even if the interpreter is not smart enough to recognize that they are both the same op, who cares?

这根本不是问题.不必为此担心.

It is simply not an issue. Don't make a mountain out of a mole hill to worry about this.

响应于Amro关于一种方法相对于另一种方法的错误的评论,您几乎无法控制.添加操作将以不同的顺序进行,但是无法保证哪个顺序会更好.

in response to Amro's comment about the errors for one method over the other, there is little you can control. The additions will be done in a different order, but there is no assurance about which sequence will be better.

A = randn(1000);
format long g

两个解决方案非常接近.实际上,与eps相比,差异不大.

The two solutions are quite close. In fact, compared to eps, the difference is barely significant.

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

假设您选择我提到的隔离和排序技巧.请注意,负零件和正零件将足够大,从而会失去精度.

Suppose you choose the segregate and sort trick I mentioned. See that the negative and positive parts will be large enough that there will be a loss of precision.

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

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

因此,无论如何,您确实确实需要将片段堆积在更高精度的阵列中.我们可以尝试一下:

So you really would need to accumulate the pieces in a higher precision array anyway. We might try this:

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

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

An interesting problem arises even in these tests. Will there be an issue because the tests are done on a random (normal) array? Essentially, we can view sum(A(:)) as a random walk, a drunkard's walk. But consider sum(sum(A)). Each element of sum(A) (i.e., the internal sum) is itself a sum of 1000 normal deviates. Look at a few of them:

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(:))运算可能会更准确一些.是这样吗?如果我们使用更高的精度进行累加怎么办?因此,首先,我将使用双精度值对列进行求和,然后将其转换为25位十进制精度,并对行求和. (我在这里只显示了20位数字,而保留了5位数字作为警卫数字.)

When we add them up, there will be a loss of precision. So potentially, the operation as sum(A(:)) might be slightly more accurate. Is it so? What if we use a higher precision for the accumulation? So first, I'll form the sum down the columns using doubles, then convert to 25 digits of decimal precision, and sum the rows. (I've displayed only 20 digits here, leaving 5 digits hidden as guard digits.)

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

或者,而是立即将其转换为25位精度,然后将结果求和.

Or, instead, convert immediately to 25 digits of precision, then summing the result.

sum(hpf(A(:))
945.76066810244749807

因此,这两种双精度形式在相反的方向上同样是错误的.最后,这都是没有实际意义的,因为与简单的变化sum(A(:))或sum(sum(A))相比,我展示的所有替代方案都更加耗时.只需选择其中一个就不用担心.

So both forms in double precision were equally wrong here, in opposite directions. In the end, this is all moot, since any of the alternatives I've shown are far more time consuming compared to the simple variations sum(A(:)) or sum(sum(A)). Just pick one of them and don't worry.

这篇关于在MATLAB中高效(最快)求和矩阵元素的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆