matlab中不使用循环的逐行setdiff

matlab中不使用循环的逐行setdiff,matlab,matrix,vectorization,Matlab,Matrix,Vectorization,假设我们有两个矩阵 A = [1,2,3; 2,4,5; 8,3,5] B= [2,3; 4,5; 8,5] 如何在不使用循环或cellfun的情况下分别对A和B中的每一行执行sediff,换句话说,对所有I执行setdiff(A(I,:),B(I,:)。对于这个例子,我想得到 [1; 2; 3] 我试图为我的流体模拟器的两个非常大的矩阵做这个,因此我不能在性能上妥协 更新: 您可以假设答案的第二维度(列数)是固定的,例如答案始终是一些n×m矩阵

假设我们有两个矩阵

A = [1,2,3;
     2,4,5;
     8,3,5]
B=  [2,3;
     4,5;
     8,5]
如何在不使用循环或cellfun的情况下分别对A和B中的每一行执行
sediff
,换句话说,对所有
I
执行
setdiff(A(I,:),B(I,:)
。对于这个例子,我想得到

[1;
 2;
 3]
我试图为我的流体模拟器的两个非常大的矩阵做这个,因此我不能在性能上妥协

更新:

您可以假设答案的第二维度(列数)是固定的,例如答案始终是一些n×m矩阵,而不是一些不同列大小的不规则数组

另一个例子:

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

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

C = [1,4,5;
     8,7,6]
方法#1使用-

样本运行-

>> 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

方法#2使用和-


一行中每个此类运行的元素数可能具有不同的元素数,除非您有一些约束,使每个行运行的此类已设置元素数相同。那么,您打算如何存储这种不规则的数组呢?我同意Divakar的观点,cellfun将是一种方式,因为您的输出假定是一个单元格数组。我将解决我的问题。在我的例子中,答案的第二维度对于所有行都是固定的。在任何其他情况下,你们都是对的。第二维度永远是一吗?你能不能再举一个例子?它包含零吗?第二维度不包含零,因为我正在处理索引矩阵(从1到m)。bsxfun比循环快吗?因为举例来说,cellfun在使用预定义函数时速度更快。@dontcarebar这在很大程度上取决于可用的系统RAM和所涉及的输入尺寸。最好的办法是测试。但由于我们处理的是关系运算符,我认为这肯定会提高性能,除非您的输入将bsxfun扩展到极限。@DontCarebar请参阅有关bsxfun关系运算符的一些基准。@DontCarebar查看新添加的方法?@DontCarebar Hmm,很好!!谢谢你收到这些号码!嗯,bsxfun FTW!;)
>> 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
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)).'