简体   繁体   中英

setdiff row by row without using loops in matlab

Let's say we have two matrices

A = [1,2,3;
     2,4,5;
     8,3,5]
B=  [2,3;
     4,5;
     8,5]

How do I perform sediff for each row in A and B respectively without using loops or cellfun, in other words performing setdiff(A(i,:),B(i,:)) for all i . For this example I want to get

[1;
 2;
 3]

I am trying to do this for two very big matrices for my fluid simulator, thus I can't compromise on performance.

UPDATE:

you can assume that the second dimension (number of columns) of the answer will be fixed eg the answer will always be some n by m matrix and not some ragged array of different column sizes.

Another Example:

In my case A and B are m by 3 and m by 2 respectively and the answer should be m by 1. A solution for this case will suffice, but a general solution for matrices of size m by n1, m by n2 with answer of m by n3 will be very interesting. another example is

A = [1,2,3,4,5;
     8,4,7,9,6]
B = [2,3;
     4,9]

And the answer is

C = [1,4,5;
     8,7,6]

Approach #1 Using bsxfun -

mask = all(bsxfun(@ne,A,permute(B,[1 3 2])),3);
At = A.'; %//'
out = reshape(At(mask.'),[],size(A,1)).'

Sample run -

>> A
A =
     1     2     3     4     5
     8     4     7     9     6
>> B
B =
     2     3
     4     9
>> mask = all(bsxfun(@ne,A,permute(B,[1 3 2])),3);
>> At = A.'; %//'
>> out = reshape(At(mask.'),[],size(A,1)).'
out =
     1     4     5
     8     7     6

Approach #2 Using diff and sort -

sAB = sort([A B],2)
dsAB = diff(sAB,[],2)~=0

mask1 = [true(size(A,1),1) dsAB]
mask2 = [dsAB true(size(A,1),1)]

mask = mask1 & mask2
sABt = sAB.'

out = reshape(sABt(mask.'),[],size(A,1)).'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM