"symmetrical" matlab中的行检测
"symmetrical" rows detection in matlab
我的整数矩阵 A (nA x c)
具有偶数列(例如 mod(c,2) = 0
)和唯一行。
如何有效地(通过速度和内存优化函数 symmetricRows
)找到矩阵 A
、iA1
和 iA2
的 "symmetrical" 行,其中 "symmetric"行 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
问题是由大型数据集的预处理引起的,其中 "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.'));
我的整数矩阵 A (nA x c)
具有偶数列(例如 mod(c,2) = 0
)和唯一行。
如何有效地(通过速度和内存优化函数 symmetricRows
)找到矩阵 A
、iA1
和 iA2
的 "symmetrical" 行,其中 "symmetric"行 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
问题是由大型数据集的预处理引起的,其中 "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.'));