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

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

问题描述

让矩阵 AA = 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.

任何一种方法都需要相同数量的加法,所以对于一个大数组,即使解释器不够聪明,无法识别它们都是同一个操作,谁在乎呢?

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天全站免登陆