【问题标题】:What are the ways to sum matrix elements in MATLAB?MATLAB中矩阵元素求和的方法有哪些?
【发布时间】:2009-11-12 12:52:20
【问题描述】:

给定矩阵:

A = [1 2 3; 4 5 6; 7 8 9];
  1. 如何使用 for 循环来计算矩阵中元素的总和?
  2. 使用函数sum 编写一行 MATLAB 命令来求和 A中的矩阵元素。

我的回答:

1)

for j=1:3,
    for i=j:3,
        A(i,:) = A(i,:)+A(j+1,:)+A(j+2,:)
    end
end

2)

sum(A)

这些是正确的答案吗?我不知道如何使用ifwhilefor。谁能给我解释一下?

【问题讨论】:

  • 这些都是非常简单的问题。在 Google 上花几分钟的时间学习无数教程之一,可以为我们其他人节省大量时间。
  • 尽量避免在 Matlab 中使用 for 循环来计算东西。除非你真的想让事情变得很慢或者没有其他办法。

标签: matlab matrix sum


【解决方案1】:

对于非常大的矩阵,使用sum(sum(A)) 可以比sum(A(:)) 更快:

>> A = rand(20000);
>> tic; B=sum(A(:)); toc; tic; C=sum(sum(A)); toc
Elapsed time is 0.407980 seconds.
Elapsed time is 0.322624 seconds.

【讨论】:

  • 不错的发现!实际上,对于几乎任何尺寸,它似乎都更快。即使对于rand(100),我的系统上的差异也很大。 (虽然不适用于rand(10000,1))。但是,由于它大约只有几分之一秒,对于大多数用途,我仍然建议使用更强大/更通用的sum(A(:))
  • @Dennis Jaheruddin 我更喜欢sum(sum(A)),因为它的计算效率更高。 sum(A(:)) 的唯一优点是它更易于阅读,但它将整个矩阵 A 重新编码为一个向量,因此计算量很大。
  • @MarioReutter 当然它的效率较低(如答案所示),但实际上我使用它的主要原因是它也适用于更高维度的矩阵。假设你有M=rand(3,3,3),现在比较sum(sum(M)))sum(M(:))
  • 更新:使用 Matlab 2015b,差异大约小一个数量级(0.193 秒 v. 0.185 秒)。
  • timeit(@()sum(sum(A)))/timeit(@()sum(A(:)))tictoc 更准确。
【解决方案2】:

1)

total = 0;
for i=1:size(A,1)
  for j=1:size(A,2)
    total = total + A(i,j);
  end
end

2)

total = sum(A(:));

【讨论】:

  • 如果你在实际使用 MATLAB 时使用 1) 而不是 2),那么你需要慢慢地死去;)
  • 虽然是正确答案,但我希望看到最新的答案来阻止循环。它们确实会导致缓慢而可怕的死亡......也许可以编辑它?
【解决方案3】:

第一个问题的另一个答案是使用 one for 循环并使用函数NUMELlinear indexing 执行到数组中以获取元素总数:

total = 0;
for i = 1:numel(A)
  total = total+A(i);
end

