【问题标题】:Optimize the code by omitting an unnecessary loop通过省略不必要的循环来优化代码
【发布时间】:2018-01-13 14:50:10
【问题描述】:

我想通过省略不必要的循环来优化一些示例,但我不知道如何。以下是示例:

%Subtract 7 from all elements on the matrix diagonal
    A=rand(100,100)*10;
    for i=1:100
        A(i,i)=A(i,i)-7;
    end
---
%Count the number of elements of matrix A which are bigger than the adequate elements of matrix B
    A=rand(100,100)*10;
    B=rand(100,100)*10;
    a_bigger=0;
    for i=1:100
       for j=1:100
          if A(i,j)>B(i,j)
             a_bigger=a_bigger+1;
          end
       end
    end
---
    %Create vector with sums of 100 natural numbers (so-called cumulative ``sum):
B=[1, 1+2, 1+2+3... 1+2+3+...+n]
    A=1:100;
    B=zeros(1,100);
    for i=1:100
       for j=1:i
          B(i)=B(i)+A(j);
       end
    end

我尝试用

解决第一个问题
n=100;
A=rand(n,n)*10;
x=ones(1,n)*7;
diag(x);
A=A-x;

但是,情况比现在更糟。运行代码需要更多时间。为什么是这样?有没有更快的方法来实现这一点?

我正在查看矢量化页面,并尝试使用find 函数来解决第二个问题。但是当我写代码时

A=rand(100,100)*10;
B=rand(100,100)*10;
a_bigger=0;
find(A);
find(B);
if find(A)>find(B)
    a_bigger = a_bigger + 1;
end
a_bigger

结果它给了我 0。我做错了什么?

【问题讨论】:

  • @CrisLuengo 我试图解决这些问题,但我不能。我试过 n=100; A=rand(n,n)*10; x=ones(1,n)*7;诊断(x); A=A-x;这是第一个,但它比现在更糟。这也是一个家庭作业,但只是家庭作业的一小部分。我想如果我能理解他们,我可以做剩下的事
  • 这个答案有什么问题?产生相同的结果并且没有循环。我认为您的问题与您发布的内容完全不同。你知道怎么做,但想知道为什么要这样做?在此处阅读有关矢量化的信息:mathworks.com/help/matlab/matlab_prog/vectorization.html
  • @CrisLuengo 正如我在标题中指出的那样,它还必须进行优化。所以我的代码在没有循环的情况下给出了相同的结果,但它无效。我整天都在矢量化页面上,但只有简单的例子,所以我无法解决问题。这就是我在这里写示例的原因
  • 我的意思是,您需要重新表述您的问题,听起来不像“为我做作业”,而更像是“我想了解为什么我被要求将其变成如果这不是更有效的矢量化形式”。展示你的计时测试。表明你一直在解决这个问题。这将是一个更有趣的问题。继续编辑您的问题,我会将我的反对票改为赞成票。
  • @CrisLuengo 现在可以了吗?

标签: matlab


【解决方案1】:

关于您的第一个问题:MATLAB 过去的循环速度比现在慢很多。但是,如果将n 增加到 1e5 或 1e6,您可能会发现矢量化代码更高效。

近期相关帖子:https://stackoverflow.com/a/48220174/7328782

而不是

x=ones(1,n)*7;

你可以的

x=repmat(7,1,n);

防止n不必要的乘法。

关于您的第二个问题:findif 不是这样工作的。但是你不需要使用任何一个:

I = A>B;

返回一个为真 (1) 的逻辑矩阵,其中 A 较大。您想计算其中的数量,可以通过两种方式进行:

a_bigger = sum(I(:));

a_bigger = sum(sum(I));

前者更快。它将矩阵重塑为列向量,然后将所有元素相加。第二种形式将每列的所有元素相加,然后将所有总和相加。

【讨论】:

  • 我遇到了一个错误,比如索引超出矩阵维度。无标题错误(第 4 行)a_bigger = sum(I(:));当我写 A=rand(100,100)*10; B=兰特(100,100)*10;我=A>B; a_bigger = sum(I(:));
  • 您是否定义了一个名为sum 的变量? clear sum 将是解决方案。
  • 谢谢。你也可以帮我做第三个吗?至少你能说我应该使用哪个功能吗?
  • 寻找cumsum
猜你喜欢
  • 2019-11-17
  • 2011-03-12
  • 1970-01-01
  • 2018-06-20
  • 2014-07-18
  • 2011-10-12
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多