No BSD License  

Highlights from
lagrange interpolation and derivative

from lagrange interpolation and derivative by Geoff Wawrzyniak
This function performs the Lagrange interpolation of a function and its derivative.

y=lagrange(x,pointx,pointsy,dydx_on)
function y=lagrange(x,pointx,pointsy,dydx_on)
%
%LAGRANGE  approx a point-defined function using the Lagrange polynomial interpolation
%
%    LAGRANGE(X,POINTX,POINTY) approx the function definited by the points:
%    P1=(POINTX(1),POINTY(1)), P2=(POINTX(2),POINTY(2)), ..., PN(POINTX(N),POINTY(N))
%    and calculate it in each elements of X
%
%    If POINTX and POINTY have different number of elements the function will return the NaN value
% DERIVATIVE FUNCTIONS
%    LAGRANGE(X,POINTX,POINTY,1) computes the derivative at X
%    LAGRANGE(X,POINTX,POINTY,2) computes the derivative at X by finding the solution at X, then re-running with option 1 to find the derivative there.  This is numerically unstable for small step size of X and should not be trusted at tails of the data set.  However, it can be more accurate than option 1. 
%
%    NOTE: When dealing with lots of control points, this algorithm works best by buffering the interpolation period with more control points outside that epoch.  However, the more control points, the slower this gets.
%
%    function wrote by: Calzino
%    7-oct-2001
%    modified by GGW on 2-AUG-2006
%
if nargin < 4
  dydx_on = 0 ;  % so differentiation can be in the same script 
end

% operation on rows of data (i.e., px = [x0 x1 ... xn], py = [y0 y1 ... yn])
x = x(:).' ; 
[ytr,pointsy,pointx] = dimchecking(pointsy,pointx) ; 

s = size(x,2) ; 
n = size(pointx,2);

if dydx_on == 1
  Linit = zeros(n,s) ; 
else
  Linit = ones(n,s);
end

y=zeros(size(pointsy,1),s);

for h = 1:size(pointsy,1) ; 
  L = Linit ; 
  pointy = pointsy(h,:) ; 

  for j=1:n
    for i=1:n
      if (j~=i)
        if dydx_on == 1
          dlprod = ones(1,s) ;
          for k = 1:n
            if k~=j && k~=i
              dlprod = dlprod .* (x-pointx(k))/(pointx(j)-pointx(k)) ; 
            end 
          end
          L(j,:) = L(j,:) + 1/(pointx(j)-pointx(i))*dlprod ; 
        else
          L(j,:) = L(j,:) .* (x-pointx(i))./(pointx(j)-pointx(i));
        end
      end
    end
  end

  for j = 1:n
    y(h,:) = y(h,:) + pointy(j)*L(j,:);
  end

  if dydx_on == 2
    y(h,:) = lagrange(x,x,y,1) ; 
  end

end

if ytr 
  y = y.' ; 
end

%=========================================
function [ytr,pointsy,pointx] = dimchecking(pointsy,pointx)  
xtr = 0 ; 
if length(pointx) ~= length(pointx(:))
  error('pointx must be a vector')
end
if size(pointx) ~= size(pointx(:).')
  xtr = 1 ; 
end 
pointx = pointx(:).' ; 

ytr = 0 ;  % y got transposed? had to transpose input, yes = 1

if numel(pointsy) == length(pointsy) % pointsy is a vector
  tempy = pointsy(:).' ; 
  if size(tempy) ~= size(pointsy)
    ytr = 1 ;  
  end
  pointsy = tempy ; 
else % pointsy is an array 
  if size(pointsy,2) ~= size(pointx,2) 
    if size(pointsy,1) ~= size(pointx,2)  % no hope for a transpose
      error('pointsy must have same number of states as elements in pointx')
    else
    pointsy = pointsy.' ; 
    ytr = 1 ; 
    end
  end
  if size(pointsy) == size(pointsy.')  % square matrix case, assume that rows 
    if xtr                             % of pointx match rows of pointsy or
      pointsy = pointsy.' ;            % cols of pointx match cols of pointsy
      ytr = 1 ; 
      disp('Warning: pointx is a column, I will assume corresponding pointsy are columns')
    end
      disp('Warning: pointx is a row, I will assume corresponding pointsy are rows')
  end
end

if size(pointsy,2) ~= size(pointx,2)
  error('pointsy must have same number of states as elements in pointx')
end 

return

Contact us at files@mathworks.com