Cjen1
Cjen1

Reputation: 1746

Efficient ways to find minimum of subset of elements

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

Answers (2)

Cjen1
Cjen1

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

Luis Mendo
Luis Mendo

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

Related Questions