"symmetrical" matlab中的行检测

"symmetrical" rows detection in matlab

我的整数矩阵 A (nA x c) 具有偶数列(例如 mod(c,2) = 0)和唯一行。 如何有效地(通过速度和内存优化函数 symmetricRows)找到矩阵 AiA1iA2 的 "symmetrical" 行,其中 "symmetric"行 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

问题是由大型数据集的预处理引起的,其中 "symmetrical" 行与用户定义的距离度量点无关。

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

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

如果你有足够的内存,你可以通过隐式扩展来创建一个 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' );

此 returns 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 ), : );

如果您有统计工具箱:

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