Code covered by the BSD License  

Highlights from
Smoooth and Differentiate

image thumbnail
from Smoooth and Differentiate by Carlos J. Dias
A function that smoothes and calculates the first derivative of a two column matrix input data.

ynew=smoothdiff(dados,xnew,sdx,q,nmin)
function ynew=smoothdiff(dados,xnew,sdx,q,nmin)
%
% function ynew=smoothdiff(dados,xnew,sdx,q,nmin)
%
% This function smooths and differentiates a sequence of numbers based on
% an algorithm similar to Savistky and Golay. There are no restrictions
% however, on the number of points or on their spacing.
% This function also calculates the first derivative at the xnew points
%
% INPUT:
% dados - data in a two column matrix (first column x; second column y)
% xnew - is a vector where new ordinates are to be computed
%
% sdx - is the range of data to be used in the interpolation
% nmin - is the minimum data points to be used in the interpolation.
% q - is the degree of the polynomial to be used in the interpolation
%
% When sdx range includes fewer points than nmin the range is
% enlarged to include at least nmin points. This occurs mainly at the edges
% of the data.
% Note that we should have nmin>q
%
% OUTPUT (ynew - 5 column matrix)
% column 1- new abscissas
% column 2- new ordinates
% column 3- their standard error
% column 4- first derivative
% column 5- no. of values that were calculated for the ith point
%


if q+1>nmin
    error('Polynomial degree should not be lower than min. no. of points');
end

x=dados(:,1);
y=dados(:,2);
clear dados

if max(xnew)>max(x) || min(xnew)<min(x)
    error('New data outside data range. Please remove extrapolation points.');
end

N=length(x);
Nnew=length(xnew);

% [x y delta^2 y' N]
ynew=[xnew zeros(Nnew,1) Inf*ones(Nnew,1) zeros(Nnew,2)];
% [yi delta(i)^2 y'(i)]
ynew1=zeros(Nnew,3);

for ii=1:Nnew
    JJ=find (x>=xnew(ii)-sdx & x<=xnew(ii)+sdx);
    
    %TREATMENT OF END EFFECTS
    if length(JJ)<nmin
        
        mn=ceil((nmin-length(JJ))/2);
        JJ=JJ(1)-mn:JJ(1)-mn+nmin;
        
        if min(JJ)<1
            JJ=JJ-min(JJ)+1;
        end
        if max(JJ)>N
            JJ=JJ-max(JJ)+N;
        end
        
    end
    
    %ACTUAL CALCULATION
    [p,s,mu]=polyfit(x(JJ),y(JJ),q);
    
    %RECALCULATING VALUES USING THE FITTED POLYNOMIAL
    JJ=find (xnew>=min(x(JJ)) & xnew<=max(x(JJ)));
    
    [ynew1(JJ,2),ynew1(JJ,3)]=polyval(p,xnew(JJ),s,mu);
    ynew1(JJ,3)=ynew1(JJ,3).^2;
    ynew1(JJ,4)=polyval(polyder(p)/mu(2),xnew(JJ),[],mu);
    ynew(JJ,5)=ynew(JJ,5)+1;
    
    figure(1);plot(x,y,xnew(JJ),ynew1(JJ,2),'.');

    ynew(JJ,2)=ynew1(JJ,2)./ynew1(JJ,3)+ynew(JJ,2)./ynew(JJ,3);
    ynew(JJ,4)=ynew1(JJ,4)./ynew1(JJ,3)+ynew(JJ,4)./ynew(JJ,3);
    
    ynew(JJ,3)=1./(1./ynew1(JJ,3)+1./ynew(JJ,3));
    
    ynew(JJ,2)=ynew(JJ,2).*ynew(JJ,3);
    ynew(JJ,4)=ynew(JJ,4).*ynew(JJ,3);
            
end

ynew(:,3)=sqrt(ynew(:,3));
figure(1)
subplot(2,1,1);plot(x,y,xnew,ynew(:,2),'r');grid
title('Smoothed and Unsmoothed function');
subplot(2,1,2);plot(xnew,ynew(:,4));grid
title('First derivative');
%subplot(3,1,3);errorbar(xnew,ynew(:,2),ynew(:,3));grid
end

Contact us at files@mathworks.com