matlab矩阵求子矩阵的一般方法 [英] General method to find submatrix in matlab matrix
问题描述
我正在寻找一种在较大矩阵(任意维数)中找到矩阵(模式)的好"方法.
I am looking for a 'good' way to find a matrix (pattern) in a larger matrix (arbitrary number of dimensions).
示例:
total = rand(3,4,5);
sub = total(2:3,1:3,3:4);
现在我希望这发生:
loc = matrixFind(total, sub)
在这种情况下,loc
应该变成 [2 1 3]
.
In this case loc
should become [2 1 3]
.
现在我只想找到一个点(如果存在)而不担心四舍五入问题.可以假设 sub
'适合' total
.
For now I am just interested in finding one single point (if it exists) and am not worried about rounding issues. It can be assumed that sub
'fits' in total
.
这是我如何为 3 维做这件事,但感觉有更好的方法:
Here is how I could do it for 3 dimensions, however it just feels like there is a better way:
total = rand(3,4,5);
sub = total(2:3,1:3,3:4);
loc = [];
for x = 1:size(total,1)-size(sub,1)+1
for y = 1:size(total,2)-size(sub,2)+1
for z = 1:size(total,3)-size(sub,3)+1
block = total(x:x+size(sub,1)-1,y:y+size(sub,2)-1,z:z+size(sub,3)-1);
if isequal(sub,block)
loc = [x y z]
end
end
end
end
<小时>
我希望为任意数量的维度找到一个可行的解决方案.
I hope to find a workable solution for an arbitrary number of dimensions.
推荐答案
这里是低性能,但(据说)任意维函数.它使用 find
在 total
中创建潜在匹配位置的(线性)索引列表,然后只检查 total
的适当大小的子块匹配 sub
.
Here is low-performance, but (supposedly) arbitrary dimensional function. It uses find
to create a list of (linear) indices of potential matching positions in total
and then just checks if the appropriately sized subblock of total
matches sub
.
function loc = matrixFind(total, sub)
%matrixFind find position of array in another array
% initialize result
loc = [];
% pre-check: do all elements of sub exist in total?
elements_in_both = intersect(sub(:), total(:));
if numel(elements_in_both) < numel(unique(sub))
% if not, return nothing
return
end
% select a pivot element
% Improvement: use least common element in total for less iterations
pivot_element = sub(1);
% determine linear index of all occurences of pivot_elemnent in total
starting_positions = find(total == pivot_element);
% prepare cell arrays for variable length subscript vectors
[subscripts, subscript_ranges] = deal(cell([1, ndims(total)]));
for k = 1:length(starting_positions)
% fill subscript vector for starting position
[subscripts{:}] = ind2sub(size(total), starting_positions(k));
% add offsets according to size of sub per dimension
for m = 1:length(subscripts)
subscript_ranges{m} = subscripts{m}:subscripts{m} + size(sub, m) - 1;
end
% is subblock of total equal to sub
if isequal(total(subscript_ranges{:}), sub)
loc = [loc; cell2mat(subscripts)]; %#ok<AGROW>
end
end
end
这篇关于matlab矩阵求子矩阵的一般方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!