【讨论】:

    【解决方案4】:

    尽可能避免 for 循环。

    sum(A(:))
    

    很好,但是如果你有一些逻辑索引,你不能使用 (:) 但你可以写

    % Sum all elements under 45 in the matrix
    sum ( sum ( A *. ( A < 45 ) )
    

    因为 sum 对列求和,并对由第一个 sum 创建的行向量求和。请注意,这仅在矩阵为 2-dim 时才有效。

    【讨论】:

      【解决方案5】:

      最好的做法绝对是避免 Matlab 中的循环或递归。

      sum(A(:))sum(sum(A)) 之间。 根据我的经验,Matlab 中的数组似乎作为堆叠列向量存储在内存中的连续块中。所以 A 的形状在sum() 中并不重要。 (可以测试reshape()并检查在Matlab中reshaping是否很快。如果是,那么我们有理由相信数组的形状与数据的存储和操作方式没有直接关系。)

      因此,sum(sum(A)) 没有理由应该更快。如果 Matlab 实际创建一个行向量,首先记录 A 的每一列的总和,然后对各列求和,它会更慢。但我认为sum(sum(A)) 在用户中非常普遍。他们很可能将sum(sum(A)) 硬编码为单个循环,与sum(A(:)) 相同。

      下面我提供一些测试结果。在每个测试中,A=rand(size) 和 size 在显示的文本中指定。

      首先是使用tic toc。

      Size 100x100
      sum(A(:))
      Elapsed time is 0.000025 seconds.
      sum(sum(A))
      Elapsed time is 0.000018 seconds.
      
      Size 10000x1
      sum(A(:))
      Elapsed time is 0.000014 seconds.
      sum(A)
      Elapsed time is 0.000013 seconds.
      
      Size 1000x1000
      sum(A(:))
      Elapsed time is 0.001641 seconds.
      sum(A)
      Elapsed time is 0.001561 seconds.
      
      Size 1000000
      sum(A(:))
      Elapsed time is 0.002439 seconds.
      sum(A)
      Elapsed time is 0.001697 seconds.
      
      Size 10000x10000
      sum(A(:))
      Elapsed time is 0.148504 seconds.
      sum(A)
      Elapsed time is 0.155160 seconds.
      
      Size 100000000
      Error using rand
      Out of memory. Type HELP MEMORY for your options.
      
      Error in test27 (line 70)
      A=rand(100000000,1);
      

      下面是使用cputime

      Size 100x100
      The cputime for sum(A(:)) in seconds is 
      0
      The cputime for sum(sum(A)) in seconds is 
      0
      
      Size 10000x1
      The cputime for sum(A(:)) in seconds is 
      0
      The cputime for sum(sum(A)) in seconds is 
      0
      
      Size 1000x1000
      The cputime for sum(A(:)) in seconds is 
      0
      The cputime for sum(sum(A)) in seconds is 
      0
      
      Size 1000000
      The cputime for sum(A(:)) in seconds is 
      0
      The cputime for sum(sum(A)) in seconds is 
      0
      
      Size 10000x10000
      The cputime for sum(A(:)) in seconds is 
      0.312
      The cputime for sum(sum(A)) in seconds is 
      0.312
      
      Size 100000000
      Error using rand
      Out of memory. Type HELP MEMORY for your options.
      
      Error in test27_2 (line 70)
      A=rand(100000000,1);
      

      根据我的经验,两个计时器的意义都只有 0.1 秒。因此,如果您对 Matlab 计时器有类似的经验,则没有任何测试可以辨别 sum(A(:))sum(sum(A))

      我又尝试了几次我计算机上允许的最大尺寸。

      Size 10000x10000
      sum(A(:))
      Elapsed time is 0.151256 seconds.
      sum(A)
      Elapsed time is 0.143937 seconds.
      
      Size 10000x10000
      sum(A(:))
      Elapsed time is 0.149802 seconds.
      sum(A)
      Elapsed time is 0.145227 seconds.
      
      Size 10000x10000
      The cputime for sum(A(:)) in seconds is 
      0.2808
      The cputime for sum(sum(A)) in seconds is 
      0.312
      
      Size 10000x10000
      The cputime for sum(A(:)) in seconds is 
      0.312
      The cputime for sum(sum(A)) in seconds is 
      0.312
      
      Size 10000x10000
      The cputime for sum(A(:)) in seconds is 
      0.312
      The cputime for sum(sum(A)) in seconds is 
      0.312
      

      它们看起来是等价的。 任何一个都很好。但是sum(sum(A)) 要求您知道数组的维度是 2。

      【讨论】:

      • 有人可以帮我缩小密码框的大小吗? (如果可行的话。)
      • 第一个是与sum(sum(A))的比较,但其余的都是与sum(A)的比较...
      【解决方案6】:

      您正在尝试总结二维数组的所有元素

      在matlab中使用

      Array_Sum = sum(sum(Array_Name));

      【讨论】:

      • 虽然这不是错误的,但几个月前发布了具有相同信息的更好答案(尤其是 Mohsen 的)。
      猜你喜欢
      • 2012-07-02
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2013-09-20
      • 2014-02-07
      • 2016-08-13
      • 2013-03-14
      • 2015-01-08
      相关资源
      最近更新 更多