function Z = mgv2d(U,B,gs_iter)
[n n1] = size(B);
if ( n~=n1 )
error('mgv2d: input not square');
end
N = n-1;
h = 2/N;
if ( n==3 )
Z = zeros(n,n);
Z(2,2) = -h^2/4*B(2,2);
else
for iter=1:gs_iter
for j = 2:n-1
for i = 2:n-1
U(i,j) = (U(i+1,j)+U(i-1,j)+U(i,j+1)+U(i,j-1))/4 - h^2/4*B(i,j);
end
end
end
cen = 2:n-1;
dec = cen - 1;
inc = cen + 1;
R = zeros(n,n);
R(cen,cen) = B(cen,cen) - 1/h^2*( ...
-4*U(cen,cen) ...
+U(dec,cen) ...
+U(inc,cen) ...
+U(cen,dec) ...
+U(cen,inc) );
cen_s = 3:2:n-2;
dec_s = cen_s - 1;
inc_s = cen_s + 1;
m = (n+1)/2;
Rhat = zeros(m,m);
Rhat(2:m-1,2:m-1) = 1/16*( ...
R(dec_s,dec_s) + ...
R(dec_s,inc_s) + ...
R(inc_s,dec_s) + ...
R(inc_s,inc_s) + ...
2*R(inc_s,cen_s) + ...
2*R(dec_s,cen_s) + ...
2*R(cen_s,inc_s) + ...
2*R(cen_s,dec_s) + ...
4*R(cen_s,cen_s));
Uhat = mgv2d(zeros(m,m),Rhat,gs_iter);
Ucor = zeros(n,n);
Ucor(cen_s,cen_s) = Uhat(2:m-1,2:m-1);
Ucor(2:2:n-1,cen_s) = .5*(Uhat(1:m-1,2:m-1)+Uhat(2:m,2:m-1));
Ucor(cen_s,2:2:n-1) = .5*(Uhat(2:m-1,1:m-1)+Uhat(2:m-1,2:m));
Ucor(2:2:n-1,2:2:n-1) = .25*( ...
Uhat(1:m-1,1:m-1) + ...
Uhat(2:m,1:m-1) + ...
Uhat(1:m-1,2:m) + ...
Uhat(2:m,2:m));
Z = U + Ucor;
for iter=1:gs_iter
for j = 2:n-1
for i = 2:n-1
Z(i,j) = (Z(i+1,j)+Z(i-1,j)+Z(i,j+1)+Z(i,j-1))/4 - h^2/4*B(i,j);
end
end
end
end