Octave: multiple matrix sub-matrices

I have a large matrix from which I would like to assemble a collection of submatrices. If my matrix is ​​NxN and the submatrix size is MxM, I want to collect the submatrices I=(N - M + 1)^2 . In other words, I need one MxM submatrix for each element of the original matrix, which can be in the upper left corner of such a matrix.

Here is the code I have:

 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 

The result, if a) is incorrect, and b) implying that there is something in the big_mat(x:x+M-1, y:y+M-1) expression big_mat(x:x+M-1, y:y+M-1) that can get me what I want, without the need for two cycles. Any help would be greatly appreciated

+4
source share
3 answers

There seems to be something wrong in your code. Here is how I would do it if I used a double loop:

 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

I just saw that there is an im2col implementation for Octave. So you can rewrite the double loop as

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

It is probably faster and saves a lot of digital trees.

+5
source

With Mathematica: This code creates a matrix in which each element is an MxM matrix with each element of the original matrix in the upper left corner of such a matrix.

Matrix elements on the right and bottom are complemented by x.

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

Example: alt text http://img130.imageshack.us/img130/6203/partitionf.png

If you leave the argument x, then it will automatically be selectively counted.

+1
source

If you are mistaken, this may be due to the appointment. You are trying to assign a matrix to a vector position. Try using

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

instead.

0
source

Source: https://habr.com/ru/post/1308066/


All Articles