How to enlarge matrix by putting average of surrounding numbers in between of every number of original matrix
2 views (last 30 days)
Show older comments
Hi everyone,
i would like to create a larger matrix from a small one by putting average of surrounding numbers. so for a matrix
a = [1 2; 3 4]
a =
1 2
3 4
i'd like to create matrix of
b = [1 0 2;0 (1+2+3+4)/4 0;3 0 4]
b =
1.0000 0 2.0000
0 2.5000 0
3.0000 0 4.0000
then to put average to the places where is zero to creat a 3 by 3 matrix from original 2 by 2:
c = [1 (1+2+2.5)/3 2;(1+3+2.5)/3 2.5 (2+4+2.5)/3; 3 (3+4+2.5)/3 4]
c =
1.0000 1.8333 2.0000
2.1667 2.5000 2.8333
3.0000 3.1667 4.0000
And now i want to do so over and over to create matrices of 2x2 to 3x3 to 5x5 to 8x8 to 13x13 to 24x24 to 46x46 to 92x92 to 184x184. The reason to do so is to create some kind of map, i.e. brainmap.
So any idea how to make it some elegant. I can only thing of using some 4 for cyclus to do so like in paper i need to solve out some PC way. Thanks for any idea in advance
Jan
4 Comments
Accepted Answer
Sean de Wolski
on 6 Apr 2011
Here's a fully vectorized method. Call it n number of times and it will repeat each time! (It will also work on non-square matrices)
function out = expandWmean(in)
%SCd 04/06/2011
%
M1 = false((2*size(in))-1); %Map of points we have
M1(1:2:end,1:2:end) = true;
sz = size(M1);
M2 = false(sz);
M2(2:2:end,2:2:end) = true; %Map of points we get on first iteration
out = zeros(sz);
out(M2) = conv2(in,ones(2)./4,'valid'); %Mean for first iteration (center of boxes)
out(M1) = in;
N = ones(sz)*4; %number of elements in the valid mean calculation
N([1 end],:) = 3;
N(:,[1 end]) = 3;
C2 = conv2(out,ones(3),'same')./N; %Second iteration
out(~M1&~M2) = C2(~M1&~M2);
end
EDIT: There are 4 valid points in the middle parts on the second iteration, not 5.
More Answers (2)
Andrew Newell
on 6 Apr 2011
You may not be able to get what you want using just interp2. The following code
nb = 2*size(a,1)-1;
[ia,ja] = meshgrid(1:2:nb,1:2:nb);
[ib,jb] = meshgrid(1:nb,1:nb);
c = interp2(ia,ja,a,ib,jb,'*linear')
returns the matrix
c =
1.0000 1.5000 2.0000
2.0000 2.5000 3.0000
3.0000 3.5000 4.0000
As you can see, the middle components are averages of just two neighbors ( e.g, 1.5 = (1+2)/2 ). Unless you have a compelling reason to do it the way you described, this would be much easier.
0 Comments
Chris
on 6 Apr 2011
This made a nice brain teaser to work on for a few minutes every hour or so. So, here's the hard way, if so inclined. It could be cleaned up plenty, and you could add some fixes to allow an 'a' with a dimension smaller than 2, but this will work for all rectangles, not just squares, 2x2 and up.
% Supply your own N-by-M matrix 'a', at least 2x2
S = size(a,1);
T = size(a,2);
U = 2*S-1;
V = 2*T-1;
%Preallocate 'b'
b = zeros(U,V);
%Calc 'b'
for n = 1:size(a,1)
for m = 1:size(a,2)
W = 2*n;
X = 2*m;
Y = 2*n-1;
Z = 2*m-1;
if n < size(a,1) && m < size(a,2)
b(W,X) = (a(n,m)+a(n+1,m)+a(n,m+1)+a(n+1,m+1))/4;
end
b(Y,Z) = a(n,m);
end
end
%Preallocate 'c'
c = b;
%Calc 'c'
for n = 1:size(a,1)
for m = 1:size(a,2)
W = 2*n;
X = 2*m;
Q = 2*n-2;
R = 2*m-2;
Y = 2*n-1;
Z = 2*m-1;
O = 2*n+1;
P = 2*m+1;
if n == 1 && m == 1
c(W,Z) = (b(Y,Z)+b(Y+2,Z)+b(W,X))/3;
c(Y,X) = (b(Y,Z)+b(Y,Z+2)+b(W,X))/3;
elseif m == 1 && n < size(a,1)
c(W,Z) = (b(Y,Z)+b(Y+2,Z)+b(W,X))/3;
c(Y,X) = (b(Y,Z)+b(Y,Z+2)+b(W,X)+b(Q,X))/4;
elseif n == 1 && m < size(a,2)
c(Y,X) = (b(Y,Z)+b(Y,Z+2)+b(W,X))/3;
c(W,Z) = (b(Y,Z)+b(Y+2,Z)+b(W,X)+b(W,R))/4;
elseif n > 1 && n < size(a,1) && m > 1 && m < size(a,2)
c(W,Z) = (b(Y,Z)+b(Y+2,Z)+b(W,X)+b(W,R))/4;
c(Y,X) = (b(Y,Z)+b(Y,Z+2)+b(W,X)+b(Q,X))/4;
elseif m == size(a,2) && n < size(a,1)
c(W,Z) = (b(Y,Z)+b(W,R)+b(O,Z))/3;
elseif n == size(a,1) && m < size(a,2)
c(Y,X) = (b(Y,Z)+b(Q,X)+b(Y,P))/3;
end
end
end
0 Comments
See Also
Categories
Find more on EEG/MEG/ECoG 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!