Logical Indexing and Vectorization
A comparison on an array gives a logical mask of the same size; indexing with the mask selects the elements where it is true:
Concept
A comparison on an array gives a logical mask of the same size; indexing with the mask selects the elements where it is true:
Combine masks with &, |, ~. find(mask) returns the positions; nnz(mask) counts trues; any/all summarize.
Vectorized code applies an operation to whole arrays instead of looping over elements: element-wise operators (.*, ./, .^), array functions (sum, cumsum, diff, max), logical indexing and implicit expansion. Benefits: shorter, usually faster, closer to the math.
When a loop is unavoidable, preallocate the output (zeros, ones, cell, strings) — growing an array element by element forces MATLAB to reallocate and copy repeatedly.
mask = v > 12; % [0 1 1 0 ...]
v(mask) % elements greater than 12
v(mask) = 12; % modify only thoseWhy It Matters
Cleaning measurement data (removing outliers, clamping, selecting time windows) and fast processing of large datasets both depend on logical indexing and vectorization — this is the MATLAB way of thinking.
Syntax
x(x < 0) = 0; % clamp negatives
idx = find(t >= 2 & t <= 5); % time window
d = sqrt(sum(P .^ 2, 2)); % row norms without a loop
result = zeros(1, n); % preallocate before a loopExample
13.1 Masks, clamping, vectorized computations and preallocation
v = [12.6 10.9 13.1 15.2 11.4 12.9];
ok = v >= 11.5 & v <= 14.8 % logical mask
fprintf('in-range readings: %s\n', mat2str(v(ok)))
fprintf('out-of-range count: %d, indices: %s\n', nnz(~ok), mat2str(find(~ok)))
v(v > 14.8) = 14.8; % clamp in place
fprintf('clamped: %s\n', mat2str(v))
fprintf('any(v < 11) = %d, all(v > 10) = %d\n', any(v < 11), all(v > 10))
M = magic(4);
M(M > 10) = 0;
disp('magic(4) with values > 10 zeroed:'), disp(M)
% vectorized versus loop: distance of 3-D points from the origin
P3 = [3 4 0; 1 2 2; 0 0 5];
d = sqrt(sum(P3 .^ 2, 2))';
fprintf('distances: %s\n', mat2str(d))
% cumulative logic without loops
speed = [0 20 45 80 60 30 0];
accelerating = [false diff(speed) > 0];
fprintf('accelerating samples: %s\n', mat2str(find(accelerating)))
% preallocation matters for loops that must stay loops
N = 1e5;
tic; a = []; for k = 1:N, a(k) = k; end; t1 = toc;
tic; b = zeros(1, N); for k = 1:N, b(k) = k; end; t2 = toc;
fprintf('growing array vs preallocated: equal %d, preallocated faster: %d\n', isequal(a, b), t2 < t1)Expected Result
The mask selected the in-range readings, and v(v > 14.8) = 14.8 clamped the high value in place. The distances of three 3-D points came from one expression. Preallocating produced the same array faster than growing it element by element.
ok =
1 0 1 0 0 1
in-range readings: [12.6 13.1 12.9]
out-of-range count: 3, indices: [2 4 5]
clamped: [12.6 10.9 13.1 14.8 11.4 12.9]
any(v < 11) = 1, all(v > 10) = 1
magic(4) with values > 10 zeroed:
0 2 3 0
5 0 10 8
9 7 6 0
4 0 0 1
distances: [5 3 5]
accelerating samples: [2 3 4]
growing array vs preallocated: equal 1, preallocated faster: 1Common Mistakes
Using && with arrays (error) instead of &.
Using find when the logical mask itself would do (v(find(v > 0)) → v(v > 0)).
Forgetting that v(mask) returns a column when v is a matrix.
Vectorizing so aggressively that the code becomes unreadable.
Best Practices
Name masks (isValid, isHot) to make code self-explanatory.
Vectorize the obvious cases; keep loops for sequential algorithms, with preallocation.
Check sizes when combining masks from arrays of different shapes.
Interview Relevance
Very high for MATLAB roles: "what is logical indexing?", "what is vectorization and why is it faster?", "why preallocate?", "replace this loop with one line".
Practice Questions
Replace all negative values in a matrix by 0 in one line.
Count how many samples of a signal exceed its mean by more than 2 standard deviations.
Compute the pairwise distance matrix of 5 points using implicit expansion.
Rewrite a loop that sums 1/k^2 for k = 1..1000 in vectorized form.
Quick Quiz
Q1. (Multiple choice) v(v > 0) returns: A) The indices of positive elements B) The positive elements C) A logical mask D) An error Answer: B.
Q2. (Predict the output) How many readings were out of range in the example?
Answer: 3 (10.9, 15.2 and 11.4; verified).
Q3. (True/False) Preallocating with zeros changes the result of a loop that fills an array.
Answer: False. Same result (verified), just faster.
Q4. (Find the bug) if v > 0 && v < 10 with a vector v raises an error.
Answer: && needs scalars; use all(v > 0 & v < 10) (or any, depending on the intent).
Coding Challenge
Given a temperature log [88 91 96 97 99 94 101 102 103 98], use logical indexing (no loops) to find the number of samples above 95, their mean, and the indices where the temperature rises from one sample to the next.
T = [88 91 96 97 99 94 101 102 103 98];
hot = T > 95;
fprintf('%d samples above 95 C, mean %.2f C\n', nnz(hot), mean(T(hot)))
rising = find(diff(T) > 0) + 1;
fprintf('rising at samples %s\n', mat2str(rising))