Matlab中的for循环优化

3

我有三个矩阵,A 是 2 行 3 列,B 是 2 行 5 列,Index 是 3 行 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]。我的问题是:BIndex非常大(长度为10^6),导致这个过程非常缓慢。有没有办法避免使用for循环或者我注定要这么做?
1个回答

4
您可以使用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.

1
你使用的MATLAB版本是什么?索引中存在双重间接,但我仍然惊讶于它需要这么长时间才能运行。矢量化解决方案使用了更多的内存,因此可能会被认为速度较慢。 - Cris Luengo
@CrisLuengo 我正在使用 R2021a 在线版。昨晚它经常变得缓慢/崩溃,所以我猜可能出了些问题。我刚才又试了一下,速度在两个方面都更快了。 - tdy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接