function [yi, u, ypi, yppi] = floaterhormann(x, y, xi, c)
% FLOATERHORMANN Rational interpolation using the Floater-Hormann Method
% FLOATERHORMANN(X,Y,XI,C) interpolates to find YI, the values of the
% underlying function Y at the points in the array XI, using
% Floater-Hormann rational interpolation. X and Y must be
% vectors of length N.
%
% C specifies the order of the interpolating polynomial
% (0 <= C <= N). The default is C = 0 (Berrut rational interpolation).
%
% [YI,U] = FLOATERHORMANN() also returns the barycentric interpolation
% weights U.
%
% [YI,U,YPI,YPPI] = FLOATERHORMANN() also returns the interpolated
% derivative YPI and the interpolated second derivative YPPI.
% Joe Henning - Fall 2011
% Barycentric Rational Interpolation with no Poles and High Rates of Approximation
% Michael S. Floater and Kai Hormann
% Ifl Technical Report Series, Ifl-06-06
if (nargin < 4)
c = 0;
end
n = length(x);
if (n-1 < c)
fprintf('??? Bad c input to floaterhormann ==> c <= length(x)-1\n');
yi = [];
u = [];
ypi = [];
yppi = [];
return
end
% calculate Floater-Hormann coefficients
u = [];
for k = 1:n
u(k,1) = 0;
for m = k-c:k
prod = 1;
if (m < 1 || m > n-c)
continue
end
for j = m:m+c
if (j ~= k)
prod = prod/(x(k)-x(j));
end
end
u(k,1) = u(k,1) + (-1)^m*prod;
end
end
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 floaterhormann ==> x values must be distinct\n');
yi(i) = NaN;
ypi(i) = NaN;
yppi(i) = NaN;
continue;
end
isiny = 0;
for k = 1:n
if (xi(i) == x(k))
yi(i) = y(k);
num = 0;
for j = 1:n
if (j ~= k)
num = num + u(j)*(y(k)/(x(k)-x(j)) + y(j)/(x(j)-x(k)));
end
end
ypi(i) = -num/u(k);
num = 0;
for j = 1:n
if (j ~= k)
num = num + u(j)*(ypi(i)-(y(k)/(x(k)-x(j)) + y(j)/(x(j)-x(k))))/(x(k)-x(j));
end
end
yppi(i) = -2*num/u(k);
isiny = 1;
break
end
end
if (isiny)
continue
end
% Evaluate polynomial
num = 0;
den = 0;
for k = 1:n
num = num + y(k)*u(k)/(xi(i)-x(k));
den = den + u(k)/(xi(i)-x(k));
end
yi(i) = num/den;
num = 0;
den = 0;
for k = 1:n
term = yi(i)/(xi(i)-x(k)) + y(k)/(x(k)-xi(i));
num = num + term*u(k)/(xi(i)-x(k));
den = den + u(k)/(xi(i)-x(k));
end
ypi(i) = num/den;
num = 0;
den = 0;
for k = 1:n
term = (ypi(i)-(yi(i)/(xi(i)-x(k)) + y(k)/(x(k)-xi(i))))/(xi(i)-x(k));
num = num + term*u(k)/(xi(i)-x(k));
den = den + u(k)/(xi(i)-x(k));
end
yppi(i) = 2*num/den;
end