我有整数矩阵A (nA x c)
,列数为偶数(例如mod(c,2) = 0
( 和唯一行。 如何有效地(通过速度和内存优化函数symmetricRows
(找到矩阵A
、iA1
和iA2
的"对称"行,其中"对称"行iA1
和iA2
定义为:
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
矩阵的典型大小A
:nA ~ 1e4 to 1e6
、c ~ 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 ), : );