# How does Matlab surf perform interpolation?

When I use Matlab's surf function, I notice that I can't re-perform its interpolation, which produces unreliable results. Do you know what does surf do under the hood?

The following code compares spline and surf interpolation:

z= linspace(-1,1,4001);
x = linspace(-2*pi,2*pi,150);
sharp_gausian = @(y,sigma) exp((-y.^2).*sigma);

% initializing low-resolution surf
for j=1:length(z)
psi_grid(j,:) = sharp_gausian(x + sin(5*z(j)),10);
end
subplot(2,2,1)
s =surf(x,z, psi_grid);
set(s,'linestyle','none')
xlabel('$x$' , 'FontSize', 14, 'Interpreter', 'latex');
ylabel('$z$', 'FontSize', 14, 'interpreter', 'latex','rot',0);
title('$Nx = 150$')

% using higher resolution grid and interpolating the function using spline.
x_fine = linspace(-2*pi,2*pi,1500);
for j=1:length(z)
psi_grid2(j,:) = spline(x, psi_grid(j,:), x_fine);
end
subplot(2,2,2)
s2 =surf(x_fine,z, psi_grid2);
set(s2,'linestyle','none')
xlabel('$x$' , 'FontSize', 14, 'Interpreter', 'latex');
ylabel('$z$', 'FontSize', 14, 'interpreter', 'latex','rot',0);
title('$Nx = 1500$')


I assume you are interested in how the surf function controls the coloring of the surfaces. Most of the information is readily available at the Matlab help pages for surf and shading.

By default, surf uses faceted shading, so "each mesh line segment and face has a constant color determined by the color value at the endpoint of the segment or the corner of the face that has the smallest index or indices". So, in your code — no explicit interpolation has been performed.

By introducing a fine grid and using spline, you performed interpolation by yourself, and now surf function for $N_x=1500$ just uses the result you fed it.

In the picture below, I demonstrated the work of surf function with different shading options. It is clear, that surf with shading interp for $N_x=150$ (bottom-left) pretty much resembles the figure obtained with a fine ($10\times$) grid $N_x=1500$ (bottom-right). shading flat and shading faceted look the same because you manually disabled lines for the surface plots.

Matlab code:

sharp_gausian = @(y,sigma) exp((-y.^2).*sigma);

Nz=4001;
Nx=150;
Nx_refine=Nx*10;
z=linspace(-1,1,Nz);
x=linspace(-2*pi,2*pi,Nx);
x_fine=linspace(-2*pi,2*pi,Nx_refine);

% initializing low-resolution surf
psi_grid=zeros(Nz,Nx);
for j=1:length(z)
psi_grid(j,:)=sharp_gausian(x+sin(5*z(j)),10);
end

% using higher resolution grid and interpolating the function using spline.
psi_grid2=zeros(Nz,Nx_refine);
for j=1:length(z)
psi_grid2(j,:)=spline(x,psi_grid(j,:),x_fine);
end

%% ONLY VISUALIZATION AFTER THIS POINT
set(groot,'DefaultTextInterpreter','latex');
set(groot,'defaultLegendInterpreter','latex');
set(groot,'defaultAxesTickLabelInterpreter','latex');
ff=20;

figure(1)
set(gcf,'Units','inches');
set(gcf,'Position',[2 2 13 12]);
subplot(2,2,1)
s1=surf(x,z, psi_grid);
set(s1,'linestyle','none')
xlabel('$x$','FontSize', ff, 'Interpreter', 'latex');
ylabel('$z$','FontSize', ff, 'interpreter', 'latex','rot',0);
title('$N_x = 150$, shading flat');
set(gca,'FontSize',ff-2);
% original x, faceted (default) shading
subplot(2,2,2)
s2=surf(x,z, psi_grid);
set(s2,'linestyle','none')
xlabel('$x$' , 'FontSize', ff, 'Interpreter', 'latex');
ylabel('$z$', 'FontSize', ff, 'interpreter', 'latex','rot',0);
title('$N_x = 150$, shading faceted');
set(gca,'FontSize',ff-2);
subplot(2,2,3)
s3=surf(x,z, psi_grid);
set(s3,'linestyle','none')
xlabel('$x$' , 'FontSize', ff, 'Interpreter','latex');
ylabel('$z$', 'FontSize', ff, 'interpreter','latex','rot',0);
title('$N_x = 150$, shading interp');
set(gca,'FontSize',ff-2);
% 10* refinement in x, faceted (default) shading
subplot(2,2,4)
s4=surf(x_fine,z, psi_grid2);
xlabel('$x$','FontSize',ff,'Interpreter','latex');
ylabel('$z$','FontSize',ff,'interpreter','latex','rot',0);
title('$N_x = 1500$, shading default (faceted)');