设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1246|回复: 0

三次样条插值

[复制链接]

8

主题

80

金钱

115

积分

入门用户

发表于 2018-9-13 15:29:33 | 显示全部楼层 |阅读模式
  1. function output = spline(x,y,xx)
  2. %三次样条插值
  3. %yi=spline(x,y,xi)等价于YI=interp(x,y,xi,'spline'),
  4. %     根据数据(x,y)给出在xi的线性插值结果yi..
  5. %     使用"非扭结"端点条件, 即强迫第一﹑二端多项式三次项系数相同,
  6. %     最后一段和倒数第二段三次项系数相同.
  7. %pp=spline(x,y)返回样条插值的分段多项式(pp形式).
  8. %[breaks,coefs]=unmkpp(pp)将pp形式展开,其中breaks为结点,coefs为各段多项式系数.
  9. %yi=ppval(pp,xi),pp形式在xi的函数值.
  10. %例 考虑数据
  11. %          x  | 1  2  4  5
  12. %         ---|-------------
  13. %          y  | 1  3  4  2
  14. %      clear;close;
  15. %      x=[1 2 4 5];y=[1 3 4 2];
  16. %      p=spline(x,y);
  17. %      xi=1:0.1:5;yi=ppval(p,xi);
  18. %      plot(x,y,'o',xi,yi,'k');
  19. %      title('not-a-knot SPLINE');
  20. %      [b,c]=unmkpp(p)
  21. %另一个例子见下列英文部分
  22. %
  23. %SPLINE Cubic spline data interpolation.
  24. %   YY = SPLINE(X,Y,XX) uses cubic spline interpolation
  25. %   to find a vector YY corresponding to XX.  X and Y are the
  26. %   given data vectors and XX is the new abscissa vector.
  27. %
  28. %   The ordinates Y may be vector-valued, in which case Y(:,j) is
  29. %   the j-th ordinate.
  30. %
  31. %   PP = SPLINE(X,Y) returns the pp-form of the cubic spline
  32. %   interpolant instead, for later use with  PPVAL, etc.
  33. %
  34. %   Ordinarily, the not-a-knot end conditions are used. However, if
  35. %   Y contains two more ordinates than X has entries, then the first
  36. %   and last ordinate in Y are used as the endslopes for the cubic spline.
  37. %
  38. %   Here's an example that generates a coarse sine curve, then
  39. %   samples the spline over a finer mesh:
  40. %
  41. %       x = 0:10;  y = sin(x);
  42. %       xx = 0:.25:10;
  43. %       yy = spline(x,y,xx);
  44. %       plot(x,y,'o',xx,yy)
  45. %
  46. %   Here is an example that features a vector-valued spline, along with complete
  47. %   spline interpolation, i.e., fitting to given end slopes (instead of using the
  48. %   not-a-knot end condition); it uses SPLINE to generate a circle:
  49. %
  50. %       circle = spline( 0:4, [0 1 0 -1 0 1 0; pi/2 0 1 0 -1 0 pi/2] );
  51. %       xx = 0:.1:4; cc = ppval(circle, xx); plot(cc(1,:), cc(2,:)), axis equal
  52. %
  53. %   See also INTERP1, PPVAL, SPLINES (The Spline Toolbox).

  54. %   Carl de Boor 7-2-86
  55. %   Revised 11-24-87 JNL, 6-16-92 CBM, 10-14-97 CB.
  56. %   Copyright (c) 1984-98 by The MathWorks, Inc.
  57. %   $Revision: 5.11 $  $Date: 1997/12/03 19:22:33 $

  58. % Generate the cubic spline interpolant in pp form, depending on the
  59. % number of data points (and usually using the not-a-knot end condition).

  60. output=[];
  61. n=length(x);
  62. if n<2, error('There should be at least two data points.'), end

  63. if any(diff(x)<0), [x,ind]=sort(x); else, ind=1:n; end

  64. x=x(:); dx = diff(x);
  65. if all(dx)==0, error('The data abscissae should be distinct.'), end

  66. [yd,yn] = size(y); % if Y happens to be a column matrix, change it to
  67.                    % the expected row matrix.
  68. if yn==1, yn=yd; y=reshape(y,1,yn); yd=1; end

  69. if yn==n
  70.    notaknot = 1;
  71. elseif yn==n+2
  72.    notaknot = 0; endslopes = y(:,[1 n+2]).'; y(:,[1 n+2])=[];
  73. else
  74.    error('Abscissa and ordinate vector should be of the same length.')
  75. end

  76. yi=y(:,ind).'; dd = ones(1,yd);
  77. dx = diff(x); divdif = diff(yi)./dx(:,dd);
  78. if n==2
  79.    if notaknot, % the interpolant is a straight line
  80.       pp=mkpp(x.',[divdif.' yi(1,:).'],yd);
  81.    else         % the interpolant is the cubic Hermite polynomial
  82.       divdif2 = diff([endslopes(1,:);divdif;endslopes(2,:)])./dx([1 1],dd);
  83.       pp = mkpp(x,...
  84.       [(diff(divdif2)./dx(1,dd)).' ([2 -1]*divdif2).' ...
  85.                                            endslopes(1,:).' yi(1,:).'],yd);
  86.    end
  87. elseif n==3¬aknot, % the interpolant is a parabola
  88.    yi(2:3,:)=divdif;
  89.    yi(3,:)=diff(divdif)/(x(3)-x(1));
  90.    yi(2,:)=yi(2,:)-yi(3,:)*dx(1);
  91.    pp = mkpp([x(1),x(3)],yi([3 2 1],:).',yd);
  92. else % set up the sparse, tridiagonal, linear system for the slopes at  X .
  93.    b=zeros(n,yd);
  94.    b(2:n-1,:)=3*(dx(2:n-1,dd).*divdif(1:n-2,:)+dx(1:n-2,dd).*divdif(2:n-1,:));
  95.    if notaknot
  96.       x31=x(3)-x(1);xn=x(n)-x(n-2);
  97.       b(1,:)=((dx(1)+2*x31)*dx(2)*divdif(1,:)+dx(1)^2*divdif(2,:))/x31;
  98.       b(n,:)=...
  99.       (dx(n-1)^2*divdif(n-2,:)+(2*xn+dx(n-1))*dx(n-2)*divdif(n-1,:))/xn;
  100.    else
  101.       x31 = 0; xn = 0; b([1 n],:) = dx([1 n-2],dd).*endslopes;
  102.    end
  103.    c = spdiags([ [dx(2:n-1);xn;0] ...
  104.         [dx(2);2*[dx(2:n-1)+dx(1:n-2)];dx(n-2)] ...
  105.         [0;x31;dx(1:n-2)] ],[-1 0 1],n,n);

  106.    % sparse linear equation solution for the slopes
  107.    mmdflag = spparms('autommd');
  108.    spparms('autommd',0);
  109.    s=c\b;
  110.    spparms('autommd',mmdflag);
  111.    % convert to pp form
  112.    c4=(s(1:n-1,:)+s(2:n,:)-2*divdif(1:n-1,:))./dx(:,dd);
  113.    c3=(divdif(1:n-1,:)-s(1:n-1,:))./dx(:,dd) - c4;
  114.    pp=mkpp(x.',...
  115.      reshape([(c4./dx(:,dd)).' c3.' s(1:n-1,:).' yi(1:n-1,:).'],(n-1)*yd,4),yd);
  116. end
  117. if nargin==2
  118.    output=pp;
  119. else
  120.    output=ppval(pp,xx);
  121. end
复制代码


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表