function [y,yp] = hermiteval(rho,t,tau,s_in,w,D)
%
% [y,yp] = hermiteval( rho, t, tau, s, w, D )
% (c)  Robert M. Corless, 2007
% Evaluate a Hermite Interpolant and its derivative
% at a potentially large number of points, t.
% y^(j)(tau(i))/j! = rho(k) where k = s(1)+s(2)+...s(i-1)+j+1
% confluencies s(i)
% generalized barycentric weights w
% differentiation matrix D (Taylor form if rho is)
%
% based on a code fragment in Berrut and Trefethen
% exact node value requests replaced with input data
% or (possibly) computed derivatives if t=tau(i) and s(i)=1
% 
n = length( tau );
m = length( t ); % expect m >> n

if max(size(s_in))==1,
    s = s_in*ones(n,1);
else
    s = s_in;
end;
smax = max(s);

numer = zeros(m,1);
denom = zeros(m,1);
exact = zeros(m,1); % which t-values are exactly nodes

temp = zeros(m,smax);

if nargout>1,
    dert   = D*rho(:);  % D must match rho's form; Taylor or not
    numerd = zeros(m,1);
end;

ik = 0;
for i=1:n,
    tdiff = t(:) - tau(i);
    % B-T trick had a typo, fixed now!  i, not 1
    exact(tdiff==0) = i;  % nonzero is true
    % Second barycentric Hermite form
    for j=1:s(i),
        temp(:,j) = w(i,j)./(tdiff.^j);
        rhoik = zeros(m,1);
        if nargout>1,
            rhoikd = zeros(m,1);
        end;
        for k=j:-1:1,
            rhoik = rho(ik+k) + tdiff.*rhoik;
            if nargout>1,
                rhoikd = dert(ik+k) + tdiff.*rhoikd;
            end;
        end;
        numer  = numer + temp(:,j).*rhoik;
        if nargout>1,
            numerd = numerd + temp(:,j).*rhoikd;
        end;
        denom = denom + temp(:,j);
    end;
    ik = ik + s(i);
end;
y = numer./denom;
if nargout>1,
    yp= numerd./denom;
end;


% for replacing node-poles, flatten data for easy access.

ik = 1+cumsum(s(:)');
ik = [1,ik(1:n-1)]; % [1,s(1)+1,s(1)+s(2)+1,...,] points at y-vals
rhoflat = rho(ik); 

jj=find(exact);  % Berrut-Trefethen trick

y(jj) = rhoflat(exact(jj));
if nargout>1,
    dertflat = dert(ik);
    yp(jj) = dertflat(exact(jj));
end;
        
        

            

