Octave: múltiples submatrices de una matriz

votos
4

Tengo un gran matriz de la que me gustaría reunir una colección de submatrices. Si mi matriz es NxN y el tamaño submatriz es MxM, quiero recoger I=(N - M + 1)^2submatrices. En otras palabras, quiero una submatriz MxM para cada elemento de la matriz original que puede estar en la esquina superior izquierda de una matriz de este tipo.

Aquí está el código que tengo:

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

La salida si: a) mal, y b) dando a entender que hay algo en la big_mat(x:x+M-1, y:y+M-1)expresión que me puede conseguir lo que quiera sin necesidad de los dos bucles. Cualquier ayuda sería muy apreciada

Publicado el 26/04/2010 a las 21:26
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
0

Acerca de su salida a equivocarse, que podría ser debido a la asignación. Usted está tratando de asignar una matriz a un vector de posición. Trate de usar

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

en lugar.

Respondida el 26/04/2010 a las 21:39
fuente por usuario

votos
5

Parece que hay algunas cosas equivocadas en el código. Así es como yo lo haría si tuviera que utilizar el doble circuito:

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

EDITAR

Acabo de ver que existe una implementación de im2col de Octave. De este modo, se puede volver a escribir el doble bucle

%# 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,[]);

Esto es probablemente más rápido y ahorra un montón de árboles digitales.

Respondida el 26/04/2010 a las 22:33
fuente por usuario

votos
1

Con Mathematica: Este código hace que una matriz donde cada elemento es una matriz de MxM con cada elemento de la matriz original en la esquina superior izquierda de una matriz tal.

Los elementos de matriz a lo largo de la derecha y la parte inferior se rellenan con x.

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

Ejemplo: texto alt http://img130.imageshack.us/img130/6203/partitionf.png

Si deja fuera x argumento, entonces, entonces automáticamente muestras periódicamente.

Respondida el 27/04/2010 a las 00:51
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more