matlab - 在 Matlab 中优化 for 循环
问题描述
我有三个矩阵,分别A
是 2 乘 3、2B
乘 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]。我的问题是非常大(10^6)的长度B
和Index
,这变得非常慢。有没有办法可以避免 for 循环或者我注定要失败?
解决方案
您可以预先构造索引矩阵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.
推荐阅读
- flutter - Flutter:重新编辑列表时卡片大小不会改变
- javascript - 使用 JavaScript 获取 HTML 表单数据
- excel - 如何通过切片器选择数组索引
- swift - 为什么顶部和底部都有边框
- adtf - 插件描述生成器的用法?
- flutter - 允许用户继续在单个 TextForm 字段中输入
- java - Android 将 ARCore frame.acquireCameraImage() 转换为 Bitmap 以进行 MLKit 对象检测
- javascript - 如何使用 Javascript 和 HTML 进行 img 移动?
- sqlalchemy - 使用 SqlAlchemy 表达式语言作为列的子查询
- r - 为什么在 bsplines 图中指定线型,结果图看起来像三维,一个点连接到多个其他点