How to divide a data arry into blocks like this using a FOR loop?

10 views (last 30 days)
How to divide a data array into blocks like this using a FOR loop?
Please consider my sample code:
a = -1-j; b = 2-j; % some constants
data = a+(b-a)*rand(1,256); % data
b=[1,2,4,8,16] % number of blocks
How to divide my data into blocks b=[1,2,4,8,16] in a adjacent grouping of data indices like this Using a For Loop running for 'b' :
out1=1x256=same as data(1x256)(no division into blocks)
out2=[data(1:128) zeros(1,128);zeros(1,128) data(129:256)]; % 2x256
out4=[ data(1:64) zeros(1,192); % 4x256
zeros(1,64) data(65:128) zeros(1,128);
zeros(1,128) data(129:192) zeros(1,64);
zeros(1,192) data(193:256)];
out8= [ data(1:32) zeros(1,224); % 8x256
zeros(1,32) data(33:64) zeros(1,192);
zeros(1,64) data(65:96) zeros(1,160);
zeros(1,96) data(97:128) zeros(1,128)
zeros(1,128) data(129:160) zeros(1,96);
zeros(1,160) data(161:192) zeros(1,64);
zeros(1,192) data(193:224) zeros(1,32);
zeros(1,224) data(225:256)];
similarly,
out16=[data(1:16) zeros(17,240); % 16x256
zeros(1,16) data(17:32) zeros(1,224);
...
... ]

Answers (3)

dpb
dpb on 22 Nov 2013
Edited: dpb on 23 Nov 2013
Quick thought...
For the first case from command line it's easy enough
>> N=16; d=rand(1,N);
>> blkdiag(d(1:N/2),d(N/2+1:l))
ans =
Columns 1 through 9
0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469 0
0 0 0 0 0 0 0 0 0.9575
Columns 10 through 16
0 0 0 0 0 0 0
0.9649 0.1576 0.9706 0.9572 0.4854 0.8003 0.1419
Now to generalize observe...
>> reshape(d,N/2,[])'
ans =
0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469
0.9575 0.9649 0.1576 0.9706 0.9572 0.4854 0.8003 0.1419
>> c{1}=ans(1,:);c{2}=ans(2,:); % Put into cell array for later...
>> blkdiag(c{:})
ans =
Columns 1 through 9
0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469 0
0 0 0 0 0 0 0 0 0.9575
Columns 10 through 16
0 0 0 0 0 0 0
0.9649 0.1576 0.9706 0.9572 0.4854 0.8003 0.1419
>>
The key is the comma-separated list generated from the cell array avoids the need to write an explicit argument list for blkdiag as blkdiag(a,b,c,...) w/ a differing number of arguments.
Seems like should be a way w/o the intermediate cell but it doesn't come to me here otomh, but should its an easy-enough-to-write function to do it in general with simply the input data and N as arguments.

Image Analyst
Image Analyst on 23 Nov 2013
See the FAQ: http://matlab.wikia.com/wiki/FAQ#How_do_I_split_an_image_into_non-overlapping_blocks.3F. Even though the FAQ says image, an image is just a matrix so it will work for a 2D array of numbers also.
  3 Comments
Image Analyst
Image Analyst on 23 Nov 2013
But what do they want to do after it's in blocks? No one wants to divide an array up into blocks just for the fun of it. You always do something with the blocks afterwards. Before, I've seen people say that they want to divide the image up into blocks, and after further questions it was revealed that they wanted to do a filter on it, and it turned out just calling conv2 or imfilter is what was needed. My answer may vary if we knew what "a" had planned for those blocks.
dpb
dpb on 23 Nov 2013
Edited: dpb on 23 Nov 2013
There must be some reason for the block diagonal form I'd presume. Generating the blocks was just the first step in OPs query. In a former life block-diagonal forms of coefficients were common and I was assuming the rand() here was simply a placeholder for whatever the real values are.
But, whether there's another way to get to a final result w/o the block diagonal form and can get to that point with only the subblocks is a different question, indeed, granted.

Sign in to comment.


Andrei Bobrov
Andrei Bobrov on 23 Nov 2013
Edited: Andrei Bobrov on 23 Nov 2013
a = -1-j;
b = 2-j;
data = a+(b-a)*rand(1,256);
m=[1,2,4,8,16];
s = numel(m);
k = numel(data)./m;
out = cell(s,1);
for jj = 1:s
l = kron(eye(m(jj)),ones(1,k(jj)))>0;
out{jj} = zeros(m(jj),n);
out{jj}(l) = data;
end
with blkdiag
a = -1-j;
b = 2-j;
data = a+(b-a)*rand(1,256);
m=[1,2,4,8,16];
s = numel(m);
k = numel(data)./m;
out = cell(s,1);
for jj = 1:s
p = mat2cell(data,1,k(jj)*ones(1,m(jj)));
out{jj} = blkdiag(p{:});
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!