Reputation: 593
Problem Statement
I want to improve the speed of my code which has a lot of for-loops in the following manner. A programmer I talked to on a meeting mentioned that boolean operations in matlab work faster then for loops (sorry I am not a programmer, so if I am wrong please tell me).
I have multiple loops which are similar to this:
for k= 1:length(source);
kk=source(1,k);
E(find(E(:,2)==kk),3)=0;
end
What I try to achieve with this loop
With this loop i want to find all values in the second column of E which are equal to the values in source. And in the rows where i find the values in the second column i want to set the third column to zero.
Question Is there a way to write this as a matlab boolean matrix operation ? Or is there another way to improve the coding to improve the speed of these kinds of short for-loops?
Upvotes: 2
Views: 99
Reputation: 65460
In this situation, you basically want to find all rows in column 2 that are in the source
array and set them equal to 0
. You can use ismember
to check if items in one array are within another. It will return a logical array the size of the first input that is 1
when the item was found in the second input and 0
otherwise.
% Figure out which rows of E(:,2) contain a value that exists in source
tf = ismember(E(:,2), source);
This logical array (tf
) tells us which rows of E
we want to set to 0
. We can use this variable as the first subscript (row) and then we want to specify column 3
as the second subscript of the assignment.
% Set these rows (at column 3) equal to 0
E(tf, 3) = 0;
Side-note
In the solution above, we completely eliminated the for loop. This isn't always possible. In your case, if we couldn't remove the loop, we could at least remove find
to speed some things up. This is because E(:,2) == k
will yield a logical matrix that we can use directly as the first subscript in the assignment. There is no need for find
. Logical indexing is always going to be faster than find
.
E(E(:,2) == k, 3) = 0;
Upvotes: 3