Hermite函数在Matlab中的实现与应用


保形分段三次hermite插值



% 这是MATLAB里面的pchip.m文件。这里把它的凝视改写成汉语,主要是想弄清楚它是怎么计算在节点处的导数的。function v = pchip(x,y,xx)%输入:n个插值节点的纵坐标向量x;横坐标向量y;插值点xx。%输出:分段三次Hermite插值结果。% PCHIP Piecewise Cubic Hermite Interpolating Polynomial.% PP = PCHIP(X,Y)为X处的值Y提供了一种特定的保形分段三次厄尔米特插值(shape-preserving piecewise cubic Hermite interpolant)% 的分段多项式形式,在后面的PPVAL和样条功能UNMKPP(spline utility UNMKPP)将用到这个函数。% X必须是个向量。% 假设Y是个向量,则Y的第j个元素Y(j)被取为和X的第j个元素X(j)匹配的值,因此Y和X的长度必须一样。% 假设Y是一个矩阵,或者N维数组,则Y(:,...,:,j)被取为和X(j)相匹配的值,因此Y的最后一维必须等于length(X).% YY = PCHIP(X,Y,XX)和YY = PPVAL(PCHIP(X,Y),XX)是一样的,因此在YY中给出了在XX处的插值。% PCHIP插值函数p(x)满足:% 在每一个子区间X(k) <= x <= X(k+1),p(x)都是三阶Hermite插值多项式(给定插值点和两个端点的斜率)。% 因而。p(x) interpolates Y,也就是说。p(X(j)) = Y(:,j),而且一阶导数Dp(x)是连续的,可是% 二阶导数D^2p(x)可能不是连续的;在X(j)处可能会出现跳跃.% 在X(j)处的斜率的选取方法。确保了p(x)是"shape preserving"和"respects monotonicity"的,% 这意味着,在那些数据是单调的区间里,p(x)也是单调的;在那些数据是局部极值(local extremum)的点,% p(x)也取局部极值。%% PCHIP与SPLINE的对照:% SPLINE提供的函数s(x)的构建方法和PCHIP里面的函数p(x)全然同样,仅仅只是在X(j)处的斜率的选择方法不一样,% SPLINE函数的s(x)在X(j)的二阶导数D^2s(x)也是连续的,这导致了例如以下结果:% SPLINE更加光滑。也就是说。D^2s(x)是连续的。% 假设数据是一个光滑函数的值。则SPLINE更加精确。% 假设数据不是光滑的,则PCHIP没有overshoots,也不太震荡(less oscillation)。% PCHIP建立的难度较小(is less expensive to set up).% 这两种函数预计的难度是一样的。% 样条比pchip光滑,样条的两阶导数连续。而pchip一阶导数连续。不连续的两阶导数隐含着不连续的曲率。人的眼睛能够检測出图形上曲率的不连续。还有一方面,pchip是保形状的,而样条不一定保形状。%% 样例:% x = -3:3;% y = [-1 -1 -1 0 1 1 1];% t = -3:.01:3;% plot(x,y,'o',t,[pchip(x,y,t); spline(x,y,t)])% legend('data','pchip','spline',4)%% Class support for inputs x, y, xx:% float: double, single%% 还可參见INTERP1, SPLINE, PPVAL, UNMKPP.% 參考文献:% F. N. Fritsch and R. E. Carlson, "Monotone Piecewise Cubic% Interpolation", SIAM J. Numerical Analysis 17, 1980, 238-246.% David Kahaner, Cleve Moler and Stephen Nash, Numerical Methods% and Software, Prentice Hall, 1988.%% Copyright 1984-2004 The MathWorks, Inc.% $Revision: 1.7.4.4 $ $Date: 2004/03/02 21:47:53 $% 检验数据的可接受性,假设不可接受,则对其进行适当的调整[x,y,sizey] = chckxy(x,y); %chckxy返回三个变量:x,y,和sizey。可是不知道chckxy是什么意思。n = length(x); %n为向量x的长度。也就是后面要用的节点数目。h = diff(x); %diff表示把向量x的相邻元素相减。得到h=[X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)]m = prod(sizey); %%确保插值点是实数if nargin==3 && any(~isreal(reshape(xx,numel(xx),1))) error('MATLAB:pchip:ComplexInterpPts',... 'The interpolation points should be real.')end%计算斜率del = diff(y,1,2)./repmat(h,m,1);% diff(y,n,dim)是在标量dim指定的维度上进行n次差分。假设阶数n等于或超过第dim维的长度,则diff返回一个空的数组。% 比如y=[1 3 4 6 9 10 8 12];则diff(y,1,2)=[2 1 2 3 1 -2 4];% repmat(h,m,1)把矩阵h在纵向方面复制m次。二者相除就是一阶差商。slopes = zeros(size(y)); % 设定一个全是0的向量。准备存放斜率数值。for r = 1:m slopes(r,:) = pchipslopes(x,y(r,:),del(r,:)); %调用函数见下。end% 对上述值x,y,和斜率计算分段三次Hermite插值v = pwch(x,y,slopes,h,del); v.dim = sizey;if nargin == 3 % if values are wanted instead, provide them v = ppval(v,xx);end% 以下是计算节点处的斜率的函数pchipslopes------------------------------------------function d = pchipslopes(x,y,del)%PCHIPSLOPES Derivative values for shape-preserving Piecewise Cubic Hermite Interpolation.% d = pchipslopes(x,y,del)计算一阶导数d(k)=P'(x(k)).% 特殊情况:n=2,此时使用线性插值. n = length(x); if n==2 d = repmat(del(1),size(y)); return end% 内点(interior points)处的斜率.% 假设第k个节点处的左右差商del(k-1)和del(k)符号同样,则设定d(k)等于二者的加权平均。% 假设第k个节点处的左右差商del(k-1)和del(k)符号相反,或者当中一个为0。则设定d(k)=0. d = zeros(size(y)); if isreal(del) %假设del是实数。 k = find(sign(del(1:n-2)).*sign(del(2:n-1)) > 0); %则把其左右差商同号的那个序号赋值给k. else k = find(~(del(1:n-2) == 0 & del(2:n-1) == 0)); end h = diff(x); hs = h(k)+h(k+1); w1 = (h(k)+hs)./(3*hs); w2 = (hs+h(k+1))./(3*hs); dmax = max(abs(del(k)), abs(del(k+1))); dmin = min(abs(del(k)), abs(del(k+1))); d(k+1) = dmin./conj(w1.*(del(k)./dmax) + w2.*(del(k+1)./dmax));%函数congj(a)返回数组a的每一个元素的共轭复数组成的数组。 % 区间端点处的斜率(end points).% Set d(1) and d(n) via non-centered, shape-preserving three-point formulae. d(1) = ((2*h(1)+h(2))*del(1) - h(1)*del(2))/(h(1)+h(2)); if isreal(d) && (sign(d(1)) ~= sign(del(1))) d(1) = 0; elseif (sign(del(1)) ~= sign(del(2))) && (abs(d(1)) > abs(3*del(1))) d(1) = 3*del(1); end d(n) = ((2*h(n-1)+h(n-2))*del(n-1) - h(n-1)*del(n-2))/(h(n-1)+h(n-2)); if isreal(d) && (sign(d(n)) ~= sign(del(n-1))) d(n) = 0; elseif (sign(del(n-1)) ~= sign(del(n-2))) && (abs(d(n)) > abs(3*del(n-1))) d(n) = 3*del(n-1); end


   


   

   

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空