Supondo que temos uma matriz M de tamanho N^2 x N^2 elementos (por exemplo, 9x9), qual é a maneira mais rápida de dividi-la em segmentos de 3x3 (cada um com 3x3 elementos)?
Uma maneira que me vem à mente é a seguinte:
M = magic(9);
N = 3;
m = mat2cell(M, N * ones(1, size(M, 1) / N), ...
N * ones(1, size(M, 2) / N));
Eu, no entanto, não prefiro o uso de células. Fiquei curioso para saber se há uma maneira de dividir a matriz e armazenar os segmentos na forma de uma matriz 3D usando uma indexação de coluna principal para os segmentos (por exemplo, o primeiro segmento m{1} se torna m(:, :, 1) e o segundo segmento m{2} se torna m(:, :, 2), e assim por diante).
Você pode combinar
reshape
compermute
, por exemplo assim:O interior
reshape
tem as "células" pretendidas divididas nas dimensões 1 e 3, quepermute
mudam para as dimensões 1 e 2. O exteriorreshape
pode ser omitido, se você não se importar em ter uma matriz 4D.Depois de usar
mat2cell
, você pode concatenar as matrizes 2D em uma matriz 3D comIsso irá satisfazer "m{1} se torna m(:, :, 1)" etc.
Uma opção diferente seria pegar cada faixa de
N
linhas ereshape
colocá-las diretamente em umaNxNxN
matriz de segmentos, atribuindo-as como o próximo pedaço daNxNx(N^2)
matriz de saída.Note que os segmentos nessas duas opções estão em uma ordem diferente (o primeiro vai para baixo e depois para as submatrizes, o último vai para o outro lado e depois para baixo). Se você quisesse que esse loop e a versão de remodelagem correspondessem
mat2cell
exatamente à versão, você precisaria fazer algumas operações de transposição com oreshape
para obter a ordem corretaHá apenas uma pequena perda de desempenho ao realizar operações de transposição adicionais.
Atualização com benchmarking
Fiquei curioso sobre qual das opções acima seria mais rápida, então escrevi o benchmark na parte inferior aqui (wrapper para o código sugerido na resposta acima). Aqui está o gráfico resultante, então fazer um loop e atribuir diretamente em uma matriz numérica é mais rápido do que passar por uma célula, independentemente de
N
:Também incluí a resposta de chtz que usa apenas
reshape
e permuta, e fornece o mesmo resultado que as opçõesmat2cell
epagetranspose
acima, muito mais rápido e com menos dependência deN
, então eu recomendaria a solução deles .Código de benchmarking:
Se você tiver o Image Procressing Toolbox, poderá fazer isso facilmente com
im2col
(mas o código provavelmente é mais lento que as outras opções):Isso pode ajudar você?