八度:矩阵中的多个子矩阵

时间:2010-04-26 20:26:03

标签: matlab matrix wolfram-mathematica octave submatrix

我有一个大矩阵,我希望从中收集一组子矩阵。如果我的矩阵是NxN且子矩阵大小是MxM,我想收集I=(N - M + 1)^2个子矩阵。换句话说,我希望原始矩阵中的每个元素都有一个MxM子矩阵,它可以位于这种矩阵的左上角。

这是我的代码:

for y = 1:I
    for x = 1:I
        index = (y - 1) * I + x;
        block_set(index) = big_mat(x:x+M-1, y:y+M-1)
    endfor
 endfor

输出如果a)错误,并且b)暗示big_mat(x:x+M-1, y:y+M-1)表达式中的某些东西可以得到我想要的东西,而不需要两个for循环。任何帮助将不胜感激

3 个答案:

答案 0 :(得分:5)

您的代码中似乎存在一些问题。如果我使用双循环,我就是这样做的:

M = someNumber;
N = size(big_mat,1); %# I assume big_mat is square here

%# you need different variables for maxCornerCoord and nSubMatrices (your I)
%# otherwise, you are going to index outside the image in the loops!
maxCornerCoord = N-M+1;
nSubMatrices = maxCornerCoord^2;

%# if you want a vector of submatrices, you have to use a cell array...
block_set = cell(nSubMatrices,1); 
%# ...or a M-by-M-by-nSubMatrices array...
block_set = zeros(M,M,nSubMatrices);
%# ...or a nSubMatrices-by-M^2 array
block_set = zeros(nSubMatrices,M^2);

for y = 1:maxCornerCoord
    for x = 1:maxCornerCoord
        index = (y - 1) * maxCornerCoord + x; 
        %# use this line if block_set is a cell array
        block_set{index} = big_mat(x:x+M-1, y:y+M-1);
        %# use this line if block_set is a M-by-M-by-nSubMatrices array
        block_set(:,:,index) = big_mat(x:x+M-1, y:y+M-1);
        %# use this line if block_set is a nSubMatrices-by-M^2 array
        block_set(index,:) = reshape(big_mat(x:x+M-1, y:y+M-1),1,M^2);
    endfor
 endfor

修改

我刚看到Octave有im2col的实现。因此,您可以将双循环重写为

%# block_set is a M^2-by-nSubMatrices array
block_set = im2col(big_mat,[M,M],'sliding');

%# if you want, you can reshape the result to a M-by-M-by-nSubMatrices array
block_set = reshape(block_set,M,M,[]);

这可能更快,并节省了大量的数字树。

答案 1 :(得分:1)

使用Mathematica: 此代码生成一个矩阵,其中每个元素都是MxM的矩阵,原始矩阵中的每个元素都位于此矩阵的左上角。

右侧和底部的矩阵元素用x填充。

Partition[big_mat, {M, M}, {1, 1}, {1, 1}, x]

实施例: alt text http://img130.imageshack.us/img130/6203/partitionf.png

如果你不使用x参数,那么它会定期自动采样。

答案 2 :(得分:0)

关于输出错误,可能是因为分配。您正在尝试将矩阵分配给矢量位置。尝试使用

block_set(:,:,index) = big_mat(x:x+M-1, y:y+M-1)

代替。