问题陈述
我希望以下列方式提高代码的速度,该代码有很多for循环。我在一次会议上谈到的程序员提到matlab中的布尔运算比循环更快(抱歉,我不是程序员,所以如果我错了请告诉我)。
我有多个与此类似的循环:
for k= 1:length(source);
kk=source(1,k);
E(find(E(:,2)==kk),3)=0;
end
我尝试通过此循环实现的目标
通过这个循环,我想找到E的第二列中的所有值,它们等于source中的值。在我找到第二列中的值的行中,我想将第三列设置为零。
问题 有没有办法把它写成matlab布尔矩阵运算?还是有另一种方法可以改进编码以提高这类短循环的速度吗?
答案 0 :(得分:3)
在这种情况下,您基本上希望查找第2列中source
数组中的所有行,并将它们设置为0
。您可以使用ismember
检查一个数组中的项是否在另一个数组中。当第二个输入中找到该项时,它将返回第一个输入大小为1
的逻辑数组,否则返回0
。
% Figure out which rows of E(:,2) contain a value that exists in source
tf = ismember(E(:,2), source);
此逻辑数组(tf
)告诉我们要将E
哪些行设置为0
。我们可以将此变量用作第一个下标(行),然后我们要将列3
指定为赋值的第二个下标。
% Set these rows (at column 3) equal to 0
E(tf, 3) = 0;
<强>侧面注意
在上面的解决方案中,我们完全消除了for循环。这并不总是可行的。在您的情况下,如果我们无法删除循环,我们至少可以删除find
以加快某些速度。这是因为E(:,2) == k
将产生一个逻辑矩阵,我们可以直接使用 作为赋值中的第一个下标。不需要find
。逻辑索引总是比find
快。
E(E(:,2) == k, 3) = 0;