from 3D Data Interpolation by Per Sundqvist
3D interpolation using modified 4-point vector Newton interpolation

ui=NewtFit(x,y,z,u,xi,yi,zi)
function ui=NewtFit(x,y,z,u,xi,yi,zi)
% Syntax: ui=NewtFit(x,y,z,u,xi,yi,zi)
% 3D interpolation. It may be used where griddata3 fails to find a
% triangularization of the datagrid (x,y,z).
% The function uses a modified 4 point Newton interpolation formula
% for vector arguments in 3D instread of scalars used in 1D.
% The interpolation is performed for the 4 nearest neighbors for each
% point in the (xi,yi,zi).
% u=u(x,y,z) is the data from which ui(xi,yi,zi) is interpolated
% x,y,z,u are vectors of same size and xi,yi,zi are also vectors.
% The fit is exact (u=ui) for points (xi,yi,zi) that coinside
% with data points (x,y,z). Note: NewtFit also delivers result for points outside
% the domain (i.e., extrapolation), but results may be inaccurate then.
%
% Created by: Per Sundqvist, Gothenburg University 2005
%
% %Example: Prepare data in random non-uniform grid
% xyz=rand(10003,3);
% x=xyz(:,1);y=xyz(:,2);z=xyz(:,3);
% u=x.^3+sin(pi*y).^2.*z.^2;
% 
% %Gridpoints to fit:
% xyz=rand(8007,3);
% xi=xyz(:,1);yi=xyz(:,2);zi=xyz(:,3);
%
% %Interpolate
% ui=NewtFit(x,y,z,u,xi,yi,zi);
%
% %compare and plot
% uui=xi.^3+sin(pi*yi).^2.*zi.^2;%exact
% plot(uui,ui,'.');pause(4)
% hist(uui-ui,60);
% standard_deviation=std(uui-ui)


%Covert to column and row vectors;
x=x(:);y=y(:);z=z(:);u=u(:);
sz=size(xi);    %Original input size
xi=xi(:);yi=yi(:);zi=zi(:);

%find index of 4 nearest neighbors for each ri
I4=find4near(x,y,z,xi,yi,zi);

% Newton 4-point interpolation with 3D vectors
f0=u(I4(1,:));
f1=u(I4(2,:));
f2=u(I4(3,:));
f3=u(I4(4,:));
D10=sqrt((x(I4(2,:))-x(I4(1,:))).^2+(y(I4(2,:))-y(I4(1,:))).^2+(z(I4(2,:))-z(I4(1,:))).^2);
D12=sqrt((x(I4(2,:))-x(I4(3,:))).^2+(y(I4(2,:))-y(I4(3,:))).^2+(z(I4(2,:))-z(I4(3,:))).^2);
D20=sqrt((x(I4(3,:))-x(I4(1,:))).^2+(y(I4(3,:))-y(I4(1,:))).^2+(z(I4(3,:))-z(I4(1,:))).^2);
D30=sqrt((x(I4(4,:))-x(I4(1,:))).^2+(y(I4(4,:))-y(I4(1,:))).^2+(z(I4(4,:))-z(I4(1,:))).^2);
D31=sqrt((x(I4(4,:))-x(I4(2,:))).^2+(y(I4(4,:))-y(I4(2,:))).^2+(z(I4(4,:))-z(I4(2,:))).^2);
D32=sqrt((x(I4(4,:))-x(I4(3,:))).^2+(y(I4(4,:))-y(I4(3,:))).^2+(z(I4(4,:))-z(I4(3,:))).^2);


A1=(f1-f0)./D10;
A2=((f2-f0)./D20+(f0-f1)./D10)./D12;
A3=(D12.*((f3-f0)./D30+(f0-f1)./D10)+D31.*((f1-f0)./D10+(f0-f2)./D20))./D12./D31./D32;
dv0=sqrt((xi-x(I4(1,:))).^2+(yi-y(I4(1,:))).^2+(zi-z(I4(1,:))).^2);
dv1=sqrt((xi-x(I4(2,:))).^2+(yi-y(I4(2,:))).^2+(zi-z(I4(2,:))).^2);
dv2=sqrt((xi-x(I4(3,:))).^2+(yi-y(I4(3,:))).^2+(zi-z(I4(3,:))).^2);

ui=f0+A1.*dv0+A2.*dv0.*dv1+A3.*dv0.*dv1.*dv2;
ui=reshape(ui,sz);

function I4=find4near(x,y,z,xi,yi,zi)
% Find the 4 nearest neighbor-indexes for each point ri
% I4 is a 4xN matrix, where N is the length of xi.
% Divide into blocks of memory reasons

%Covert to column and row vectors;
x=x(:);y=y(:);z=z(:);
xi=xi(:)';yi=yi(:)';zi=zi(:)';

Nd=length(x);
Nv=length(xi);
p=floor(Nv*Nd/1e6); %1000x1000 matrix maximum
if p~=0
    n=floor(Nv/p);
    n_rest=Nv-p*n;
    Rij=zeros(Nd,p);Idx=zeros(Nd,p);I4=zeros(4,Nv);   %allocate memory
    for j=1:p
        ind=(1+(j-1)*n:1:j*n);
        Rij=(x*ones(1,n)-ones(Nd,1)*xi(ind)).^2+...
            (y*ones(1,n)-ones(Nd,1)*yi(ind)).^2+...
            (z*ones(1,n)-ones(Nd,1)*zi(ind)).^2;
        [Rij,Idx]=sort(Rij);
        I4(1:4,ind)=Idx(1:4,:);
    end
    ind=(n*p+1:1:Nv);clear Rij Idx;
    Rij=(x*ones(1,n_rest)-ones(Nd,1)*xi(ind)).^2+...
        (y*ones(1,n_rest)-ones(Nd,1)*yi(ind)).^2+...
        (z*ones(1,n_rest)-ones(Nd,1)*zi(ind)).^2;
    [Rij,Idx]=sort(Rij);
    I4(1:4,ind)=Idx(1:4,:);
else
    Rij=(x*ones(1,Nv)-ones(Nd,1)*xi).^2+...
            (y*ones(1,Nv)-ones(Nd,1)*yi).^2+...
            (z*ones(1,Nv)-ones(Nd,1)*zi).^2;
    [Rij,Idx]=sort(Rij);
    I4=Idx(1:4,:);
end

Contact us at files@mathworks.com