‘find’ instead of logicals for a long time.
Thanks for clarifying that the array must be of logical type for logical indexing.
I started using logical arrays a LOT more often after heeding the warnings and recommendations issued by ‘mlint’. Initially, I didn’t really believe logical arrays were that much more efficient, but profiling my code before and after has shown direct performance improvements.
I’ve always enjoyed using array indexing of all sorts (logical or otherwise) because it can be a very compact way of expressing an operation.
Here, for example, is a “logical array” method for removing row R and column C (both scalars) from a matrix X…
How cool is that ?
…how would you do the same thing if R and C were vectors ?
Actually, to answer Loren’s original question “Which Method(s) Do You Prefer?”, I have to say “none of the above”.
I often rely on the rather naughty mix of arithmetic and logical operations:
A .* (A > (17^2)/2)
…because it doesn’t require an assignment statement and can be used inline as part of a longer expression.
For myself, generally the answer to my preference depends on what I’m going to do with the selected elements. If I’m going to be doing something that can be vectorized (is “vectorizable”?) then I try to use logical arrays. If not, I tend to need the actual indices of the selected elements. As a related question, is there any way to determine which of the following will be faster (or even a rule of thumb)?
A=A(1:5000,1:100); %Explicityly stating the number of columns
some other method?
When I’m dealing with very large data sets, this is one of the most frustrating slow points, since it can exceed the time requirements of many of the calculations.
With regard to removing rows R and columns C from a matrix, you can use:
A = reshape(1:49, 7, 7);
B = A; % for comparison
R = 1:2:7; % Rows to remove
C = 2:2:7;
B(R, :) = ;
B(:, C) = ;
A = reshape(1:49, 7, 7);
R = 1:2:7; % Rows to remove
C = 2:2:7;
B = A(setxor(R, 1:7), setxor(C, 1:7));
B = A(setdiff(1:7, R), setdiff(1:7, C));
As for the arithmetic/logical combination, that will work … as long as all your elements of A are finite.
A = 1:1000;
B = A.*(A > (17^2)/2);
all(B == A | B == 0)
A = 1:1000;
A([5 982]) = NaN;
A([7 562]) = Inf;
A([324 870]) = -Inf;
B = A.*(A > (17^2)/2);
all(B == A | B == 0)
Note that not only are elements 5 and 982 of the second B NaN (as you would expect, since any arithmetic operation on a NaN results in a NaN result) but so are elements 324 and 870. This is because 0*Inf and 0*(-Inf) also both return NaN.
Nice reply to Tony’s challenge. You can use end’s in the expressions of your first solutions as well:
A = reshape(1:49, 7, 7); R = 1:2:7; % Rows to remove C = 2:2:7; B = A(setxor(R, 1:end), setxor(C, 1:end)); % or B = A(setdiff(1:end, R), setdiff(1:end, C));
I definitely prefer, and use as often as possible, logical indexing, possibly keeping the indices stored for future reference only if really needed.
It makes the code much more readable and, as I used to be programming with SQL languages, it exploits the semantic power of the WHERE clauses which are what make DB programming so powerful.
I tend to use all methods mentioned based on my need.
What I find interesting is how common a problem it is for (not necessarily beginner) users to run into the issue mentioned in Method #1. Often users are using subscripting and don’t realize they need to convert to linear indices to solve a specific problem.
I find myself having to repeatedly explain the difference and am glad you have addressed the topic here.
Thanks very much for this solution…
B = A(setdiff(1:end, R), setdiff(1:end, C));
Steve – very neat,
Loren – I had no idea I could use “end” in a function call !
…where’s that documented ?
Here’s the documentation for end:
The capability has been allowed, I believe, since its introduction as an index (and overloadable with the class system).
Logical indexing is nice, but not always practical. We produce hundreds of GB of data every day a subsequently load it into MATLAB. It’s possible to construct a short array of numerical i