Iman
Iman

Reputation: 412

Efficient alternative for "ismember" function for arrays - MATLAB

if A is a series of points coordinate in 2D, for example:

>> A = [1 2; 3 4; 5 6; 7 8; 9 0];
A =
     1     2
     3     4
     5     6
     7     8
     9     0

and B contained two cells which each cell is a portion of 'A' and represented just with x values (first column), means:

>> B = {[3; 7];[5]}
B =
     [2x1 double]
     [     5    ]

I am looking for a solution to search B cells into A and give the coordinates of those points.

This is my code which is very slow for a large set of data:

C = cell (length(B) ,1)

for i = 1 : length(B)
     C{i} = A(ismember(A(:,1),B{i},'rows'),:);
end

C is the right answer and include 2 cells which are coordinates of each cell of B:

C = 
    [2x2 double]
    [1x2 double]

>> C{1}
ans =
     3     4
     7     8

and

>> C{2}
ans =
     5     6

Again, although C is the correct answer, I am looking for a more efficient solution. Probably cellfun?

Upvotes: 1

Views: 1501

Answers (2)

Amro
Amro

Reputation: 124563

Here is the cellfun version, although I doubt it is any faster than the loop (perhaps even slightly slower):

>> C = cellfun(@(b) A(ismember(A(:,1),b),:), B, 'Uniform',false)
C = 
    [2x2 double]
    [1x2 double]

>> C{:}
ans =
     3     4
     7     8
ans =
     5     6

Upvotes: 1

Divakar
Divakar

Reputation: 221514

You don't need to use 'rows' with ismember there. So, you can just do -

for k = 1 : numel(B)
    C{i}=A(ismember(A(:,1),B{k}),:);
end

Not sure if that would speedup your solution though.


As a second approach and this could be faster (not tested though), you can use bsxfun -

for k = 1 : numel(B)
    C{k} = A(any(bsxfun(@eq,A(:,1),B{k}.'),2),:);
end

Of course, before using either of the approaches, do pre-allocate with -

C = cell (numel(B) ,1)

Upvotes: 2

Related Questions