Code covered by the BSD License  

Highlights from
Interpolation Utilities

Interpolation Utilities

by

 

22 May 2012 (Updated )

A variety of interpolation utilities

sincint(x, y, xi, c, win)
function [yi, ypi] = sincint(x, y, xi, c, win)

% SINCINT 1-D piecewise sinc interpolation
%    SINCINT(X,Y,XI,C,WIN) interpolates to find YI, the values of the
%    underlying function Y at the points in the array XI, using
%    piecewise sinc interpolation.  X and Y must be vectors 
%    of length N.
%
%    C specifies the number of data points to use in the
%    interpolation.  The default is to use all points.
%
%    If WIN is nonzero, a window is applied to the sinc interpolator.
%    Possible windows are:
%        0 : Rectangular window (default)
%        1 : Lanczos window
%        2 : Hamming window
%        3 : Squared cosine window
%        4 : Kaiser window (alpha = 3)
%        5 : Blackman window
%
%    [YI,YPI] = SINCINT() also returns the interpolated derivative
%    of the underlying function Y at points XI.

% Joe Henning - Fall 2011

if (nargin < 4)
   c = 0;
   win = 0;
elseif (nargin < 5)
   win = 0;
end

n = length(x);

if (n < c)
   fprintf('??? Bad c input to sincint ==> c <= length(x)\n');
   yi = [];
   ypi = [];
   return
end

% Find the period of the undersampled signal
T = x(2) - x(1);

