三次样条插值自然边界条件
- 格式:doc
- 大小:60.50 KB
- 文档页数:3
三次样条插值函数MATLAB 编程实现三次样条插值函数为()()[)()[]1011,,,,n n n S x x x x S x S x x x x-⎧∈⎪=⎨⎪∈⎩ 利用三次埃尔米特插值函数表示三次样条插值函数,即()()()()())111111,,j j j j j j j j j j j S x y x y x m x m x x x x ααββ++++++⎡=+++∈⎣(0,1,,1j n =-)基函数满足()()()()()()21112111121121111212jj j j j j j j j j j j j j j j j j j jj j j j x x x x x x x x xx xx x x x x x xx xx x x x xx x x x x x xααββ++++++++++++⎛⎫⎛⎫--=+ ⎪⎪ ⎪⎪--⎝⎭⎝⎭⎛⎫⎛⎫--=+ ⎪⎪ ⎪⎪--⎝⎭⎝⎭⎛⎫-=-⎪ ⎪-⎝⎭⎛⎫-=-⎪ ⎪-⎝⎭由上式易得()()()()()()()()()()()()()()1331111331112211112211612612246246j j j j j j j j j j j j j j j j j j j j j j jj j j j j x x x x x x xx x x x x x x x x x x x x xx xx x x x x x x x x ααββ+++++++++++++++''=---+''=-+--+''=---+''=---则有()()()()()()()()()()()111111113333111111122221111661212242466j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j S x y x y x m x m x x x x x y x y x x x x x x x x x x x x x m x m x x x x x x x x x ααββ+++++++++++++++++++''''''''''=+++⎡⎤⎡⎤++⎢⎥⎢⎥=-+-+⎢⎥⎢⎥----⎣⎦⎣⎦⎡⎤++⎢⎥+-+-⎢⎥----⎣⎦)1,j j x x x +⎡⎤⎢⎥⎡∈⎣⎢⎥⎣⎦(0,1,,1j n =-)同理有()()()()()()()()()()()()()()()11111113333111111122221111661212242466j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j S x y x y x m x m x x x x x y x y x x x x x x x x x x x x x m x m x x x x x x x x x ααββ------------------''''''''''=+++⎡⎤⎡⎤++⎢⎥⎢⎥=-+-+⎢⎥⎢⎥----⎣⎦⎣⎦⎡⎤⎡++⎢⎥+-+-⎢⎥----⎣⎦⎣)1,j j x x x -⎤⎢⎥⎡∈⎣⎢⎥⎦(1,,j n =)根据样条函数二阶导数连续性,即()()100j j j j S x S x +''''+=-(1,,1j n =-)即()()()()()()()()()()()()()()()()111111332211111111113322111166426624j j jj j j j j j j jj j j j j j j j j j j j j j jj j j j j jj j j j j j j j x x y x x y x x x x m m x x x x x x x x x x y x x y x x x x m m x x x x x x x x ++++++++++--------------+++--------=+++----(1,,1j n =-)化简得()()()()()111111111111233j j j j j j j j j j j j j j j j j j jj j xx m x x m x x m x x x x y y y y x x x x +-+--+-++-+--+-+---=-+---(1,,1j n =-)可得线性方程组()()()()()()()()()()0121201023231213121221111110212110211032213221322122233333n n n n n n n n n n n n m m x x x x x x m x x x x x x m x x x x x x m m m x x x x y y y y x x x x x x x x y y y y x x x x y ------⨯+-+⨯⎛⎫ ⎪ ⎪ ⎪---⎛⎫⎪ ⎪--- ⎪ ⎪⎪ ⎪⎪ ⎪ ⎪--- ⎪⎝⎭ ⎪ ⎪ ⎪⎝⎭---+------+---=()()()121112112113n n n n n n n n n n n n n x x x x y y y x x x x ----------⨯⎛⎫⎪ ⎪ ⎪ ⎪⎪⎪ ⎪-- ⎪-+- ⎪--⎝⎭为了使样条插值问题有惟一解,我们在原有方程基础上增加两个边界条件。
用Matlab实现了3次样条曲线插值的算法。
边界条件取为自然边界条件,即:两个端点处的2阶导数等于0;共包含3各个函数文件,主函数所在文件(即使用的时候直接调用的函数)为spline3.m,另外两个函数文件是在splin3函数文件中被调用的自定义函数。
一个是GetParam.m,一个是GetM.m。
%GetParam.m文件的内容:%根据给定的离散点的横坐标所构成的向量,计算各个区间段的h值;function GetParam(Vx,Vy)global gh;global gf;global gu;global gr;global gd;global gff;global gM;%global gn;%n=length(Vx);%length()为向量Vx所含元素的个数;%n=legth(Vx);%gn=n;%n=gn;n=length(Vx);gh(1)=Vx(2)-Vx(1);gf(1)=(Vy(2)-Vy(1))/gh(1);for i=2:1:n-1%从区间0到区间n-1; gh(i)=Vx(i+1)-Vx(i);gf(i)=(Vy(i+1)-Vy(i))/gh(i);gu(i)=gh(i-1)/(gh(i-1)+gh(i));gr(i)=1-gu(i);gff(i)=(gf(i-1)-gf(i))/(Vx(i-1)-Vx(i+1)); gd(i)=6*gff(i);end%设置与边界条件有关的参数;gM(1)=0;%起点的2阶导数;gM(n)=0;%终点的2阶导数;end%GetM.m文件的内容:function GetM(Vx)global gh;global gf;global gu;global gr;global gd;global gff;global gM;%global gn;nn=length(Vx);%nn=gn;n=nn-2;b=zeros(n,1);A=zeros(n,n);A(1,1)=2;A(1,2)=gr(2);b(1)=gd(2)-gu(2)*gM(1);for i=2:1:n-1A(i,i)=2;A(i,i-1)=gu(i+1);A(i,i+1)=gr(i+1);b(i)=gd(i+1);endA(n,n-1)=gu(n);A(n,n)=2;b(n)=gd(nn-1)-gr(nn-1)*gM(nn); X=(inv(A))*b;for i=2:1:nn-1gM(i)=X(i-1);end%主函数文件spline3.m的内容:function result=spline3(x,Vx,Vy) global gh;global gf;global gu;global gr;global gd;global gff;global gM;%global gn;GetParam(Vx,Vy);GetM(Vx);%n=length(Vx);%n=gn;n=length(Vx);nn=length(x);y=zeros(1,nn);for j=1:1:nni=1;while(x(j)>Vx(i+1))endsn=i;t1=(Vx(sn+1)-x(j))^3/(6*gh(sn));t1=t1*gM(sn);t2=(x(j)-Vx(sn))^3/(6*gh(sn));t2=t2*gM(sn+1);t3=Vy(sn)-gM(i)*((gh(i))^2)/6;t3=t3*(Vx(sn+1)-x(j))/gh(sn);t4=Vy(sn+1)-gM(sn+1)*((gh(sn))^2)/6;t4=t4*(x(j)-Vx(sn))/gh(sn);y(j)=t1+t2+t3+t4;endresult=y;end函数调用的时候,result=spline3(x,Vx,Vy),x为代求点的横坐标向量,(Vx,Vy)为已知的点的坐标。
三次样条插值自然边界条件(一)三次样条插值自然边界条件引言•什么是样条插值?•为什么需要自然边界条件?样条插值基本概念•样条定义和性质•插值问题三次样条插值算法1.数据准备–输入数据的获取和整理2.线性方程组的建立–利用数据点和导数的关系建立线性方程组3.矩阵求解–解线性方程组获取样条插值函数的系数4.插值函数构建–使用线性方程组的解构建三次样条插值函数自然边界条件的引入•什么是自然边界条件?•为什么要使用自然边界条件?自然边界条件的应用1.边界条件的设置–左、右边界条件的定义2.线性方程组建立–利用自然边界条件建立线性方程组3.矩阵求解–解线性方程组获取带有自然边界条件的样条插值函数的系数4.插值函数构建–使用线性方程组的解构建带自然边界条件的三次样条插值函数结论•自然边界条件在三次样条插值中的应用优势•对比其他边界条件的选择参考文献参考文献1.DeBoor, C. (1978). A Practical Guide to Splines. NewYork: Springer-Verlag.2.王援胜. 数值计算方法(第2版). 中国科学技术大学出版社,2014.3.徐健, 曹洪欣, & 张平原. (2003). 数值分析与算法 C++语言实现. 清华大学出版社.4.Zhang, Q., & Jiao, L. (2001). Piecewise polynomialinterpolation with adaptive knot values. Journal ofcomputational and applied mathematics, , .。
三次样条插值多项式实验的目的及意义:为了取得理想结果:在不增加更多的插值条件下,能够求得一个插值多项式,既有良好的逼近效果,又有好的光滑性,引进三次样条插值 多项式。
如果已知函数y=f(x)在节点a=x0<x1<…<xn=b 处的函数值和导数值:()i i x f y =,i=0,1,2,…,n如果S(x)满足条件:1. S(x)是一个分段的三次多项式且()i i y x S =;2. S(x)在[a,b]具有二阶连续导数。
则称S(x)是三次样条插值函数。
S(x)的具体形式为:()()()()⎪⎪⎩⎪⎪⎨⎧∈∈∈=-]12,121,01,[,...............][,][,n n n x x x x s x x x x s x x x x s x s其中()x S i 在[]i i x x ,1-上是三次多项式()iiiiid x c x b x a x S +++=23由插值条件()ii y x S =,i=0,1,2,…,n ,得n+1个条件。
边界条件一:()()nn y x S y x S '',''00== 边界条件二:()()nn y x S y x S '''',''''00==数学公式:()()2211133[2]()[2()]()i i i i i i i i i i ih x x x x h x x x x H x y y h h ---+-----=++2211122()()()()i i i i i i i ix x x x x x x x m m h h -------+ 算法描述:Step1:输入未知数X 及(xi,yi),i=0,1,…,n ; Step2:计算步长H[i]; Step3:计算[][]()⎪⎪⎪⎩⎪⎪⎪⎨⎧+=-=+=-+++i i i i i i i ii i i i i x x f x x f u g u hh h ,,311111λλλStep4:根据边界条件,求解相应的方程得到m0,m1,…, mn Step5:判断X 属于[]i i x x ,1-,i=1,2,…,n 中的哪一个Step6:计算()x s y i i ≈Step7:输出y. 程序原代码如下: #include "stdio.h" #define N 5 void main() { int i,k; float X,s,y0,yn;float a[N][N+1],h[N],u[N],v[N],g[N],m[N],p[N],q[N],w[N];printf("please input X:"); //X 为未知数的大小scanf("%f",&X);printf("please input x:"); //输入x的大小for(i=0;i<N;i++)scanf("%f",&a[i][0]);printf("please input y:"); //输入y的大小for(i=0;i<N;i++)scanf("%f",&a[i][1]);for(i=1;i<N;i++)h[i]=a[i][0]-a[i-1][0]; //计算步长for(i=1;i<N;i++){v[i]=h[i+1]/(h[i]+h[i+1]);u[i]=1-v[i];g[i]=3*u[i]*(a[i+1][1]-a[i][1])/h[i+1]+3*v[i]*(a[i][1]-a[i-1][1])/h[i]; }printf("\t(1)已知边界条件1\n");printf("\t(2)已知边界条件2\n");printf("请选择边界条件序号:");scanf("%d",&k);if(k==1){printf("请输入y0和yn的一阶导:"); //输入边界条件一scanf("%f%f",&m[0],&m[N-1]);p[0]=0; //用追赶法求解m[N]q[0]=0;g[1]=g[1]-v[1]*m[0];g[N-2]=g[N-2]-u[N-2]*m[N-1];for(i=1;i<N;i++){w[i]=2-u[i]*p[i-1];p[i]=v[i]/w[i];q[i]=(g[i]-u[i]*q[i-1])/w[i];}m[N-2]=q[N-2];for(i=N-3;i>0;i--)m[i]=q[i]-p[i]*m[i+1];printf("输出m[i]的值:\n");for(i=0;i<N;i++)printf("%f\n",m[i]);for(i=1;i<N;i++) //计算最终结果if(X>a[i-1][0]&&X<a[i][0])s=(h[i]+2*(X-a[i-1][0]))*(X-a[i][0])*(X-a[i][0])*a[i-1][1]/(h[i]*h[i]*h[i]) +(h[i]-2*(X-a[i][0]))*(X-a[i-1][0])*(X-a[i-1][0])*a[i][1]/(h[i]*h[i]*h[i])+ (X-a[i-1][0])*(X-a[i][0])*(X-a[i][0])*m[i-1]/(h[i]*h[i])+(X-a[i-1][0])*(X-a[i-1][0])*(X-a[i][0])*m[i]/(h[i]*h[i]);printf("s(%f)=%f\n",X,s);}if(k==2){printf("请输入y0和yn的二阶导:"); //输入边界条件二scanf("%f%f",&y0,&yn);g[0]=3*(a[1][1]-a[0][1])/h[1]-h[1]*y0/2;g[N-1]=3*(a[N-1][1]-a[N-2][1])/h[N-1]+h[N-1]*yn/2;q[0]=g[0];u[0]=1;v[N-1]=1;w[0]=2;for(i=1;i<N;i++){w[i]=2-v[i]*u[i-1]/w[i-1];q[i]=g[i]-v[i]*q[i-1]/w[i-1];}m[N-1]=q[N-1]/w[N-1];for(i=N-2;i>=0;i--)m[i]=(q[i]-u[i]*m[i+1])/w[i];printf("输出m[i]的值:\n");for(i=0;i<N;i++)printf("%f\n",m[i]);for(i=1;i<N;i++)if(X>=a[i-1][0]&&X<=a[i][0])s=(h[i]+2*(X-a[i-1][0]))*(X-a[i][0])*(X-a[i][0])*a[i-1][1]/(h[i]*h[i]*h[i]) +(h[i]-2*(X-a[i][0]))*(X-a[i-1][0])*(X-a[i-1][0])*a[i][1]/(h[i]*h[i]*h[i])+ (X-a[i-1][0])*(X-a[i][0])*(X-a[i][0])*m[i-1]/(h[i]*h[i])+(X-a[i-1][0])*(X-a[i-1][0])*(X-a[i][0])*m[i]/(h[i]*h[i]);printf("s(%f)=%f\n",X,s);}}数值计算:已知y=f(x)的如下数值求三次样条插值函数S(x),满足条件1.s’(0)=0,s’(4)=482.s’’(0)=0,s’’(4)=24Please input X:2.5Please input x:0 1 2 3 4 Please input y:-8 -7 0 19 56(1)已知边界条件1(2)已知边界条件2请选择边界条件的序号:1请输入y0和yn的一阶导:0 48 0.0000003.00000012.00000027.00000048.000000s(2.500000)=7.625000press any key tocontinue请选择边界条件的序号:2请输入y0和yn的二阶导:0 24 -0.0000003.00000011.99999927.00000248.0000007.625000press any key tocontinue s(2.500000)=7.625000 对计算结果进行评价分析:()()443845h M x S x f ≤-三次样条插值函数与三次Hermite 插值函数相比,不仅光滑度有提高,而且要求求解时还不需要增加内节点处的导数值,因此比较实用。
三次样条插值1. 算法原理由于在许多实际问题中,要求函数的二阶导数连续,人们便提出了三次样条插值函数,三次样条插值函数是由分段三次函数拼接而成的,在连接点处二阶导数连续。
设S(x)在节点i x 处的二阶导数),1,0()(''n i M x S i i ,⋯⋯==,其中i M 为待定参数。
由S (x )是分段三次多项式可知,)(''x S 是分段线性函数,)(''x S 在子区间[]i i x x ,1-上可以表示为ii i ii i i i i i i i i i i i x x x M h x x M h x x M x x x x M x x x x x S ≤≤-+-=--+--=-------1111111,)(''其中1--=i i i x x h ,对S (x )两端积分两次得()ii i i i i i i i i i i x x x x x c x x b M h x x M h x x x S ≤≤-+-+-+-=-----111113),(6)(6)()(其中i b 和i c 为积分常数。
由插值条件()i i i i y x S y x S ==--)(,11得i i i i i i i i i i y h c M h y h b M h =+=+--6,62112由此解得i i i i i i i i i i h M h y c h M h y b /6,/62121⎪⎪⎭⎫ ⎝⎛-=⎪⎪⎭⎫ ⎝⎛-=--代入得:()()()ii ii i i i i i i i i i ii i i i x x x h x x M h y h x x M h y Mh x x Mh x x x S ≤≤-⎪⎪⎭⎫ ⎝⎛-+-⎪⎪⎭⎫ ⎝⎛-+-+-=------1121213113,6666 求导得:()()()i i i i i i i i i ii i ii x x x h M M h y y Mh x x Mh x x x S ≤≤---+-+--=-----1112112,622' 令i x x =得()x S 在i x 处的左导数 ()ii i i i i i i i i i i i i i h y y M h M h h M M h y y M h x S 11113662'------++=---+=又令1-=i x x 得()x S 在1-i x 处右导数 ()ii i i i i i i i i i i i i i i h y y M h M h h M M h y y M h x S 1111116362'------+-+--=---+-=, 从而有1111163)('++++++-+--=i ii i i i i h y y M h M h x S ,由()x S 在节点i x 处一阶导数的连续性知1,2,1),(')('-⋯⋯==+-n i x S x S i i ,,即1,2,16361111111-⋯⋯=---=+++-+++++-n i h y y h y y M h M h h M h ii i i i i i i i i i i i ,, 两端同乘16++i i h h 得)(62111111111ii i i i i i i i i i i i i i i i h y y h y y h h M h h h M M h h h -++++++-+---+=++++,记ii i i i i i i i h h h h h h μλμ-=+=+=+++1,111,1,,2,1],,,[66111111-⋯⋯==⎪⎪⎭⎫⎝⎛---+=+--+++n i x x x f h y y h y y h h d i i i i i i i i i i i i ,则关于i M 的方程组写成1,2,1,211-⋯⋯==+++-n i d M M M i i i i i ,λμ。
/****************函数说明*********************///pxpy为已知的数据点,xs为要插值的x坐标,最终会得到xs坐标下的y值using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace spline{class Program{staticvoid Main(string[] args){point[] points = new point[13];double[] px = { 64, 304, 544, 1035, 1502, 2061, 2540, 2939, 3498, 3897, 4456, 4696, 4936 }; double[]py={4.663,4.476,4.969,4.853,4.766,5.2415,4.795,4.7055,5.4565,5.5515,5.411,5.8385,6.7085} ;for (int i = 0; i< 13; i++){points[i] = new point();points[i].x =px[i];points[i].y = py[i];}point.DeSortX(points);double[] xs = {64, 304, 544, 1023, 1502, 1981, 2460, 2939, 3418, 3897, 4376, 4616, 4856}; splineInsertPoint(points, xs, 1);Console.ReadLine();}staticdouble[] splineInsertPoint(point[] points, double[] xs, int chf){int plength = points.Length;double[] h = newdouble[plength];double[] f = newdouble[plength];double[] l = newdouble[plength];double[] v = newdouble[plength];double[] g = newdouble[plength];//三转角法的待定一阶系数法。
三次样条插值 python 边界条件三次样条插值是一种常见的数据拟合方法,适用于任意分段连续函数的插值。
在 Python 中,可以使用 SciPy 库中的 interpolate 模块来进行三次样条插值。
不过,在进行样条插值时,需要指定边界条件,以确定插值的唯一性。
常见的边界条件包括自然边界条件、固定边界条件和周期边界条件。
本文将详细介绍三次样条插值在Python 中的边界条件设置方法。
一、自然边界条件自然边界条件是指插值函数的二阶导数在插值区间两端均为零。
在 SciPy 中,可以使用 interp1d 函数来实现自然边界条件的三次样条插值。
具体实现方法如下:```pythonfrom scipy.interpolate import interp1d# x和y为插值区间的数据点f = interp1d(x, y, kind='cubic',fill_value='extrapolate')```其中,kind 参数设置为 cubic 表示三次样条插值;fill_value 参数设置为 extrapolate 表示在插值区间之外的点依然可以进行插值。
二、固定边界条件固定边界条件是指插值函数在插值区间两端的值与一定值相等。
在 SciPy 中,可以使用 CubicSpline 类来实现固定边界条件的三次样条插值。
具体实现方法如下:```pythonfrom scipy.interpolate import CubicSpline# x和y为插值区间的数据点,left和right为左右端点的值f = CubicSpline(x, y, bc_type='clamped', left=left, right=right)```其中,bc_type 参数设置为 clamped 表示固定边界条件;left 和 right 分别为左右端点的值。
三、周期边界条件周期边界条件是指插值函数在插值区间两端的值相等。
例:已知一组数据点,编写一程序求解三次样条插值函数满足并针对下面一组具体实验数据求解,其中边界条件为.1)三次样条插值自然边界条件源程序:function s=spline3(x,y,dy1,dyn)%x为节点,y为节点函数值,dy1,dyn分别为x=0.25,0.53处的二阶导m=length(x);n=length(y);if m~=nerror('x or y输入有误')returnendh=zeros(1,n-1);h(n-1)=x(n)-x(n-1);for k=1:n-2h(k)=x(k+1)-x(k);v(k)=h(k+1)/(h(k+1)+h(k));u(k)=1-v(k);endg(1)=3*(y(2)-y(1))/h(1)-h(1)/2*dy1;g(n)=3*(y(n)-y(n-1))/h(n-1)+h(n-1)/2*dyn;for i=2:n-1g(i)=3*(u(i-1)*(y(i+1)-y(i))/h(i)+v(i-1)*(y(i)-y(i-1))/h(i-1)); endfor i=2:n-1;A(i,i-1)=v(i-1);A(i,i+1)=u(i-1);endA(n,n-1)=1;A(1,2)=1;A=A+2*eye(n);M=zhuigf(A,g); %调用函数,追赶法求Mfprintf('三次样条(三对角)插值的函数表达式\n');syms X;for k=1:n-1fprintf('S%d--%d:\n',k,k+1);s(k)=(h(k)+2*(X-x(k)))./h(k).^3.*(X-x(k+1)).^2.*y(k)...+(h(k)-2*(X-x(k+1)))./h(k).^3.*(X-x(k)).^2.*y(k+1)... +(X-x(k)).*(X-x(k+1)).^2./h(k).^2*M(k)+(X-x(k+1)).*... (X-x(k)).^2./h(k).^2*M(k+1);ends=s.';s=vpa(s,4);%画三次样条插值函数图像for i=1:n-1X=x(i):0.01:x(i+1);st=(h(i)+2*(X-x(i)))./(h(i)^3).*(X-x(i+1)).^2.*y(i)...+(h(i)-2.*(X-x(i+1)))./(h(i)^3).*(X-x(i)).^2.*y(i+1)...+(X-x(i)).*(X-x(i+1)).^2./h(i)^2*M(i)+(X-x(i+1)).*...(X-x(i)).^2./h(i)^2*M(i+1);plot(x,y,'o',X,st);hold onEndplot(x,y);grid on%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%调用的函数:%追赶法function M=zhuigf(A,g)n=length(A);L=eye(n);U=zeros(n);for i=1:n-1U(i,i+1)=A(i,i+1);endU(1,1)=A(1,1);for i=2:nL(i,i-1)=A(i,i-1)/U(i-1,i-1);U(i,i)=A(i,i)-L(i,i-1)*A(i-1,i);endY(1)=g(1);for i=2:nY(i)=g(i)-L(i,i-1)*Y(i-1);endM(n)=Y(n)/U(n,n);for i=n-1:-1:1M(i)=(Y(i)-A(i,i+1)*M(i+1))/U(i,i);end2)在命令窗口输入x,y,dy1,dyn,得到三次样条函数:>>x=[0.25,0.3,0.39,0.45,0.53];>>y=[0.5,0.5477,0.6245,0.6708,0.7280];>>dy1=0;>>dyn=0;>>s=spline3(x,y,dy1,dyn)运行结果:三次样条(三对角)插值的函数表达式S1--2:S2--3:S3--4:S4--5:.5000*(-3600.+.1600e5*X)*(X-.3000)^2+.5477*(5200.-.1600e5*X)*(X-.2500)^2+394.8*(X-.2500)*(X-.3000)^2+355.2*(X-.3000)*(X-.2500)^2.5477*(-699.6+2743.*X)*(X-.3900)^2+.6245*(1193.-2743.*X)*(X-.3000)^2+109.6*(X-.300 0)*(X-.3900)^2+96.77*(X-.3900)*(X-.3000)^2.6245*(-3333.+9259.*X)*(X-.4500)^2+.6708*(4444.-9259.*X)*(X-.3900)^2+217.7*(X-.39 00)*(X-.4500)^2+207.6*(X-.4500)*(X-.3900)^2.6708*(-1602.+3906.*X)*(X-.5300)^2+.7280*(2227.-3906.*X)*(X-.4500)^2+116.8*(X-.45 00)*(X-.5300)^2+109.2*(X-.5300)*(X-.4500)^2如将三次样条函数加以整理,可用如下程序:s=collect(s);则输出结果为:s=.4595000000000-13.200*X^3+9.9000000*X^2-1.48800000000*X.37459306800000-4.2924*X^3+3.66332200*X^2-.137976090000*X.5180681700000-3.3917*X^3+3.90576600*X^2-.733130370000*X-.408614400000e-1+2.5768*X^3-4.03188800*X^2+2.868770320000*X。
精品资料三次样条插值的M a t l a b实现(自然边界和第一边界条件)........................................(第一边界条件)源代码:function y=yt1(x0,y0,f_0,f_n,x) _____________(1)%第一类边界条件下三次样条插值;%xi 所求点;%yi 所求点函数值;%x 已知插值点;%y 已知插值点函数值;%f_0左端点一次导数值;%f_n右端点一次导数值;n = length(x0);z = length(y0);h = zeros(n-1,1);k=zeros(n-2,1);l=zeros(n-2,1);S=2*eye(n);for i=1:n-1h(i)= x0(i+1)-x0(i);endfor i=1:n-2k(i)= h(i+1)/(h(i+1)+h(i)); l(i)= 1-k(i);end%对于第一种边界条件:k = [1;k];_______________________(2)l = [l;1];_______________________(3)%构建系数矩阵S:for i = 1:n-1S(i,i+1) = k(i);S(i+1,i) = l(i);end%建立均差表:F=zeros(n-1,2);for i = 1:n-1F(i,1) = (y0(i+1)-y0(i))/(x0(i+1)-x0(i)); endD = zeros(n-2,1);for i = 1:n-2F(i,2) = (F(i+1,1)-F(i,1))/(x0(i+2)-x0(i)); D(i,1) = 6 * F(i,2);end%构建函数D:d0 = 6*(F(1,2)-f_0)/h(1);___________(4)dn = 6*(f_n-F(n-1,2))/h(n-1);___________(5)D = [d0;D;dn];______________(6)m= S\D;%寻找x所在位置,并求出对应插值:for i = 1:length(x)for j = 1:n-1if (x(i)<=x0(j+1))&(x(i)>=x0(j)) y(i) =( m(j)*(x0(j+1)-x(i))^3)/(6*h(j))+...(m(j+1)*(x(i)-x0(j))^3)/(6*h(j))+...(y0(j)-(m(j)*h(j)^2)/6)*(x0(j+1)-x(i))/h(j)+... (y0(j+1)-(m(j+1)*h(j)^2)/6)*(x(i)-x0(j))/h(j) ; break;else continue;endendend(2)(自然边界条件)源代码:仅仅需要对上面部分标注的位置做如下修改: __(1):function y=yt2(x0,y0,x)__(2):k=[0;k]__(3):l=[l;0]__(4)+(5):删除—(6):D=[0:D:0]。
例:已知一组数据点,编写一程序求解三次样条插值函数满足
并针对下面一组具体实验数据
求解,其中边界条件为.
1)三次样条插值自然边界条件源程序:
function s=spline3(x,y,dy1,dyn)
%x为节点,y为节点函数值,dy1,dyn分别为x=0.25,0.53处的二阶导
m=length(x);n=length(y);
if m~=n
error('x or y输入有误')
return
end
h=zeros(1,n-1);
h(n-1)=x(n)-x(n-1);
for k=1:n-2
h(k)=x(k+1)-x(k);
v(k)=h(k+1)/(h(k+1)+h(k));
u(k)=1-v(k);
end
g(1)=3*(y(2)-y(1))/h(1)-h(1)/2*dy1;
g(n)=3*(y(n)-y(n-1))/h(n-1)+h(n-1)/2*dyn;
for i=2:n-1
g(i)=3*(u(i-1)*(y(i+1)-y(i))/h(i)+v(i-1)*(y(i)-y(i-1))/h(i-1)); end
for i=2:n-1;
A(i,i-1)=v(i-1);
A(i,i+1)=u(i-1);
end
A(n,n-1)=1;
A(1,2)=1;
A=A+2*eye(n);
M=zhuigf(A,g); %调用函数,追赶法求M
fprintf('三次样条(三对角)插值的函数表达式\n');
syms X;
for k=1:n-1
fprintf('S%d--%d:\n',k,k+1);
s(k)=(h(k)+2*(X-x(k)))./h(k).^3.*(X-x(k+1)).^2.*y(k)...
+(h(k)-2*(X-x(k+1)))./h(k).^3.*(X-x(k)).^2.*y(k+1)... +(X-x(k)).*(X-x(k+1)).^2./h(k).^2*M(k)+(X-x(k+1)).*... (X-x(k)).^2./h(k).^2*M(k+1);
end
s=s.';
s=vpa(s,4);
%画三次样条插值函数图像
for i=1:n-1
X=x(i):0.01:x(i+1);
st=(h(i)+2*(X-x(i)))./(h(i)^3).*(X-x(i+1)).^2.*y(i)...
+(h(i)-2.*(X-x(i+1)))./(h(i)^3).*(X-x(i)).^2.*y(i+1)...
+(X-x(i)).*(X-x(i+1)).^2./h(i)^2*M(i)+(X-x(i+1)).*...
(X-x(i)).^2./h(i)^2*M(i+1);
plot(x,y,'o',X,st);
hold on
End
plot(x,y);
grid on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%调用的函数:
%追赶法
function M=zhuigf(A,g)
n=length(A);
L=eye(n);
U=zeros(n);
for i=1:n-1
U(i,i+1)=A(i,i+1);
end
U(1,1)=A(1,1);
for i=2:n
L(i,i-1)=A(i,i-1)/U(i-1,i-1);
U(i,i)=A(i,i)-L(i,i-1)*A(i-1,i);
end
Y(1)=g(1);
for i=2:n
Y(i)=g(i)-L(i,i-1)*Y(i-1);
end
M(n)=Y(n)/U(n,n);
for i=n-1:-1:1
M(i)=(Y(i)-A(i,i+1)*M(i+1))/U(i,i);
end
2)在命令窗口输入x,y,dy1,dyn,得到三次样条函数:
>>x=[0.25,0.3,0.39,0.45,0.53];
>>y=[0.5,0.5477,0.6245,0.6708,0.7280];
>>dy1=0;
>>dyn=0;
>>s=spline3(x,y,dy1,dyn)
运行结果:
三次样条(三对角)插值的函数表达式
S1--2:
S2--3:
S3--4:
S4--5:
.5000*(-3600.+.1600e5*X)*(X-.3000)^2+.5477*(5200.-.1600e5*X)*(X-.2500)^2+394.8*(X-.2500)*(X-.3000)^2+355.2*(X-.3000)*(X-.2500)^2
.5477*(-699.6+2743.*X)*(X-.3900)^2+.6245*(1193.-2743.*X)*(X-.3000)^2+109.6*(X-.300 0)*(X-.3900)^2+96.77*(X-.3900)*(X-.3000)^2
.6245*(-3333.+9259.*X)*(X-.4500)^2+.6708*(4444.-9259.*X)*(X-.3900)^2+217.7*(X-.39 00)*(X-.4500)^2+207.6*(X-.4500)*(X-.3900)^2
.6708*(-1602.+3906.*X)*(X-.5300)^2+.7280*(2227.-3906.*X)*(X-.4500)^2+116.8*(X-.45 00)*(X-.5300)^2+109.2*(X-.5300)*(X-.4500)^2
如将三次样条函数加以整理,可用如下程序:
s=collect(s);
则输出结果为:
s=
.4595000000000-13.200*X^3+9.9000000*X^2-1.48800000000*X
.37459306800000-4.2924*X^3+3.66332200*X^2-.137976090000*X
.5180681700000-3.3917*X^3+3.90576600*X^2-.733130370000*X
-.408614400000e-1+2.5768*X^3-4.03188800*X^2+2.868770320000*X。