一种方法是首先使用函数IM2COL找到矩阵的所有唯一m-by-m子矩阵,然后使用函数SORT对每一列进行降序排序,然后最后提取顶部n 行。如果你的初始矩阵是A,而你的输出矩阵是B,它会是这样的:
B = sort(im2col(A,[m m],'distinct'),1,'descend');
B = B(1:n,:); %# Get the top n values
请注意,B 将是一个 n-by-m^2 矩阵。如果你想把它变成一个p-by-q 单元格数组,你可以使用函数NUM2CELL 和RESHAPE:
nBlocks = ceil(size(A)./m); %# The number of blocks in each dimension
B = reshape(num2cell(B,1),nBlocks(1),nBlocks(2));
编辑:
如果您还想获取每个值相对于输入矩阵A 的索引,那就有点复杂了。您可以通过从SORT 获取第二个输出来做到这一点,在这种情况下,这将是每个m-by-m 子矩阵中值的线性索引。您可以使用函数IND2SUB 将它们转换为下标,然后移动行和列索引以说明每个m-by-m 块的位置:
[B,index] = sort(im2col(A,[m m],'distinct'),1,'descend');
B = B(1:n,:); %# Get the top n values
index = index(1:n,:); %# Get the top n values
[r,c] = ind2sub([m m],index); %# Convert linear indices to subscripts
nBlocks = size(A)./m; %# The number of blocks in each dimension
r = r+repmat(0:m:(nBlocks(1)-1)*m,n,nBlocks(2)); %# Shift the row indices
c = c+kron(0:m:(nBlocks(2)-1)*m,ones(n,nBlocks(1))); %# Shift the column indices
现在您可以使用函数MAT2CELL 和RESHAPE 将行索引、列索引和值一起收集到一个元胞数组中:
B = mat2cell([r(:) c(:) B(:)],n.*ones(1,size(B,2)));
B = reshape(B,nBlocks(1),nBlocks(2));
或者,您可以使用 NUM2CELL、STRUCT 和 RESHAPE 函数创建结构体数组而不是元胞数组:
B = struct('rowIndices',num2cell(r,1),...
'colIndices',num2cell(c,1),...
'values',num2cell(B,1));
B = reshape(B,nBlocks(1),nBlocks(2));
注意:
如果A 的维度不是m 的偶数倍,函数IM2COL 将用零填充部分块。如果此零填充中的任何一个出现在块的顶部 n 值中,则相应的行和列索引中的一个或两个将超出范围(即具有大于矩阵 @ 的该维度的大小的值987654356@)。因此,通过检查行索引和列索引是否在范围内,您可以确保在后续分析中不包括任何零填充。