Matlab – How to make a block of matrices from large matrix in matlab

MATLABmatrixoctave

I have a 256×256 matrix from that I want to create block of 8×8 matrices. I have a below code which shows just one block i want all the blocks then subtract a number from each element of the matrix. When i do the subtract 128 from each element it doesn't show negative values rather showing only 0.

[x,y] = size(M);

for i=1:8
   for j=1:8
      k(i,j) = M(i,j);
   end
end

disp(k);

for a=1:size(k)
   for b=1:size(k)
     A(a,b) = k(a,b) - 128;
   end
end

disp(A);

Best Answer

well, if you have to subtract a fixed value it's better to do it as

M = M - 128;

It's faster.

You said you get 0 values instead of negative ones; it is likely due to the type of the matrix which is unsigned (i.e. the guys are just positive). A cast to general integer is necessary. Try:

M = int16(M) - 128;

To obtain the partition I propose the following, there can be more efficient ways, btw:

r = rand(256,256);            %// test case, substitute with your matrix M
[i j] = meshgrid(1:8:256);    %// lattice of indices      
idx = num2cell([ i(:) , j(:) ],2); %// cell version 

matr = cellfun( @(i) r(i(1):i(1)+7,i(2):i(2)+7), idx, 'UniformOutput',false); %// blocks

matr will contain all the sub-matrices in lexicographical order. e.g.

matr{2}

ans =

0.4026    0.3141    0.4164    0.5005    0.6952    0.1955    0.9803    0.5097
0.8186    0.9280    0.1737    0.6133    0.8562    0.7405    0.8766    0.0975
0.2704    0.8333    0.1892    0.7661    0.5168    0.3856    0.1432    0.9958
0.9973    0.8488    0.6937    0.2630    0.1004    0.5842    0.1844    0.5206
0.4052    0.0629    0.6982    0.1530    0.9234    0.1271    0.7317    0.3541
0.2984    0.3633    0.1510    0.0297    0.0225    0.7945    0.2925    0.0396
0.5097    0.0802    0.8744    0.1032    0.8523    0.6150    0.4845    0.5703
0.8635    0.0194    0.1879    0.5017    0.5297    0.6319    0.2406    0.5125

Explanation: In matlab you can efficiently operate on matrices and slices of them. For instance, you can easily copy submatrices, e.g. the first 8x8 matrix is

  sub = M(1:8,1:8);

You want all the submatrices, thus you need kind of a lattice of indices to get

  sub_ij = M(1+8*(i-1) : 7 * 8*(i-1) , 1+8*(j-1) : 7 * 8*(j-1))

i.e. you need the lattice

  (1+8*(i-1) : 7 * 8*(i-1) , 1+8*(j-1) : 7 * 8*(j-1))   % // for all i,j

you can use meshgrid for that.

Finally you have to cut off the pieces, that is what the last two instruction do. particularly the first one generates the indices (try idx{1},...), and the second one generates the submatrices (try matr{1},...).

Related Topic