Reputation: 109
I am trying to perform a row-wise "ismember" in MATLAB in order to find out where, in Set
, each element of Input
is.
Here is my work so far.
function lia = ismemberrow(Input, Set)
lia = false(size(Input)); % Pre-assign the output lia
for J = 1 : size(Input,1)
% The J-th row of "lia" is the list of locations of the
% elements of Input(J,:) in Set
lia(J,:) = find(ismember(Set, Input(J,:)));
end
end
For example, if the variables Input
and Set
are defined as follows
Input = [1 4;
4 2;
4 3;
2 4;
1 2;
3 2];
Set = [3 2 4 1];
The the output lia
of lia = ismemberrow(Input,Set)
will be:
lia = [4 3;
3 2;
3 1;
2 3;
4 2;
1 2];
My function works accurately so far, but this function is called many times in my project so I am thinking of that if I can reduce the for-loop so that it spends less time. May I have some opinions on it?
Upvotes: 3
Views: 371
Reputation: 125854
A single call to ismember
(no loop necessary) will give you what you want in the second output argument:
>> [~, lia] = ismember(Input, Set)
lia =
4 3
3 2
3 1
2 3
4 2
1 2
Upvotes: 4
Reputation: 15837
If your inputs are positive integers you simply can use indexing
m(Set)=1:numel(Set);
result = m(Input)
If the range of input is large you can use sparse matrix:
s = sparse(Set,1,1:numel(Set));
result = s(Input)
Result:
4 3
3 2
3 1
2 3
4 2
1 2
Upvotes: 1
Reputation: 112659
I'd go with ismember
as in @gnovice's answer. But here are some alternatives, just for the fun of it.
If the values in Input
are guaranteed to be in Set
:
[ind, ~] = find(bsxfun(@eq, Set(:), Input(:).'));
result = reshape(ind, size(Input));
If they are not guaranteed to be:
[ind, val] = max(bsxfun(@eq, Set(:), permute(Input, [3 1 2])));
result = permute(ind.*val, [2 3 1]);
Upvotes: 1