 2 3
Now let's see what I get if I use the subscripts to address the selected elements:
ans = 0 3 -3 2 0 -2 -1 1 0
I get the full matrix back, even though I selected only 3 elements. This definitely surprised me when I first encountered this. What's happening?
MATLAB matches each row element with each column element. matrix([1 2 3],2) returns the elements from rows 1 through 3 in column 1.
ans = 1 0 3
To learn more about indexing in general, you might want to read these posts or search the MATLAB documentation.
Here we used the single output form of find which returns indices instead of subscripts.
indA = find(A > (17^2)/2); Result2 = zeros(size(A)); Result2(indA) = A(indA); isequal(Result, Result2)
ans = 1
We'll try keeping about half of the elements unchanged.
keepA = (A > (17^2)/2); Result3 = zeros(size(A)); Result3(keepA) = A(keepA); isequal(Result, Result3)
ans = 1
keepA is a logical matrix the same size as A. I use logical indexing to populate Result3 with the chosen values from A.
If instead we have a list of candidates to set to 0, we have an easier time since we don't need to start off with a matrix of zeros. Instead we start with a copy of A.
Result4 = A; [rnotA,cnotA] = find(A <= (17^2)/2);
Convert indices to subscripts, as in method #1.
indices = sub2ind(size(A),rnotA,cnotA);
Now zero out the selected matrix elements.
Result4(indices) = 0; isequal(Result, Result4)
ans = 1
If we're instead given indices, we simply skip the step of converting subscripts and follow similar logic to that in method #4.
Result5 = A; indnotA = find(A <= (17^2)/2); Result5(indnotA) = 0; isequal(Result, Result5)
ans = 1
Finally, if we have a mask for the values to set to 0, we simply use it to select and set elements.
Result6 = A; keepnotA = (A <= (17^2)/2); Result6(keepnotA) = 0; isequal(Result, Result6)
ans = 1
Which method or methods do you naturally find yourself using? Do you ever invert the logic of your algorithm to fit your way of thinking about addressing the data (the ins or the outs)? Please post your thoughts here. I look forward to seeing them.
Get the MATLAB code
Published with MATLAB® 7.6
32 CommentsOldest to Newest
I definitely prefer the use of logical index, because the it’s more explicit. I think the code stay more readable. It’s something that I miss on other lenguajes.
It depends on the algorithm whether logical or numerical indexing is most suitable.
When I need a list of indices several times because I don’t want to create new variables, a list of numerical indices is shorter than a logical matrix. Also, when the positions of selected elements are of interest, a list of numerical indices is better, because subscripts are easy to calculate from numerical indices.
In other cases there is the warning “logical indexing is usually faster than find”. Then I use logical indexing.
Personally, I have started to use logical indexing as much as possible. What I like about logical indexing is that I can plot the data and the mask in the same plot and clearly see what I am removing and what I am not removing.
Thanks to all of you. For a long time, it seemed like people weren’t learning about logical indexing but now people are. I think that’s good
(but, as OkinawaDolphin says, not always optimal when the indices need to hang around for several operations and the array is large compared to the number of values of interest).
nowadays I do use logical indexing (with the exception that OkinawaDolphin pointed out). But the ONE thing which prevented me from using logical indexing from the beginning is the following.
When I saw the result of the following operations
> a = [1 2 3 4 5]
> i1 = (a > 3)
0 0 0 1 1
and when I realized that I can use this array in the following way (for logical indexing):
I thought I can create the logical arrays by hand and use them:
> i2 = [0 0 0 1 1]
??? Subscript indices must be real positive integers or logicals.
Of course, now I know that i2 created that way is real array which cannot be used as a mask and that the right way is
Trivial. But for me, this was the reason why I tended to use indices and 