for i = 1:length(xi)
   % Find the right place in the table by means of a bisection.
   klo = 1;
   khi = n;
   while (khi-klo > 1)
      k = fix((khi+klo)/2.0);
      if (x(k) > xi(i))
         khi = k;
      else
         klo = k;
      end
   end
   
   h = x(khi) - x(klo);
   if (h == 0.0)
      fprintf('??? Bad x input to sincint ==> x values must be distinct\n');
      yi(i) = NaN;
      ypi(i) = NaN;
      continue;
   end

   % Evaluate sinc
   yi(i) = 0;
   ypi(i) = 0;
   if (c == 0)
      for k = 1:n
         if ((1/T)*abs(xi(i)-x(k)) > (n-1)/2 && win > 0)
            w = 0;
            wp = 0;
         else
            if (win == 5)
               alpha = 0.16;
               a0 = (1-alpha)/2.0;
               a1 = 1/2.0;
               a2 = alpha/2.0;
               w = a0 + a1*cos(2*pi*(1/T)*(xi(i)-x(k))/(n-1)) + a2*cos(4*pi*(1/T)*(xi(i)-x(k))/(n-1));
               wp = -a1*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1) - a2*4*pi*(1/T)*sin(4*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1);
            elseif (win == 4)
               alpha = 3.0;
               arg1 = pi*alpha;
               arg2 = arg1*sqrt(1 - (2*(1/T)*(xi(i)-x(k))/(n-1))*(2*(1/T)*(xi(i)-x(k))/(n-1)));
               w = besseli(0,arg2)/besseli(0,arg1);
               wp = (besseli(0,arg1)*besseli(1,arg2) - besseli(1,arg1)*besseli(0,arg2))/(besseli(0,arg1)*besseli(0,arg1));
               w = real(w);
               wp = real(wp);
            elseif (win == 3)
               w = cos(pi*(1/T)*(xi(i)-x(k))/(n-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(n-1));
               wp = -2*sin(pi*(1/T)*(xi(i)-x(k))/(n-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(n-1)) * pi*(1/T)/(n-1);
            elseif (win == 2)
               w = 0.54 + 0.46*cos(2*pi*(1/T)*(xi(i)-x(k))/(n-1));
               wp = -0.46*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1);
            elseif (win == 1)
               w = sinc(2*(1/T)*(xi(i)-x(k))/(n-1));
               wp = 2*(1/T)*cosc(2*(1/T)*(xi(i)-x(k))/(n-1))/(n-1);
            else
               w = 1;
               wp = 0;
            end
         end
         yi(i) = yi(i) + y(k)*sinc((1/T)*(xi(i)-x(k)))*w;
         ypi(i) = ypi(i) + y(k)*(wp*sinc((1/T)*(xi(i)-x(k))) + w*(1/T)*cosc((1/T)*(xi(i)-x(k))));
      end
   else
      if (mod(c,2) == 0)   % even
         c2 = c/2;
         if (klo < c2)
            klo = c2;
         end
         if (klo > n-c2)
            klo = n-c2;
         end
         khi = klo + 1;
         for k = klo-(c2-1):klo+c2
            if ((1/T)*abs(xi(i)-x(k)) > (n-1)/2 && win > 0)
               w = 0;
               wp = 0;
            else
               if (win == 5)
                  alpha = 0.16;
                  a0 = (1-alpha)/2.0;
                  a1 = 1/2.0;
                  a2 = alpha/2.0;
                  w = a0 + a1*cos(2*pi*(1/T)*(xi(i)-x(k))/(n-1)) + a2*cos(4*pi*(1/T)*(xi(i)-x(k))/(n-1));
                  wp = -a1*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1) - a2*4*pi*(1/T)*sin(4*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1);
               elseif (win == 4)
                  alpha = 3.0;
                  arg1 = pi*alpha;
                  arg2 = arg1*sqrt(1 - (2*(1/T)*(xi(i)-x(k))/(c-1))*(2*(1/T)*(xi(i)-x(k))/(c-1)));
                  w = besseli(0,arg2)/besseli(0,arg1);
                  wp = (besseli(0,arg1)*besseli(1,arg2) - besseli(1,arg1)*besseli(0,arg2))/(besseli(0,arg1)*besseli(0,arg1));
                  w = real(w);
                  wp = real(wp);
               elseif (win == 3)
                  w = cos(pi*(1/T)*(xi(i)-x(k))/(c-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = -2*sin(pi*(1/T)*(xi(i)-x(k))/(c-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(c-1)) * pi*(1/T)/(c-1);
               elseif (win == 2)
                  w = 0.54 + 0.46*cos(2*pi*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = -0.46*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(c-1))/(c-1);
               elseif (win == 1)
                  w = sinc(2*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = 2*(1/T)*cosc(2*(1/T)*(xi(i)-x(k))/(c-1))/(c-1);
               else
                  w = 1;
                  wp = 0;
               end
            end
            yi(i) = yi(i) + y(k)*sinc((1/T)*(xi(i)-x(k)))*w;
            ypi(i) = ypi(i) + y(k)*(wp*sinc((1/T)*(xi(i)-x(k))) + w*(1/T)*cosc((1/T)*(xi(i)-x(k))));
         end
      else   % odd
         c2 = floor(c/2);
         if (klo < c2+1)
            klo = c2+1;
         end
         if (klo > n-c2)
            klo = n-c2;
         end
         khi = klo + 1;
         for k = klo-c2:klo+c2
            if ((1/T)*abs(xi(i)-x(k)) > (n-1)/2 && win > 0)
               w = 0;
               wp = 0;
            else
               if (win == 5)
                  alpha = 0.16;
                  a0 = (1-alpha)/2.0;
                  a1 = 1/2.0;
                  a2 = alpha/2.0;
                  w = a0 + a1*cos(2*pi*(1/T)*(xi(i)-x(k))/(n-1)) + a2*cos(4*pi*(1/T)*(xi(i)-x(k))/(n-1));
                  wp = -a1*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1) - a2*4*pi*(1/T)*sin(4*pi*(1/T)*(xi(i)-x(k))/(n-1))/(n-1);
               elseif (win == 4)
                  alpha = 3.0;
                  arg1 = pi*alpha;
                  arg2 = arg1*sqrt(1 - (2*(1/T)*(xi(i)-x(k))/(c-1))*(2*(1/T)*(xi(i)-x(k))/(c-1)));
                  w = besseli(0,arg2)/besseli(0,arg1);
                  wp = (besseli(0,arg1)*besseli(1,arg2) - besseli(1,arg1)*besseli(0,arg2))/(besseli(0,arg1)*besseli(0,arg1));
                  w = real(w);
                  wp = real(wp);
               elseif (win == 3)
                  w = cos(pi*(1/T)*(xi(i)-x(k))/(c-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = -2*sin(pi*(1/T)*(xi(i)-x(k))/(c-1)) * cos(pi*(1/T)*(xi(i)-x(k))/(c-1)) * pi*(1/T)/(c-1);
               elseif (win == 2)
                  w = 0.54 + 0.46*cos(2*pi*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = -0.46*2*pi*(1/T)*sin(2*pi*(1/T)*(xi(i)-x(k))/(c-1))/(c-1);
               elseif (win == 1)
                  w = sinc(2*(1/T)*(xi(i)-x(k))/(c-1));
                  wp = 2*(1/T)*cosc(2*(1/T)*(xi(i)-x(k))/(c-1))/(c-1);
               else
                  w = 1;
                  wp = 0;
               end
            end
            yi(i) = yi(i) + y(k)*sinc((1/T)*(xi(i)-x(k)))*w;
            ypi(i) = ypi(i) + y(k)*(wp*sinc((1/T)*(xi(i)-x(k))) + w*(1/T)*cosc((1/T)*(xi(i)-x(k))));
         end
      end
   end
end

function y = sinc(x)
% normalized sinc function
i = find(x == 0);
x(i) = 1;   % Don't need this if divide-by-zero warning is off
y = sin(pi*x)./(pi*x);
y(i) = 1;

function y = cosc(x)
% derivative of normalized sinc function
i = find(x == 0);
x(i) = 1;   % Don't need this if divide-by-zero warning is off
%y = (pi*pi*x.*cos(pi*x) - pi*sin(pi*x))./(pi*x*pi.*x);
y = cos(pi*x)./x - sin(pi*x)./(pi*x.*x);
y(i) = 0;

function y = zonk(x)
% second derivative of normalized sinc function
i = find(x == 0);
x(i) = 1;   % Don't need this if divide-by-zero warning is off
%y = (-2*pi^4*x.*x.*cos(pi*x) - pi^5*x.^3.*sin(pi*x) + 2*pi^3*x.*sin(pi*x))./(pi^4*x.^4);
y = -2*cos(pi*x)./(x.*x) - pi*sin(pi*x)./x + 2*sin(pi*x)./(pi*x.*x.*x);
y(i) = -pi*pi/3.0;

Contact us