download smooth.m
Language: Matlab
LOC: 59
Project Info
MatLinks/Chorus(matlinks)
Server: SourceForge
Type: cvs
...est\copyleft\gpl\wafo\misc\
   binom.m
   ccquad.m
   cltext.m
   Contents.m
   figtext.m
   findpeaks.m
   gaussq.m
   gaussq2d.m
   gravity.m
   h1line.m
   hypgf.m
   levels.m
   loaddata.m
   mkcont.m
   qrule.m
   qrule2d.m
   simpson.m
   smooth.m
   wafostamp.m
   wafoversion.m
   wdensity.m

function [yy,coefs]= smooth(x,y,p,xx,LinExtrap,d2)
% SMOOTH Calculates a smoothing spline.
% 
%  CALL:  yy = smooth(x,y,p,xx,def,d2)
%
%         x  = x-coordinates of data.
%         y  = y-coordinates of data.
%         p  = [0...1] is a smoothing parameter:
%              0 -> LS-straight line
%              1 -> cubic spline interpolant
%         xx = the x-coordinates in which to calculate the smoothed function.
%         yy = the calculated y-coordinates of the smoothed function.
%        def = 0 regular smoothing spline (default)
%              1 a smoothing spline with a constraint on the ends to 
%                ensure linear extrapolation outside the range of the data
%         d2 = variance of each y(i) (default  ones(length(X),1)) 
%
%  Given the approximate values 
%  
%                y(i) = g(x(i))+e(i) 
%  
%  of some smooth function, g, where e(i) is the error. Smooth tries to 
%  recover g from y by constructing a function, f, which  minimizes
%
%              p * sum (Y(i) - f(X(i)))^2/d2(i)  +  (1-p) * int (f'')^2
%
%  The call  pp = smooth(x,y,p)  gives the pp-form of the spline, 
%  for use with PPVAL. 
%  
% See also: lc2tr, dat2tr


%References:
% Carl de Boor (1978)
% 'Practical Guide to Splines'
%  Springer Verlag
%  Uses EqXIV.6--9, pp 239

% tested on: Matlab 4.x 5.x
%History:
% revised by pab 21.09.99
%    - added d2
% revised by pab 29.08.99
%    -new extrapolation: ensuring that
%     the smoothed function has contionous derivatives
%     in the first and last knot
% modified by Per A. Brodtkorb  23.09.98 
%  secret option forcing linear extrapolation outside the ends when p>0
%  used in lc2tr

if (nargin<5)|(isempty(LinExtrap)),
  LinExtrap=0; %do not force linear extrapolation in the ends (default)
end
n=length(x);

[xi,ind]=sort(x);xi=xi(:);

if n<2,
   error('There must be >=2 data points.')
elseif ~all(diff(xi)),
   error('Two consecutive values in x can not be equal.')
elseif n~=length(y),
   error('x and y must have the same length.')
end

if nargin<6|isempty(d2), 
  d2 = ones(n,1);  %not implemented yet
else
  d2=d2(:);
end

    
yi=y(ind); yi=yi(:);

dx=diff(xi);
if (LinExtrap & (n>6) & (p~=0)),
  Q=spdiags([1./dx(2:n-3) -(1./dx(2:n-3)+1./dx(3:n-2)) ...
	     1./dx(3:n-2)],0:-1:-2,n-2,n-4);
  D=spdiags(d2(2:n-1),0,n-2,n-2); % The variance
else
  Q=spdiags([1./dx(1:n-2) -(1./dx(1:n-2)+1./dx(2:n-1)) ...
	     1./dx(2:n-1)],0:-1:-2,n,n-2);
  D=spdiags(d2(:),0,n,n);  % The variance
end
if (n==2) | ((p==0) & (nargin<6)), % LS-straight line
  ai=yi-Q*(Q\yi);
  coefs=[diff(ai)./dx ai(1:n-1)];
else
  if LinExtrap & n>6 & (p~=0), %forcing linear extrapolation in the ends 
    % new call : so ci(1:2)=ci(n-1:n)=di(1)=di(n)=0
    R=spdiags([dx(2:n-3) 2*(dx(2:n-3)+dx(3:n-2)) dx(3:n-2)],-1:1,n-4,n-4);
    
    QQ=(6*(1-p))*(Q.'*D*Q)+p*R;
    % Make sure Matlab uses symmetric matrix solver
    u=2*((QQ+QQ')\diff(diff(yi(2:n-1))./dx(2:n-2))); %faster than 2*(QQ+QQ.'')\(Q'*yi);

    % The piecewise polynominals are written as
    % fi=ai+bi*(x-xi)+ci*(x-xi)^2+di*(x-xi)^3 
    ai=yi(2:n-1)-(6*(1-p)*D*diff([0;diff([0;u;0])./dx(2:n-2);0]));%faster than yi-6*(1-p)*D*Q*u ;
    ci=3*p*[0;0;u;0];
    % fixing the coefficients so that we have contionous 
    % derivatives everywhere
    a1=-(ai(2)-ai(1))*dx(1)/dx(2) +ai(1)+ ci(3)*dx(1)*dx(2)/3;
    an=(ai(n-2)-ai(n-3))*dx(n-1)/dx(n-2) +ai(n-2)+ ci(n-2)*dx(n-2)*dx(n-1)/3;  
    ai=[a1;ai; an];
  
  else
    R=spdiags([dx(1:n-2) 2*(dx(1:n-2)+dx(2:n-1)) dx(2:n-1)],-1:1,n-2,n-2);
    QQ=(6*(1-p))*(Q.'*D*Q)+p*R;
    % Make sure Matlab uses symmetric matrix solver
    u=2*((QQ+QQ')\diff(diff(yi)./dx)); % faster than u=QQ\(Q'*yi);
    ai=yi-6*(1-p)*D*diff([0;diff([0;u;0])./dx;0]);%faster than yi-6*(1-p)*Q*u
  
    %derivatives in the knots according to Carl de Boor
    %    dfi=6*p*[0;u];
    %    ddfi=diff([ci;0])./dx;
    %    dddfi=diff(ai)./dx-(ci/2+di/6.*dx).*dx;
    % thus the coefficients for the piecewise polynominals 
    %fi(x)=ai+bi*(x-xi)+ci*(x-xi)^2+di*(x-xi)^3 are
    ci=3*p*[0;u];
   
  end
  % old call: linear extrapolation
  % crude the derivatives are not necessarily continous
  % where we force ci and di to zero
  %if LinExtrap, %forcing linear extrapolation in the ends 
  %  ci([2,  end])=0;  % could be done better
  %  %di([1 end])=0;
  %end
  di=diff([ci;0])./dx/3;
  
  bi=diff(ai)./dx-(ci+di.*dx).*dx;
  coefs=[di ci bi ai(1:n-1)]; 
end

pp=mkpp(xi,coefs);

if (nargin<4)|(isempty(xx)),
  yy=pp;
else
  yy=ppval(pp,xx);
end


About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us