How to enlarge matrix by putting average of surrounding numbers in between of every number of original matrix
2 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Sean de Wolski
2011-4-6
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.
更多回答(2 个)
Andrew Newell
2011-4-6
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 个评论
Chris
2011-4-6
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 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 EEG/MEG/ECoG 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!