首页 > 解决方案 > 在 Matlab 中优化 for 循环

问题描述

我有三个矩阵,分别A是 2 乘 3、2B乘 5 和Index3 乘 5。

A = [1,3,5;2,4,6];
B = [5,3,3,5,3;6,4,4,6,4];
Index = logical([0,0,0,0,1;0,1,1,0,0;1,0,0,1,0]);

我正在尝试查看 B 中的每个列向量是否A与索引中找到的正确列向量匹配。我的代码如下。

error = 0;
for i = 1:size(B,2)
    if A(:,Index(:,i)) ~= B(:,i)
        error = error + 1;
    end
end

error在此循环结束时将为 1,因为中的最后一列B应该是 [1;2]。我的问题是非常大(10^6)的长度BIndex,这变得非常慢。有没有办法可以避免 for 循环或者我注定要失败?

标签: matlabfor-loopoptimization

解决方案


您可以预先构造索引矩阵A*Index,然后直接测试这两个矩阵:

>> error = sum(max(A*Index ~= B))

error =

     1

细节

分解,A*Index生成索引矩阵:

>> A*Index

ans =

     5     3     3     5     1
     6     4     4     6     2

然后可以直接与B

>> A*Index ~= B

ans =

  2×5 logical array

   0   0   0   0   1
   0   0   0   0   1

计时

R2021a Online 拥有 1000 万个索引,在 ~1 秒内运行矢量化版本,而循环则在 ~100 秒内运行:

>> B = repmat(B, 1, 1e7);
>> Index = repmat(Index, 1, 1e7);
>> tic
   error = sum(max(A*Index ~= B));
   toc

Elapsed time is 0.952846 seconds.
>> tic
   error = 0
   for i = 1:size(B,2)
       if A(:,Index(:,i)) ~= B(:,i)
           error = error + 1;
       end               
   end                           
   toc

Elapsed time is 98.666943 seconds.

推荐阅读