How to change 4x4 matrix to 2x2 matrix
18 views (last 30 days)
Show older comments
I have a 4x4 matrix A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
Now, I'd like to change the matrix size from 4x4 to 2x2 and have the average of 4 cells for new cell.
To visualize,
*1 2* 3 4
*2 3* 4 5
3 4 5 6 2 4
4 5 6 7 --> 4 6
Any input would be appreciated,
0 Comments
Answers (7)
Orion
on 7 Nov 2014
Edited: Orion
on 7 Nov 2014
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
B = cellfun(@mean,cellfun(@mean,mat2cell(A,[2 2],[2 2]),'UniformOutput',false))
A =
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
B =
2 4
4 6
Note : you can simplify by decomposing in several steps if you prefer.
1 Comment
Jan
on 9 Nov 2014
This is surprisingly slow: it needs about 100 times longer than the other M-versions posted here.
James Tursa
on 7 Nov 2014
Edited: James Tursa
on 7 Nov 2014
Yet another way (not necessarily any better than other posts), generalized:
kr = 2; kc = 2; % Row and Column sizes of sub-block
[m n] = size(A); mk = m/kr; nk = n/kc; % Size of input and result
B = reshape(sum(reshape(reshape(sum(reshape(A,kr,[])),mk,[]).',kc,[])),nk,mk).'/(kr*kc);
0 Comments
Image Analyst
on 7 Nov 2014
Did you try the straightforward:
out = [A(1,1)+A(1,2)+A(2,1)+A(2,2),...
A(1,3)+A(1,4)+A(2,3)+A(2,4);...
A(3,1)+A(3,2)+A(4,1)+A(4,2),...
A(3,3)+A(3,4)+A(4,3)+A(4,4)]/4
0 Comments
Azzi Abdelmalek
on 7 Nov 2014
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
[n,m]=size(A)
[ii1,jj1]=ndgrid(1:2:n,1:2:m)
out=arrayfun(@(x,y) mean(mean(A(x:x+1,y:y+1))),ii1,jj1)
0 Comments
Jan
on 9 Nov 2014
Edited: Jan
on 9 Nov 2014
Some timings for a 1024*768 image, 100 iterations (Matlab R2011b, Win7/64, Core2Duo):
BlockMean: 0.35 sec
CELLFUN: 784.0 sec (wow!)
SUM(RESHAPE): 8.37 sec
SUM(RESHAPE) 2: 5.70 sec
ARRAYFUN: 9.74 sec
SEPBLOCK: 7.50 sec
(BLOCKPROC: Undefined function, I do not have the required toolbox)
function SpeedTest(A)
A = rand(1024, 768);
n = 100;
tic;
for k = 1:n
r = BlockMean(A, 2, 2);
end
fprintf('BlockMean: %.4g sec\n', toc);
tic;
for k = 1:1
[m, n] = size(A);
r = cellfun(@mean, ...
cellfun(@mean, ...
mat2cell(A, repmat(2, 1, m/2), repmat(2, 1, n/2)),'UniformOutput',false));
end
fprintf('CELLFUN: %.4g sec\n', toc * 100);
tic;
for k = 1:n
kr = 2;
kc = 2;
[m, n] = size(A);
mk = m/kr;
nk = n/kc;
B = reshape(sum(reshape( ...
reshape(sum(reshape(A,kr,[])), mk,[]).', kc, [])), nk, mk).' / (kr*kc);
end
fprintf('SUM(RESHAPE): %.4g sec\n', toc);
tic;
for k = 1:n
V = 2;
W = 2;
[M, N] = size(A);
AM = reshape(A, V, M/V, W, N/W, []);
r = sum(sum(AM, 1), 3) .* (1.0 / (V * W));
end
fprintf('SUM(RESHAPE) 2: %.4g sec\n', toc);
tic;
for k = 1:1
[n,m] = size(A);
[ii1, jj1] = ndgrid(1:2:n,1:2:m);
r = arrayfun(@(x,y) mean(mean(A(x:x+1,y:y+1))),ii1,jj1);
end
fprintf('ARRAYFUN: %.4g sec\n', toc);
tic;
for k = 1:n
r = sepblockfun(A, [2,2], @mean);
end
fprintf('SEPBLOCK: %.4g sec\n', toc);
tic;
for k = 1:n
r = blockproc(A,[2,2], @(x) mean(x.data(:)) )
end
fprintf('BLOCKPROC: %.4g sec\n', toc);
1 Comment
Image Analyst
on 9 Nov 2014
Edited: Image Analyst
on 9 Nov 2014
Why did you run the cellfun and arrayfun tests only 1 iteration instead of n iterations like the other tests? By the way, 1 iteration of blockproc took 12 seconds.
See Also
Categories
Find more on Resizing and Reshaping Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!