# making coarse matrix from fine resolution matrix

14 views (last 30 days)
SChow on 23 Jan 2020
Edited: Matt J on 27 Jan 2020
Hi, I am trying to make a coarse resolution matrix of 3600x1800 from a 8640x4320 matrix by summing up the elements of the matrix.
Hi am trying the following: However this doesnot work with fractions (here, 2.4)
%%%%Z1 is the original 8640x4320 matrix
abc = blockproc(Z1,[2.4,2.4],@(x)sum(x.data));
abc1 = blockproc(abc,[1,2.4],@(x)sum(x.data));

Matt J on 23 Jan 2020
Edited: Matt J on 27 Jan 2020
A 3rd approach, more memory conserving and faster,.
Z1=randi(100,8640,4320);
u = 5; %upsampling factor
d = 12; %downsampling factor
t = d/u; %reduction factor
[m,n]=size(Z1);
L1=speye(m); L2=speye(round(m/t))/u;
R1=speye(n); R2=speye(round(n/t))/u;
L=repelem(L2,1,d) * repelem(L1,u,1);
R=(repelem(R2,1,d) * repelem(R1,u,1)).';
tic
abc4= L*(Z1*R);
toc
Note as well that the matrices L and R are reusable on other Z1 of the same size that one might wish to downsample later on.

Matt J on 23 Jan 2020
Edited: Matt J on 23 Jan 2020
If you have the Image Processing Toolbox,
abc1=imresize(Z1,[3600,1800])

SChow on 23 Jan 2020
I suspect what you are pursuing might not be different enough from imresize to be worth the trouble. The only difference between what you are doing, and what imresize does is that you are using a rectangular anti-aliasing filter window, while imresize uses some other low pass filter (Gaussian?). Does the difference really matter to you? imresize was written to do resolution reduction in a pretty smart way
I tried it in both ways and compared with Z1: The sum of matrix Z1 was 5.8x10^8 . the target matrix intended to have the same sum.
[Z1 contains gridded population]
Using repelem and sepblockfun :
scaling = 5; %%% I scale Z1 by factor of 5 so that the sepblockfun works,
S = repelem (Z1 / scaling ^ 2, scaling, scaling); %% where S is 43200x21600
abc2 = sepblockfun (S, [12,12], 'sum' ); %%% abc2 is 3600x1800
%%%% SUM of abc2 - 5.8x10^8
Using imresize :
abc3=imresize(Z1,0.4166667)
%%%% SUM of abc3 - 1.0269x10^8
Matt J on 23 Jan 2020
This should give proper agreement in the sums
abc3=imresize(Z1,1/2.4)*2.4^2;
or
abc3=imresize(Z1,1/2.4);
abc3=abc3/sum(abc3(:))*sum(Z1(:));
SChow on 23 Jan 2020
Thanks, they work well!!

SChow on 23 Jan 2020
Edited: SChow on 23 Jan 2020
scaling = 5; %%% I scale Z1 by factor of 5 so that sepblockfun works,
%%%%% sepblockfun is developed by MattJ and is available for
%downlaod at https://de.mathworks.com/matlabcentral/fileexchange/48089-separable-block-wise-operations
S = repelem (Z1 / scaling ^ 2, scaling, scaling); %% where S is 43200x21600
abc2 = sepblockfun (S, [12,12], 'sum' ); %%% abc2 is 3600x1800

Matt J on 23 Jan 2020
I would recommend doing this in horizontal and vertical passes, so that the intermediate matrix S won't be so large,
S = sepblockfun( repelem (Z1 , scaling, 1) , [12,1], 'sum');
abc2 = sepblockfun( repelem (S, 1, scaling) , [1,12], 'sum')/scaling^2;
SChow on 24 Jan 2020
@MattJ
I completely agree!!
Thank you so much for your help