在元胞数组中搜索特定矩阵
Search particular matrix in cell array
所以,我的这个元胞数组在每个元胞中包含 n x 2 矩阵。这是示例数据:
[16 17;17 17]
<6x2 double>
<52x2 double>
[17 17;17 18]
[17 18;17 17]
我要做的是消除重复的矩阵(具有相同值或反转值的矩阵)。在这种情况下是 [17 18; 17 17](第 5 行),因为我们已经有了 [17 17; 17 18](第 4 行)
我尝试使用 unique 函数,但它说该函数只适用于字符串。我也试过用cellfun这样
找
cellfun(@(x) x==whatToSearch, lineTraced, 'UniformOutput', false)
但是它说 'Matrix dimension must agree'
提前致谢。
这是您想要的代码。
mydup = rand(5,2);
mycell = {mydup;mydup;rand(7,2);rand(3,2);rand(5,2)}
myNewCell = trimCell(mycell)
其中 trimCell
是下面的函数:
function myNewCell = trimCell(myCell)
exclude = false(size(myCell));
for iter = 1:size(myCell,1)
toCompare = myCell{iter};
comparisons = cellfun(@(x) all(size(x)==size(toCompare)) && myEquals(x, toCompare),myCell);
% comparisons has at least 1 true in it, because toCompare==toCompare
exclude(iter) = sum(comparisons)>1;
end
myNewCell = myCell(~exclude);
end
function boolValue = myEquals(x,y)
assert(all(size(x)==size(y)));
boolValue = true;
for iter = 1:size(x,1)
thisRow = all(sort(x(iter,:))==sort(y(iter,:)));
boolValue = boolValue && thisRow;
if ~boolValue
return
end
end
end
基本上,此函数的作用是,对于单元格中的每个矩阵,它首先检查大小是否相等。如果大小不相等,那么我们就知道矩阵不相等,即使我们对行重新排序也是如此。
如果它们大小相同,那么我们需要在行重新排序后检查它们是否相等。这是通过函数 myEquals
实现的,该函数逐行检查并在比较它们之前对行进行排序。它在发现重新排序后不相等的第一行以 false
退出。
希望这对您有所帮助,
安德鲁
这是一个解决方案。给定矩阵的 m x 1
列元胞数组 C
,此代码删除等效的重复项。 (这里会删除第4和第5个矩阵,相当于第1个)
C{1} = magic(3);
C{2} = magic(4);
C{3} = magic(5);
C{4} = C{1};
C{5} = flipud(C{1});
myEq = @(A,B) isequal(A,B) | isequal(A,flipud(B)); %// equivalence operator tests for same or up-down flipped matrix
C = C(:); %// ensure the cell array is a column
Crep = repmat(C,1,size(C,1)); %// repeat cell array along rows to get a square
comp = cellfun(myEq,Crep,Crep'); %'//get a comparison matrix by comparing with transpose
comp = tril(comp) - eye(size(comp)); %// ignore upper triangle and diagonal
idx = find( sum(comp,2)==0 ); %// get index of matrices we want to keep
result = C(idx); %// get result
输出是删除第 4 个和第 5 个矩阵,留下前三个 magic
个矩阵:
>> result
result =
[3x3 double] [4x4 double] [5x5 double]
>> result{1}, result{2}, result{3}
ans =
8 1 6
3 5 7
4 9 2
ans =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
ans =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
所以,我的这个元胞数组在每个元胞中包含 n x 2 矩阵。这是示例数据:
[16 17;17 17]
<6x2 double>
<52x2 double>
[17 17;17 18]
[17 18;17 17]
我要做的是消除重复的矩阵(具有相同值或反转值的矩阵)。在这种情况下是 [17 18; 17 17](第 5 行),因为我们已经有了 [17 17; 17 18](第 4 行)
我尝试使用 unique 函数,但它说该函数只适用于字符串。我也试过用cellfun这样
找cellfun(@(x) x==whatToSearch, lineTraced, 'UniformOutput', false)
但是它说 'Matrix dimension must agree'
提前致谢。
这是您想要的代码。
mydup = rand(5,2);
mycell = {mydup;mydup;rand(7,2);rand(3,2);rand(5,2)}
myNewCell = trimCell(mycell)
其中 trimCell
是下面的函数:
function myNewCell = trimCell(myCell)
exclude = false(size(myCell));
for iter = 1:size(myCell,1)
toCompare = myCell{iter};
comparisons = cellfun(@(x) all(size(x)==size(toCompare)) && myEquals(x, toCompare),myCell);
% comparisons has at least 1 true in it, because toCompare==toCompare
exclude(iter) = sum(comparisons)>1;
end
myNewCell = myCell(~exclude);
end
function boolValue = myEquals(x,y)
assert(all(size(x)==size(y)));
boolValue = true;
for iter = 1:size(x,1)
thisRow = all(sort(x(iter,:))==sort(y(iter,:)));
boolValue = boolValue && thisRow;
if ~boolValue
return
end
end
end
基本上,此函数的作用是,对于单元格中的每个矩阵,它首先检查大小是否相等。如果大小不相等,那么我们就知道矩阵不相等,即使我们对行重新排序也是如此。
如果它们大小相同,那么我们需要在行重新排序后检查它们是否相等。这是通过函数 myEquals
实现的,该函数逐行检查并在比较它们之前对行进行排序。它在发现重新排序后不相等的第一行以 false
退出。
希望这对您有所帮助, 安德鲁
这是一个解决方案。给定矩阵的 m x 1
列元胞数组 C
,此代码删除等效的重复项。 (这里会删除第4和第5个矩阵,相当于第1个)
C{1} = magic(3);
C{2} = magic(4);
C{3} = magic(5);
C{4} = C{1};
C{5} = flipud(C{1});
myEq = @(A,B) isequal(A,B) | isequal(A,flipud(B)); %// equivalence operator tests for same or up-down flipped matrix
C = C(:); %// ensure the cell array is a column
Crep = repmat(C,1,size(C,1)); %// repeat cell array along rows to get a square
comp = cellfun(myEq,Crep,Crep'); %'//get a comparison matrix by comparing with transpose
comp = tril(comp) - eye(size(comp)); %// ignore upper triangle and diagonal
idx = find( sum(comp,2)==0 ); %// get index of matrices we want to keep
result = C(idx); %// get result
输出是删除第 4 个和第 5 个矩阵,留下前三个 magic
个矩阵:
>> result
result =
[3x3 double] [4x4 double] [5x5 double]
>> result{1}, result{2}, result{3}
ans =
8 1 6
3 5 7
4 9 2
ans =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
ans =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9