bza*_*zak 14 matlab runtime matrix vectorization
如何避免循环减少此代码的计算时间(我的上一个问题的一个解决方案):
我希望找到A(1:3,:)其对应值的列向量M(4,:)不是该单元的一个向量的一部分X(并且显然不等于这些向量之一).如果X非常大,我会寻找快速解决方案.
M = [1007 1007 4044 1007 4044 1007 5002 5002 5002 622 622;
552 552 300 552 300 552 431 431 431 124 124;
2010 2010 1113 2010 1113 2010 1100 1100 1100 88 88;
7 12 25 15 12 30 2 10 55 32 12];
Run Code Online (Sandbox Code Playgroud)
我直接在这里A:
A = [1007 4044 5002 622;
552 300 431 124;
2010 1113 1100 88];
Run Code Online (Sandbox Code Playgroud)
A 包含唯一的列向量 M(1:3,:)
X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12]};
[~, ~, subs] = unique(M(1:3,:)','rows');
A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});
%// getting a mask of which columns we want
idxC(length(A4)) = false;
for ii = 1:length(A4)
idxC(ii) = ~any(cellfun(@(x) all(ismember(A4{ii},x)), X));
end
Run Code Online (Sandbox Code Playgroud)
显示我们想要的列
out = A(:,idxC)
Run Code Online (Sandbox Code Playgroud)
结果:
>> out
out =
1007 4044
552 300
2010 1113
Run Code Online (Sandbox Code Playgroud)
列向量[5002;431;1100]被删除,因为[2;10;55]包含在X{2} = [2 10 55 9 17]
列向量[622;124;88]被删除,因为[32 12] = X{4}
另一个例子:与之相同X
M = [1007 4044 1007 4044 1007 5002 5002 5002 622 622 1007 1007 1007;
552 300 552 300 552 431 431 431 124 124 552 11 11;
2010 1113 2010 1113 2010 1100 1100 1100 88 88 2010 20 20;
12 25 15 12 30 2 10 55 32 12 7 12 7];
X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12]};
A = [1007 4044 5002 622 1077;
552 300 431 124 11;
2010 1113 1100 88 20];
Run Code Online (Sandbox Code Playgroud)
结果 :(用scmg回答)
如果A根据第一行排序我得到:(正确的结果)
out =
1007 1007 4044
11 552 300
20 2010 1113
Run Code Online (Sandbox Code Playgroud)
如果我不对矩阵进行排序A,我得到:(假结果)
out =
4044 5002 622
300 431 124
1113 1100 88
Run Code Online (Sandbox Code Playgroud)
A(:,4) = [622;124;88]应该删除列向量,因为[32 12] = X{4}.
[5002;431;1100]应该删除列向量,因为[2;10;55]它包含在X{2} = [2 10 55 9 17]
Ben Voigt 的答案很好,但这一行for A4i = A4{ii}是导致问题的原因:for 循环不适用于列向量:
%row vector
for i = 1:3
disp('foo');
end
foo
foo
foo
%column vector
for i = (1:3).'
disp('foo');
end
foo
Run Code Online (Sandbox Code Playgroud)
只要尝试一下A4i = A4{ii}.',它应该就能完成你的工作!
现在,如果我们看一下输出:
A(:,idxC) =
4044 5002
300 431
1113 1100
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,最终的结果并不是我们所期望的。
只要unique进行某种排序,子项就不会按照 A 中遇到的顺序编号,而是按照 C 中遇到的顺序编号(已排序):
subs =
2
2
3
2
3
2
4
4
4
1
1
Run Code Online (Sandbox Code Playgroud)
因此,您应该通过给出的矩阵而unique不是 A 来获得最终输出
进入
[C, ~, subs] = unique(M(1:3,:)','rows');
%% rather than [~, ~, subs] = unique(M(1:3,:)','rows');
Run Code Online (Sandbox Code Playgroud)
然后,要获得最终输出,请输入
>> out = C(idxC,:).'
out =
1007 4044
552 300
2010 1113
Run Code Online (Sandbox Code Playgroud)