Октава: несколько подматриц из матрицы - PullRequest
4 голосов
/ 27 апреля 2010

У меня есть большая матрица, из которой я хотел бы собрать коллекцию подматриц. Если моя матрица 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

Вывод, если а) неправильный и б) подразумевается, что в выражении big_mat(x:x+M-1, y:y+M-1) есть что-то, что может дать мне то, что я хочу, без необходимости использовать два цикла for Любая помощь будет высоко ценится

Ответы [ 3 ]

5 голосов
/ 27 апреля 2010

Кажется, в вашем коде есть несколько ошибок. Вот как бы я это сделал, если бы использовал двойной цикл:

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

EDIT

Я только что увидел, что есть реализация im2col для Octave. Таким образом, вы можете переписать двойной цикл как

%# 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 голос
/ 27 апреля 2010

с Mathematica: Этот код создает матрицу, в которой каждый элемент представляет собой матрицу MxM с каждым элементом в исходной матрице в верхнем левом углу такой матрицы.

Матричные элементы справа и снизу дополняются х.

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

Пример: альтернативный текст http://img130.imageshack.us/img130/6203/partitionf.png

Если вы не укажете аргумент x, то он автоматически будет периодически делать выборки.

0 голосов
/ 27 апреля 2010

Ваш вывод неверен, возможно, это связано с назначением Вы пытаетесь присвоить матрицу векторной позиции. Попробуйте использовать

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

вместо.

...