setdiff逐行而不在matlab中使用循环

Don*_*ear 4 matlab matrix vectorization

假设我们有两个矩阵

A = [1,2,3;
     2,4,5;
     8,3,5]
B=  [2,3;
     4,5;
     8,5]
Run Code Online (Sandbox Code Playgroud)

如何sediff在不使用循环或cellfun的情况下分别对A和B中的每一行执行,换句话说,setdiff(A(i,:),B(i,:))对所有人执行i.对于这个例子,我想得到

[1;
 2;
 3]
Run Code Online (Sandbox Code Playgroud)

我正在尝试为我的流体模拟器为两个非常大的矩阵做这个,因此我不能在性能上妥协.

更新:

你可以假设答案的第二个维度(列数)是固定的,例如答案总是一些n乘m矩阵而不是一些不同列大小的参差不齐的数组.

另一个例子:

在我的情况下,A和B分别是m乘3和m乘以2,答案应该是m乘1.对于这种情况的解决方案就足够了,但是对于大小为m的矩阵的一般解由n1,m乘以n2,答案为m by n3将非常有趣.另一个例子是

A = [1,2,3,4,5;
     8,4,7,9,6]
B = [2,3;
     4,9]
Run Code Online (Sandbox Code Playgroud)

答案是

C = [1,4,5;
     8,7,6]
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 5

方法#1使用bsxfun-

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

样品运行 -

>> 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
Run Code Online (Sandbox Code Playgroud)

方法#2使用diffsort-

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)).'
Run Code Online (Sandbox Code Playgroud)

  • @DontCareBear它很大程度上取决于可用的系统RAM和所涉及的输入维度.最好的方法是测试.但由于我们正在处理关系运算符,我认为这肯定会提升性能,除非你的输入将bsxfun扩展到极限. (2认同)