Reputation: 1746
I'm trying to find the minimum of each row in a matrix excluding specific elements in those rows.
Specifically in a given row I have precomputed those elements which I want to include given in valid(i,:)
.
What is the right way to do this, here are the options I've thought of:
for i = 1:n
res(i) = min(x(i, 1, valid(i,:)), [], 3);
...
end
From what I know about matlab this would be more efficient:
res = min(x(:, 1, valid), [], 3);
However this will apply only a single filter to the 3rd dimension...
Upvotes: 2
Views: 170
Reputation: 1746
Having played with this for a bit it turns out to be extremely efficient to exploit the way that matlab treats NaN
values.
Specifically in this case:
xp = x;
xp(~valid) = NaN;
res = min(xp,[],3);
This has given an approximate conservative speedup of 100x, since the previous version (explicitly looping through) each iteration took ~10s and now 100 iterations take ~5s.
Note: there is an edge case where if there aren't any valid elements then you end up with NaN
as the result for that row.
Upvotes: 1
Reputation: 112769
You can do it with accumarray
as follows. Not sure if it will be faster than your answer:
[~, jj] = find(valid); % column indices, to be used as grouping variable
res = accumarray(jj, x(valid), [size(x,2) 1], @min, NaN); % NaN used as fill value
Upvotes: 1