function [Xi,Yi,Zi] = invdistgrid(X,Y,Z,dx,varargin)
%INVDISTGRID Simple, robust gridding using inverse-distance interpolation.
% [Xi,Yi,Zi] = invdistgrid[X,Y,Z,dx] Grids values in vector Z with
% coordinates X and Y into an array with spacing dx using inverse-
% distance weighting (default power =2). All data between grid points
% are used in weighting. If no data exists between points, a NaN is
% entered. X and Y must be vectors and Z must be of the same length.
% Z can be an m by n array, with each column a dataset, and Zi will
% be a three-dimnesional array with n layers.
%
% [Xi,Yi,Zi] = invdistgrid[X,Y,Z,dx,p] Replaces the default weighting
% power 2 with the integer p. The higher the value of p, the more
% weight will be given to closer data values.
%
% NOTE: You can use FILLNANS.m or INPAINT_NANS.m to fill in the NaN
% values in Zi.
%
% Ian M. Howat, Applied Physics Lab, University of Washington
% ihowat@apl.washington.edu
% Version 1: 09-Jul-2007 13:47:46
%weighting power
p = 2;
if nargin == 5;
p = varargin{1};
end
%round the data locations to the interpolation grid spacing
XX = round(X./dx).*dx;
YY = round(Y./dx).*dx;
XYZ = sortrows([XX YY X Y Z],[2 1]);
ind = [0; XYZ(2:end,2) == XYZ(1:end-1,2) & XYZ(2:end,1) == XYZ(1:end-1,1); 0];
if sum(ind) > 0
fs = find(ind(1:end-1) == 0 & ind(2:end) == 1);
fe = find(ind(1:end-1) == 1 & ind(2:end) == 0);
for k = 1 : length(fs)
D = repmat(sqrt((XYZ(fs(k),1) - XYZ(fs(k):fe(k),3)).^2+...
(XYZ(fs(k),2)-XYZ(fs(k):fe(k),4)).^2),[1,size(Z,2)]);
D(D == 0) = .00001;
XYZ(fe(k),5:end) = sum(XYZ(fs(k):fe(k),5:end)./(D.^p))./ sum(1./(D.^p));
end
XYZ = XYZ(~ind(2:end),:);
end
Xi = min(XYZ(:,1)):dx:max(XYZ(:,1));
Yi = fliplr(min(XYZ(:,2)):dx:max(XYZ(:,2)))';
c = (XYZ(:,1) -Xi(1)+dx)./dx;
r = (Yi(1)-XYZ(:,2)+dx)./dx;
I = index([r,c],length(Yi));
for k = 1:size(Z,2)
tmp = ones(length(Yi),length(Xi)).*NaN;
tmp(I) = XYZ(:,4+k);
Zi(:,:,k) = tmp;
end
function I = index(ij,m)
% I = index([ij],[M]); Returns column-wise index equivalent I of position i j within
% an M row array.
i = ij(:,1);
j = ij(:,2);
I = (j.* m) - m + i;
%return I as a column vector
I = reshape(I,[length(I) 1]);