在 MATLAB 中进行"symmetrical"行检测



我有整数矩阵A (nA x c),列数为偶数(例如mod(c,2) = 0( 和唯一行。 如何有效地(通过速度和内存优化函数symmetricRows(找到矩阵AiA1iA2的"对称"行,其中"对称"行iA1iA2定义为:

all(A(iA1,1:end/2) == A(iA2,end/2+1:end) & A(iA1,end/2+1:end) == A(iA2,1:end/2),2) = true

示例 ((:

A = [1 1 1 1; 
2 2 2 2; 
1 2 3 4;
4 3 2 1; 
2 2 3 3; 
3 4 1 2;  
3 3 2 2]
[iA1, iA2] = symmetricRows(A)
iA1 =
1
2
3
5       
iA2 =
1
2
6
7

矩阵的典型大小AnA ~ 1e4 to 1e6c ~ 60 to 120

该问题的动机是大型数据集的预处理,其中"对称"行与用户定义的距离度量无关。

示例2:要准备更大的测试数据集,可以使用此功能,然后,例如:

N = 10;    
A = allcomb([1:N],[1:N],[1:N],[1:N]);
iA = symmetricRows(A)

如果您有统计工具箱:

d = ~pdist2(A(:,1:end/2), A(:,end/2+1:end));
[iA1, iA2] = find(triu(d & d.'));

如果您有足够的内存,您可以使用隐式扩展来创建比较的 3D 矩阵。

AL = A(:,1:end/2);
AR = A(:,end/2+1:end);
AcompLR = squeeze( all( AL == reshape( AR.', 1, 2, [] ), 2 ) ); 
AcompRL = squeeze( all( reshape( AL.', 1, 2, [] ) == AR, 2 ) ); 
[iA(:,1), iA(:,2)] = find( AcompLR & AcompRL );
iA = unique( sort(iA,2), 'rows' );

这将返回iA其中第 1 列是iA1列,第 2 列是iA2

请注意,我需要unique来避免反向匹配,即[5,7]/[7,5]

我没有做过任何基准测试,但这可能比循环更快,因为它都是在单个操作中完成的。相反,我们可以聪明地进行索引,只做必要的比较,这将节省内存和调用unique

% Create row indices to cover all combinations of rows
rIdx = arrayfun( @(x) [ones(x,1)*x,(1:x).'], 1:size(A,1), 'uni', 0 );
rIdx = vertcat( rIdx{:} );
% Logical indexing comparisons
iA = rIdx( all( A( rIdx(:,1), 1:end/2 ) == A( rIdx(:,2), end/2+1:end ), 2 ) & ...
all( A( rIdx(:,2), 1:end/2 ) == A( rIdx(:,1), end/2+1:end ), 2 ), : );

相关内容

  • 没有找到相关文章

最新更新