试求三次样条插值S(X)
- 格式:doc
- 大小:22.00 KB
- 文档页数:4
数值法实验报告专业班级:信息与计算科学121 姓名:金辉 学号:20120142801)实验目的本次实验的目的是熟练《数值分析》第二章“插值法”的相关内容,掌握三种插值方法:牛顿多项式插值,三次样条插值,拉格朗日插值,并比较三种插值方法的优劣。
本次试验要求编写牛顿多项式插值,三次样条插值,拉格朗日插值的程序编码,并在MATLAB 软件中去实现。
2)实验题目 实验一:试用44据进行插值。
用图给出{(x i ,y i ),x i =0.2+0.08i ,i=0,1, 11, 10},P 4(x )及S (x )。
实验二:在区间[-1,1]上分别取10,20n =用两组等距节点对龙格函数21()125f x x =+作多项式插值及三次样条插值,对每个n 值,分别画出插值函数即()f x 的图形。
实验三:可以得到平方根函数的近似,在区间[0,64]上作图。
(1)用这9各点作8次多项式插值L 8(x).(2)用三次样条(自然边界条件)程序求S (x )。
从结果看在[0,64]上,那个插值更精确;在区间[0,1]上,两种哪个更精确?3)实验原理与理论基础《数值分析》第二章“插值法”的相关内容,包括:牛顿多项式插值,三次样条插值,拉格朗日4)实验内容 实验一:试用44据进行插值。
用图给出{(xi ,yi),xi=0.2+0.08i,i=0,1, 11, 10},P4(x)及S(x)。
(1)首先我们先求牛顿插值多项式,此处要用4次牛顿插值多项式处理数据。
已知n次牛顿插值多项式如下:P n =f(x)+f[x,x1](x-x)+ f[x,x1,x2](x-x) (x-x1)+···+f[x0,x1, (x)n](x-x) ···(x-xn-1)我们要知道牛顿插值多项式的系数,即均差表中得部分均差。
在MATLAB的Editor中输入程序代码,计算牛顿插值中多项式系数的程序如下:function varargout=newtonliu(varargin)clear,clcx=[0.2 0.4 0.6 0.8 1.0];fx=[0.98 0.92 0.81 0.64 0.38];newtonchzh(x,fx);function newtonchzh(x,fx)%由此函数可得差分表n=length(x);fprintf('*****************差分表*****************************\n');FF=ones(n,n);FF(:,1)=fx';for i=2:nfor j=i:nFF(j,i)=(FF(j,i-1)-FF(j-1,i-1))/(x(j)-x(j-i+1));endendfor i=1:nfprintf('%4.2f',x(i));for j=1:ifprintf('%10.5f',FF(i,j));endfprintf('\n'); end由所以有四次插值牛顿多项式为:P 4(x )=0.98-0.3(x-0.2)-0.62500 (x-0.2)(x-0.4) -0.20833(x-0.2)(x-0.4)(x-0.6)-0.52083 (x-0.2)(x-0.4)(x-0.6)(x-0.8)(2)接下来我们求三次样条插值函数。
问题1:20.给定数据如下表:试求三次样条插值S(x),并满足条件 (1)S`(0.25)=1.0000,S`(0.53)=0.6868; (2)S ’’(0.25)=S ’’(0.53)=0。
分析:本问题是已知五个点,由这五个点求一三次样条插值函数。
边界条件有两种,(1)是已知一阶倒数,(2)是已知自然边界条件。
对于第一种边界(已知边界的一阶倒数值),可写出下面的矩阵方程。
⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡432104321034322110d M M M M M 200020000020022d d d d λμμλμλμλ其中μj =j1-j 1-j h h h +,λi=j1-j j h h h +,dj=6f[x j-1,x j ,x j+1], μn =1,λ0=1对于第一种边界条件d 0=0h 6(f[x 0,x 1]-f 0`),d n =1-n h 6(f`n-f `[x n-1,x n ]) 解:由matlab 计算得:由此得矩阵形式的线性方程组为:⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎣⎡=⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎣⎡ 2.1150-2.4286-3.2667-4.3143-5.5200-M M M M M 25714.00001204286.000004000.026000.0006429.023571.0001243210解得 M 0=-2.0286;M 1=-1.4627;M 2= -1.0333; M 3= -0.8058; M 4=-0.6546S(x)=⎪⎪⎩⎪⎪⎨⎧∈-+-+-∈-+-+-∈-+-+-∈-+-+-]53.0,45.0[x 5.40x 9.1087x 35.03956.8.450-x 1.3637-x .5301.67881- ]45.0,39.0[x 9.30x 11.188x 54.010.418793.0-x 2.2384-x .450(2.87040-]39.0,30.0[x 03.0x 6.9544x 9.30 6.107503.0-x 1.9136-x .3902.708779-]30.0,25.0[x 5.20x 10.9662x 0.3010.01695.20-x 4.8758-x .3006.76209-33333333),()()()(),()()()),()()()(),()()()(Matlab 程序代码如下:function tgsanci(n,s,t) %n代表元素数,s,t代表端点的一阶导。
三次样条插值分段线性插值的优点:计算简单、稳定性好、收敛性有保证且易在计算机上实现缺点:它只能保证各小段曲线在连接点的连续性,却无法保证整条曲线的光滑性,这就不能满足某些工程技术的要求。
三次Hermit 插值优点:有较好的光滑性,缺点:要求节点的一阶导数已知。
从20世纪60年代开始,首先由于航空、造船等工程设计的需要而发展起来所谓样条(Spline)插值方法,既保留了分段低次插值多项式的各种优点,又提高了插值函数的光滑性。
今天,样条插值方法已成为数值逼近的一个极其重要的分支,在许多领域里得到越来越多广泛应用。
我们介绍应用最广的具二阶连续导数的三次样条插值函数。
一、三次样条插值函数的定义:给定区间],[b a 上的个节点b x x x a n =<<<= 10和这些点上的函数值),,1,0()(n i y x f i i == 若)(x S 满足: (1)),,2,1,0()(n i y x S i i ==;(2)在每个小区间],[b a 上至多是一个三次多项式; (3))(),(),(x S x S x S '''在],[b a 上连续。
则称)(x S 为函数)(x f 关于节点的n x x x ,,,10 三次样条插值函数。
二、边界问题的提出与类型单靠一个函数表是不能完全构造出一个三次样条插值函数。
我们分析一下其条件个数,条件(2)三次样条插值函数)(x S 是一个分段三次多项式,若用)(x S i 表示它在第i 个子区间],[1i i x x -上的表达式,则)(x S i 形如],[,)(1332210i i i i i i i x x x x a x a x a a x S -∈+++=其中有四个待定系数)3,2,1,0(=j a ij ,子区间共有n 个,所以)(x S 共有n 4个待定系数。
由条件(3))(),(),(x S x S x S '''在],[b a 上连续,即它们在各个子区间上的连接点110,,,-n x x x 上连续即可,共有)1(4-n 个条件,即⎪⎪⎩⎪⎪⎨⎧==-=+''=-''-=+'=-'-=+=-),2,1,0()()1,,2,1)(0()0()1,,2,1)(0()0()1,,2,1)(0()0(n i y x S n i x S x S n i x S x S n i x S x S i i i i i i i i 共有241)1(3-=++-n n n 个条件,未知量的个数是n 4个。
/* 三次样条插值计算算法*/#include "math.h "#include "stdio.h "#include "stdlib.h "/*N:已知节点数N+1R:欲求插值点数R+1x,y为给定函数f(x)的节点值{x(i)} (x(i) <x(i+1)) ,以及相应的函数值{f(i)} 0 <=i <=NP0=f(x0)的二阶导数;Pn=f(xn)的二阶导数u:存插值点{u(i)} 0 <=i <=R求得的结果s(ui)放入s[R+1] 0 <=i <=R返回0表示成功,1表示失败*/int SPL(int N,int R,double x[],double y[],double P0,double Pn,double u[],double s[]){/*声明局部变量*/double *h; /*存放步长:{hi} 0 <=i <=N-1 */double *a; /*存放系数矩阵{ai} 1 <=i <=N ;分量0没有利用*/ double *c; /*先存放系数矩阵{ci} 后存放{Bi} 0 <=i <=N-1 */double *g; /*先存放方程组右端项{gi} 后存放求解中间结果{yi} 0 <=i <=N */double *af; /*存放系数矩阵{a(f)i} 1 <=i <=N ;*/double *ba; /*存放中间结果0 <=i <=N-1*/double *m; /*存放方程组的解{m(i)} 0 <=i <=N ;*/int i,k;double p1,p2,p3,p4;/*分配空间*/if(!(h=(double*)malloc(N*sizeof(double)))) exit(1);if(!(a=(double*)malloc((N+1)*sizeof(double)))) exit(1);if(!(c=(double*)malloc(N*sizeof(double)))) exit(1);if(!(g=(double*)malloc((N+1)*sizeof(double)))) exit(1);if(!(af=(double*)malloc((N+1)*sizeof(double)))) exit(1);if(!(ba=(double*)malloc((N)*sizeof(double)))) exit(1);if(!(m=(double*)malloc((N+1)*sizeof(double)))) exit(1);/*第一步:计算方程组的系数*/for(k=0;k <N;k++)h[k]=x[k+1]-x[k];for(k=1;k <N;k++)a[k]=h[k]/(h[k]+h[k-1]);for(k=1;k <N;k++)c[k]=1-a[k];for(k=1;k <N;k++)g[k]=3*(c[k]*(y[k+1]-y[k])/h[k]+a[k]*(y[k]-y[k-1])/h[k-1]); c[0]=a[N]=1;g[0]=3*(y[1]-y[0])/h[0]-P0*h[0]/2;g[N]=3*(y[N]-y[N-1])/h[N-1]+Pn*h[N-1]/2;/*第二步:用追赶法解方程组求{m(i)} */ba[0]=c[0]/2;g[0]=g[0]/2;for(i=1;i <N;i++){af[i]=2-a[i]*ba[i-1];g[i]=(g[i]-a[i]*g[i-1])/af[i];ba[i]=c[i]/af[i];}af[N]=2-a[N]*ba[N-1];g[N]=(g[N]-a[N]*g[N-1])/af[N];m[N]=g[N]; /*P110 公式:6.32*/ for(i=N-1;i> =0;i--)m[i]=g[i]-ba[i]*m[i+1];/*第三步:求值*/for(i=0;i <=R;i++){/*判断u(i)属于哪一个子区间,即确定k */if(u[i] <x[0] || u[i]> x[N]){/*释放空间*/free(h);free(a);free(c);free(g);free(af);free(ba);free(m);return 1;}k=0;while(u[i]> x[k+1])k++;//p1=(h[k]+2*(u[i]-x[k])*pow((u[i]-x[k+1]),2)*y[k])/pow(h[k],3); //p2=(h[k]-2*(u[i]-x[k+1])*pow((u[i]-x[k]),2)*y[k+1])/pow(h[k],3);p1=(h[k]+2*(u[i]-x[k]))*pow((u[i]-x[k+1]),2)*y[k]/pow(h[k],3);p2=(h[k]-2*(u[i]-x[k+1]))*pow((u[i]-x[k]),2)*y[k+1]/pow(h[k],3); p3=(u[i]-x[k])*pow((u[i]-x[k+1]),2)*m[k]/pow(h[k],2);p4=(u[i]-x[k+1])*pow((u[i]-x[k]),2)*m[k+1]/pow(h[k],2);s[i]=p1+p2+p3+p4;}/*释放空间*/free(h);free(a);free(c);free(g);free(af);free(ba);free(m);return 0;}void main(){int N,R;double *x,*y,*u,*s;double P0,Pn;int i;/*验证算法:*/N=7;R=6;/*分配空间*/if(!(x=(double*)malloc((N+1)*sizeof(double)))){printf( "malloc error!\n ");exit(1);}if(!(y=(double*)malloc((N+1)*sizeof(double)))){printf( "malloc error!\n ");exit(1);}if(!(u=(double*)malloc((R+1)*sizeof(double)))){printf( "malloc error!\n ");exit(1);}if(!(s=(double*)malloc((R+1)*sizeof(double)))){printf( "malloc error!\n ");exit(1);}x[0]=0.5;x[1]=0.7;x[2]=0.9;x[3]=1.1;x[4]=1.3;x[5]=1.5;x[6]=1.7;x[7]=1.9;y[0]=0.4794;y[1]=0.6442;y[2]=0.7833;y[3]=0.8912;y[4]=0.9636;y[5]=0.9975;y[6]=0.9917;y[7]=0.9 463;u[0]=0.6;u[1]=0.8;u[2]=1.0;u[3]=1.2;u[4]=1.4;u[5]=1.6;u[6]=1.8;P0=-0.4794;Pn=-0.9463;if(!SPL( N, R, x, y, P0, Pn, u, s)){/*打印结果*/printf( "\nx= ");for(i=0;i <=N;i++)printf( "%8.1f ",x[i]);printf( "\ny= ");for(i=0;i <=N;i++)printf( "%8.4f ",y[i]);printf( "\n\nu= ");for(i=0;i <=R;i++)printf( "%9.2f ",u[i]);printf( "\ns= ");for(i=0;i <=R;i++)printf( "%9.5f ",s[i]);printf( "\nsin= ");for(i=0;i <=R;i++)printf( "%9.5f ",sin(u[i]));}/*释放空间*/free(x);free(y);free(u);free(s);}/* 测试数据来自课本55页例5 《数值分析》清华大学出版社第四版*/ //输入327.7 4.128 4.329 4.130 3.013.0 -4.0//输出输出三次样条插值函数:1: [27.7 , 28]13.07*(x - 28)^3 + 0.22*(x - 27.7)^3+ 14.84*(28 - x) + 14.31*(x - 27.7)2: [28 , 29]0.066*(29 - x)^3 + 0.1383*(x - 28)^3+ 4.234*(29 - x) + 3.962*(x - 28)3: [29 , 30]0.1383*(30 - x)^3 - 1.519*(x - 29)^3+ 3.962*(30 - x) + 4.519*(x - 29)//三次样条插值函数#include<iostream>#include<iomanip>using namespace std;const int MAX = 50;float x[MAX], y[MAX], h[MAX];float c[MAX], a[MAX], fxym[MAX];float f(int x1, int x2, int x3){float a = (y[x3] - y[x2]) / (x[x3] - x[x2]);float b = (y[x2] - y[x1]) / (x[x2] - x[x1]);return (a - b)/(x[x3] - x[x1]);} //求差分void cal_m(int n){ //用追赶法求解出弯矩向量M……float B[MAX];B[0] = c[0] / 2;for(int i = 1; i < n; i++)B[i] = c[i] / (2 - a[i]*B[i-1]);fxym[0] = fxym[0] / 2;for(i = 1; i <= n; i++)fxym[i] = (fxym[i] - a[i]*fxym[i-1]) / (2 - a[i]*B[i-1]);for(i = n-1; i >= 0; i--)fxym[i] = fxym[i] - B[i]*fxym[i+1];}void printout(int n);int main(){int n,i; char ch;do{cout<<"Please put in the number of the dots:";cin>>n;for(i = 0; i <= n; i++){cout<<"Please put in X"<<i<<':';cin>>x[i]; //cout<<endl;cout<<"Please put in Y"<<i<<':';cin>>y[i]; //cout<<endl;}for(i = 0; i < n; i++) //求步长h[i] = x[i+1] - x[i];cout<<"Please 输入边界条件\n 1: 已知两端的一阶导数\n 2:两端的二阶导数已知\n 默认:自然边界条件\n";int t;float f0, f1;cin>>t;switch(t){case 1:cout<<"Please put in Y0\' Y"<<n<<"\'\n";cin>>f0>>f1;c[0] = 1; a[n] = 1;fxym[0] = 6*((y[1] - y[0]) / (x[1] - x[0]) - f0) / h[0];fxym[n] = 6*(f1 - (y[n] - y[n-1]) / (x[n] - x[n-1])) / h[n-1];break;case 2:cout<<"Please put in Y0\" Y"<<n<<"\"\n";cin>>f0>>f1;c[0] = a[n] = 0;fxym[0] = 2*f0; fxym[n] = 2*f1;break;default:cout<<"不可用\n";//待定};//switchfor(i = 1; i < n; i++)fxym[i] = 6 * f(i-1, i, i+1);for(i = 1; i < n; i++){a[i] = h[i-1] / (h[i] + h[i-1]);c[i] = 1 - a[i];}a[n] = h[n-1] / (h[n-1] + h[n]);cal_m(n);cout<<"\n输出三次样条插值函数:\n";printout(n);cout<<"Do you to have anther try ? y/n :";cin>>ch;}while(ch == 'y' || ch == 'Y');return 0;}void printout(int n){cout<<setprecision(6);for(int i = 0; i < n; i++){cout<<i+1<<": ["<<x[i]<<" , "<<x[i+1]<<"]\n"<<"\t";/*cout<<fxym[i]/(6*h[i])<<" * ("<<x[i+1]<<" - x)^3 + "<<<<" * (x - "<<x[i]<<")^3 + "<<(y[i] - fxym[i]*h[i]*h[i]/6)/h[i]<<" * ("<<x[i+1]<<" - x) + "<<(y[i+1] - fxym[i+1]*h[i]*h[i]/6)/h[i]<<"(x - "<<x[i]<<")\n";cout<<endl;*/float t = fxym[i]/(6*h[i]);if(t > 0)cout<<t<<"*("<<x[i+1]<<" - x)^3";else cout<<-t<<"*(x - "<<x[i+1]<<")^3";t = fxym[i+1]/(6*h[i]);if(t > 0)cout<<" + "<<t<<"*(x - "<<x[i]<<")^3";else cout<<" - "<<-t<<"*(x - "<<x[i]<<")^3";cout<<"\n\t";t = (y[i] - fxym[i]*h[i]*h[i]/6)/h[i];if(t > 0)cout<<"+ "<<t<<"*("<<x[i+1]<<" - x)";else cout<<"- "<<-t<<"*("<<x[i+1]<<" - x)";t = (y[i+1] - fxym[i+1]*h[i]*h[i]/6)/h[i];if(t > 0)cout<<" + "<<t<<"*(x - "<<x[i]<<")";else cout<<" - "<<-t<<"*(x - "<<x[i]<<")";cout<<endl<<endl;}cout<<endl;}。
三次样条插值的求解摘要:分段低次插值虽然解决了高次插值的振荡现象和数值不稳定现象,使得插值多项式具有一致收敛性,保证了插值函数整体的连续性,但在函数插值节点处不能很好地保证光滑性要求,这在某些要求光滑性的工程应用中是不能接受的。
如飞机的机翼一般要求使用流线形设计,以减少空气阻力,还有船体放样等的型值线,往往要求有二阶光滑度(即有二阶连续导数)。
因此,在分段插值的基础上,引进了一种新的插值方法,在保证原方法的收敛性和稳定性的同时,又使得函数具有较高的光滑性的样条插值。
关键字:三转角方程 三弯矩阵方程0. 引言1,三次样条函数定义1:若函数2()[,]S x a b C ∈,且在每个小区间上1,j j x x +⎡⎤⎦⎣上是三次多项式,其中01n a x x x b ⋯=<<<= 是给定节点,则称()s x 是节点01,,,n x x x ⋯上的三次样条函数。
若节点j x 上 给定函数值()j j y f x =(0,1,)j n ⋯= ,且()j j s x y = (0,1,)j n ⋯= (1.1)成立,则称 ()s x 为三次样条差值函数。
从定义知,要求出()s x ,在每个应小区间1[,]j j x x + 上确定4个待定系数,共有 n 个小区间,故应确定4n 个参数,根据()s x 在[,]a b 上二阶导数连续,在节点()1,2,3,,1j x j n ⋯=-处应满足连续性条件(0)(0),j j s x s x -=+ ''(0)(0),j j s x s x -=+''''(0)(0)j j s x s x -=+ (1.2) 共有 3n-3个条件,再加上()s x 满足插值条件(1.1),共有4n-2个条件,因此还需要2个条件才能确定()s x 。
通常可在区间[,]a b 端点0,n a x b x ==上各加一个条件(称边界条件),边界条件可根据实际的问题要求给定。
例1 设)(x f 为定义在[0,3]上的函数,有下列函数值表:且2.0)('0=x f ,1)('3-=x f ,试求区间[0,3]上满足上述条件的三次样条插值函数)(x s本算法求解出的三次样条插值函数将写成三弯矩方程的形式:)()6()()6()(6)(6)(211123131j j jj j j jj j j j jj j jj x x h h M y x x h h M y x x h M x x h M x s --+--+-+-=+++++其中,方程中的系数jj h M 6,jj h M 61+,jj j j h h M y )6(2-,jjj j h h M y )6(211++-将由Matlab代码中的变量Coefs_1、Coefs_2、Coefs_3以及Coefs_4的值求出。
以下为Matlab 代码:%=============================% 本段代码解决作业题的例1%============================= clear all clc% 自变量x 与因变量y ,两个边界条件的取值 IndVar = [0, 1, 2, 3]; DepVar = [0, 0.5, 2, 1.5];LeftBoun = 0.2; RightBoun = -1;% 区间长度向量,其各元素为自变量各段的长度 h = zeros(1, length(IndVar) - 1); for i = 1 : length(IndVar) - 1h(i) = IndVar(i + 1) - IndVar(i); end% 为向量μ赋值mu = zeros(1, length(h));for i = 1 : length(mu) - 1mu(i) = h(i) / (h(i) + h(i + 1));endmu(i + 1) = 1;% 为向量λ赋值lambda = zeros(1, length(h));lambda(1) = 1;for i = 2 : length(lambda)lambda(i) = h(i) / (h(i - 1) + h(i));end% 为向量d赋值d = zeros(1, length(h) + 1);d(1) = 6 * ( (DepV ar(2) - DepVar(1) ) / ( IndVar(2) - IndVar(1) ) - LeftBoun) / h(1);for i = 2 : length(h)a = ( DepVar(i) - DepVar(i - 1) ) / ( IndVar(i) - IndVar(i - 1) );b = ( DepVar(i + 1) - DepVar(i) ) / ( IndVar(i + 1) - IndVar(i) );c = (b - a) / ( IndVar(i + 1) - IndVar(i - 1) );d(i) = 6 * c;endd(i + 1) = 6 *( RightBoun - ( DepVar(i + 1) - DepVar(i) ) / ( IndVar(i + 1) - IndVar(i) ) ) / h(i);% 为矩阵A赋值% 将主对角线上的元素全部置为2A = zeros( length(d), length(d) );for i = 1 : length(d)A(i, i) = 2;end% 将向量λ的各元素赋给主对角线右侧第一条对角线for i = 1 : length(d) - 1A(i, i + 1) = lambda(i);end% 将向量d的各元素赋给主对角线左侧第一条对角线for i = 1 : length(d) - 1A(i + 1, i) = mu(i);end% 求解向量MM =A \ d';% 求解每一段曲线的函数表达式for i = 1 : length(h)Coefs_1 = M(i) / (6 * h(i));Part_1 = conv( Coefs_1, ...conv( [-1, IndVar(i + 1)], ...conv( [-1, IndVar(i + 1)], [-1, IndVar(i + 1)] ) ) );S_1 = polyval (Part_1, [IndVar(i) : 0.01 : IndVar(i + 1)]);Coefs_2 = M(i + 1)/(6 * h(i));Part_2 = conv( Coefs_2, ...conv( [1, -IndVar(i)], ...conv( [1, -IndVar(i)], [1, -IndVar(i)] ) ) );S_2 = polyval (Part_2, [IndVar(i) : 0.01 : IndVar(i + 1)]);Coefs_3 = (DepVar(i) - M(i) * h(i)^2 / 6) / h(i);Part_3 = conv(Coefs_3, [-1, IndVar(i + 1)]);S_3 = polyval (Part_3, [IndVar(i) : 0.01 : IndVar(i + 1)]);Coefs_4 = (DepVar(i + 1) - M(i + 1) * h(i)^2 / 6) / h(i);Part_4 = conv(Coefs_4, [1, -IndVar(i)]);S_4 = polyval (Part_4, [IndVar(i) : 0.01 : IndVar(i + 1)]);S = S_1 + S_2 + S_3 + S_4;plot ([IndVar(i) : 0.01 : IndVar(i + 1)], S, 'LineWidth', 1.25)% 在样条插值曲线的相应位置标注该段曲线的函数表达式text(i - 1, polyval(Part_1, 3), ...['\itS', num2str(i), '(x)=', num2str(Coefs_1), '(', num2str( IndVar(i + 1) ), '-x)^{3}+', ...num2str(Coefs_2), '(x-', num2str( IndVar(i) ), ')^{3}+', num2str(Coefs_3), ...'(', num2str( IndVar(i + 1) ), '-x)+', num2str(Coefs_4), '(x-', num2str( IndVar(i) ), ')'], ...'FontName', 'Times New Roman', 'FontSize', 14)hold onend% 过x=1和x=2两个横轴点作垂线%line([1, 1], [2.5, -0.5], 'LineStyle', '--');line([2, 2], [2.5, -0.5], 'LineStyle', '--');% 为x轴和y轴添加标注xlabel( '\itx', 'FontName', 'Times New Roman', ...'FontSize', 14, 'FontWeight', 'bold');ylabel( '\its(x)', 'FontName', 'Times New Roman', ...'Rotation', 0, 'FontSize', 14, 'FontWeight', 'bold');最终,三次样条插值函数s(x)表达式为:[][][]⎪⎩⎪⎨⎧∈-+-+-+--∈-+-+---∈+-++--=.3,2,)2(44.1)3(62.2)2(06.0)3(62.0,2,1,)1(62.2)2(08.0)1(62.0)2(42.0,1,0,08.0)1(06.042.0)1(06.0)(333333x x x x x x x x x x x x x x x x s曲线的图像如图所示:例2 已知函数值表:试求在区间[1,5]上满足上述函数表所给出的插值条件的三次自然样条插值函数)(x s本算法求解出的三次样条插值函数将写成三弯矩方程的形式:)()6()()6()(6)(6)(211123131j j jj j j jj j j j jj j jj x x h h M y x x h h M y x x h M x x h M x s --+--+-+-=+++++其中,方程中的系数jj h M 6,jj h M 61+,jj j j h h M y )6(2-,jjj j h h M y )6(211++-将由Matlab代码中的变量Coefs_1、Coefs_2、Coefs_3以及Coefs_4的值求出。
实验报告:牛顿差值多项式&三次样条... . (1)问题:在区间[-1,1]上分别取n=10、20用两组等距节点对龙格函数f (x)---作多项式插25 x 2值及三次样条插值对每个n值,分别画出插值函数矽(x)的图形。
实验目的:通过编程实现牛顿插值方法和三次样条方法,加深对多项式插值的理解。
应用所编程序解决实际算例。
实验要求:1.认真分析问题,深刻理解相关理论知识并能熟练应用;2.编写相关程序并进行实验;3.调试程序,得到最终结果;4.分析解释实验结果;5.按照要求完成实验报告。
实验原理:详见《数值分析第5版》第二章相关容。
实验容:(1)牛顿插值多项式1.1 当 n=10 时:在Matlab下编写代码完成计算和画图。
结果如下:代码:clear allclcx1=-1:0.2:1;y1=1./(1+25.*x1.八2);n=length(x1);f=y1(:);for j=2:nfor i=n:-1:jf(i) = (f(i)-f(i-1))/(x1(i)-x1(i-j+1));endendsyms F x p;F(1)=1;p(1)=y1(1);for i=2:nF(i)=F(i-1)*(x-x1(i-1));p(i)=f(i)*F(i);endsyms PP=sum(p);P10=vpa(expand(P),5);x0=-1:0.001:1;y0=subs(P,x,x0);y2=subs(1/(1+25火x八2),x,x0);plot(x0,y0,x0,y2)grid onxlabel('x')ylabel('y')P10即我们所求的牛顿插值多项式,其结果为:P10(x )=-220.94*x A10+494.91*x A8-9.5065e-14*x A7-381.43*x A6-8.504e-14*x A5+123.36*x A4+2.0202e-14*x A3-16.855*x A2-6.6594e-16*x+1.0并且这里也能得到该牛顿插值多项式的在[-1,1]上的图形,并和原函数进行对比(见Fig.1)。
三次样条插值数学公式
我们要找出三次样条插值的数学公式。
首先,我们需要了解三次样条插值的基本概念和原理。
三次样条插值是一种数学方法,用于通过给定的数据点来估计一个平滑的函数。
它要求在每个数据点之间,该函数是连续的,并且在每个数据点的端点上,该函数是二阶连续可导的。
假设我们有一组数据点 (x0, y0), (x1, y1), ..., (xn, yn)。
我们想要找到一个函数 S(x),它在每个数据点上是连续的,并且在整个数据区间上是平滑的。
三次样条插值的数学公式如下:
S(x) = ai + bi(x-xi) + ci(x-xi)^2 + di(x-xi)^3
其中,i = 0, 1, ..., n,且满足以下条件:
1. S(xi) = yi (i = 0, 1, ..., n)
2. S'(xi) = 0 (i = 1, 2, ..., n-1)
3. S''(xi) = 0 (i = 2, 3, ..., n-1)
4. S(x0) = S(xn) = 0
5. S'(x0) = S'(xn) = 0
6. S''(x0) = S''(xn) = 0
这些条件确保了函数 S(x) 在数据点上是连续的,并且在整个数据区间上是平滑的。
通过解这组方程,我们可以找到 a0, a1, ..., an, b0, b1, ..., bn, c0, c1, ..., cn, d0, d1, ..., dn。
然后,我们就可以使用 S(x) 来估计任何 x 处的 y 值。
这就是三次样条插值的数学公式。
三次样条求离散点斜率的公式
我们要找出三次样条插值法中离散点斜率的计算公式。
首先,我们需要了解三次样条插值法的基本原理。
三次样条插值法是一种数学方法,用于通过给定的离散点集来拟合一个连续的函数。
这个方法的关键在于找到一个连续的、在离散点处可微的函数,这个函数通常被称为“样条”。
假设我们有一个离散点集(x0, y0), (x1, y1), ..., (xn, yn)。
我们希望找到一个连续的、在离散点处可微的函数S(x),使得S(xi) = yi,其中i = 0, 1, ..., n。
三次样条插值法的核心在于找到这样一个函数S(x),它由一系列的三次多项式组成,这些多项式在相邻的离散点之间是连续的,并且在离散点的边界处也是连续的。
对于离散点(xi, yi),其斜率可以通过以下公式计算:
斜率= 3hi / (xi - xi-1)
其中hi 是样条在该点处的“高度”(或称为“步长”)。
这个公式告诉我们如何根据给定的离散点集计算每个离散点的斜率。
计算结果为:斜率= 3hi / (xi - xi-1)
所以,离散点斜率的计算公式为:斜率= 3hi / (xi - xi-1)。