在我的主脚本中,我试图消除具有相同元素的S
单元格数组。例如,如果您运行当前脚本(使用a=v=2
),那么您将获得S
的以下值:
S{1}(:, :, 1) = [0 0; 0 0]; S{1}(:, :, 2) = [0 0; 0 0];
S{2}(:, :, 1) = [0 0; 1 1]; S{2}(:, :, 2) = [0 1; 0 1];
S{3}(:, :, 1) = [0 1; 0 1]; S{3}(:, :, 2) = [0 0; 1 1];
S{4}(:, :, 1) = [1 0; 1 0]; S{4}(:, :, 2) = [1 1; 0 0];
S{5}(:, :, 1) = [1 1; 0 0]; S{5}(:, :, 2) = [1 0; 1 0];
S{6}(:, :, 1) = [1 1; 1 1]; S{6}(:, :, 2) = [1 1; 1 1];
代码应将S{2}
和S{3}
,S{4}
和S{5}
视为具有相同的子集。因此,我希望得到的结果应该是S{1}
,S{2}
,S{4}
和S{6}
。
我知道MATLAB有ismember
,isequal
等函数,但它们似乎不适用于单元格数组......或者我无法使它们正常工作。
是否有一种简洁的方法来处理目前正在编写的单元数组?
主脚本:
clear all
clc
a = 2;
v = 2;
R = dec2base(0:1:v^(v^a)-1, v)-'0';
cnt1 = 0;
cnt2 = 0;
for j=1:v^(v^a)
% List all degenerates in Psi1
V = FN_Break(a, v, R(j,:));
if V > 0 % Connector is degenerate
cnt1 = cnt1 + 1;
Psi1(cnt1,1) = j-1;
% Store all "breaks" into cell array S
S{cnt1} = FN_Break_T(a,v,R(j,:));
else % Connector is not degenerate
cnt2 = cnt2 + 1;
Psi2(cnt2,1) = j-1;
end
end
功能FN_Break
:
function [valU] = FN_Beak(a, v, R)
FreeAtomCtr = 0;
for j=0:v^a-1
for k=1:a
for l=1:a
B = dec2base(j,v,a);
atom(l,j+1) = str2num(B(l));
end
end
end
for j=1:a % Do this for each atom
cnt(1:v) = 0;
for k = 1:v^a % Do this for each position of each atom
for l=0:v-1 % Break this down for each value
if atom(j,k) == l
cnt(1+l) = cnt(1+l) + 1;
T(1+l, cnt(1+l),j) = R(k);
end
end
end
end
for j=1:a
B = unique(T(:,:,j), 'rows');
if dot(size(B), [1 0]) < v % does not depend on this atom
FreeAtomCtr = FreeAtomCtr + 1;
end
end
valU = FreeAtomCtr;
end
功能FN_Break_T
:
function [valU] = FN_Beak_T(a, v, R)
FreeAtomCtr = 0;
for j=0:v^a-1
for k=1:a
for l=1:a
B = dec2base(j,v,a);
atom(l,j+1) = str2num(B(l));
end
end
end
for j=1:a % Do this for each atom
cnt(1:v) = 0;
for k = 1:v^a % Do this for each position of each atom
for l=0:v-1 % Break this down for each value
if atom(j,k) == l
cnt(1+l) = cnt(1+l) + 1;
T(1+l, cnt(1+l),j) = R(k);
end
end
end
end
for j=1:a
B = unique(T(:,:,j), 'rows');
if dot(size(B), [1 0]) < v % does not depend on this atom
FreeAtomCtr = FreeAtomCtr + 1;
end
end
valU = T;
end
答案 0 :(得分:1)
一种方法可能是对您的组合进行哈希处理,并使用它们来比较单元格内容。您可以使用ismember
根据可能的组合(在本例中为4)索引对,然后使用sort
结果并使用unique
查找每个唯一(已排序)哈希的第一个实例
例如:
S{1}(:, :, 1) = [0 0; 0 0]; S{1}(:, :, 2) = [0 0; 0 0];
S{2}(:, :, 1) = [0 0; 1 1]; S{2}(:, :, 2) = [0 1; 0 1];
S{3}(:, :, 1) = [0 1; 0 1]; S{3}(:, :, 2) = [0 0; 1 1];
S{4}(:, :, 1) = [1 0; 1 0]; S{4}(:, :, 2) = [1 1; 0 0];
S{5}(:, :, 1) = [1 1; 0 0]; S{5}(:, :, 2) = [1 0; 1 0];
S{6}(:, :, 1) = [1 1; 1 1]; S{6}(:, :, 2) = [1 1; 1 1];
combinations = [0 0; 0 1; 1 0; 1 1];
% Assume array in every cell has the same shape
hash = zeros(size(S{1}, 1)*size(S{1}, 3), numel(S));
for ii = 1:numel(S)
[~, hash(:,ii)] = ismember([S{ii}(:, :)].', combinations, 'rows');
end
hash = sort(hash, 1).';
[~, keepidx] = unique(hash, 'rows');
S = S(keepidx);
给出了期望的S
(单元格1,2,4,6)
如果您想要嵌套重复项,可以使用以下命令:
hash = sort(hash, 1).';
[~, keepidx, uniqueidx] = unique(hash, 'rows');
bincounts = accumarray(uniqueidx, 1); % Count occurrences
for ii = 1:numel(bincounts)
if bincounts(ii) > 1
idx = find(uniqueidx == ii);
S{idx(1)} = S(idx); % Nest duplicates in first instance of duplicate
end
end
S = S(keepidx);
这使用unique
的第三个输出和accumarray
来获取每个唯一组合的出现次数。嵌套重复项,然后像以前一样修剪原始单元格数组。