数值分析论文 (11)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

四、计算结果:
五、程序源代码。 #include "stdafx.h" #include<stdio.h> void main(int argc,char* argv[]) { int i1,i2,p,j,k,w,n=0; float x[100],f[100][100],f1[100],x1,x2,N1,N2=1.0,N3=0.0; printf("请输入节点个数w<=100: "); //输入节点个数 scanf("%d",&w); for(n=0;n<w;n++) //根据节点个数和阶商的关系,用 节点控制输入节点及对应的函数值 { printf("x="); scanf("%f",&x[n]); printf("f(x)="); scanf("%f",&f1[n]); } for(n=0;n<w;n++) //将节点对应的函数值送给 二维数组 f[n][0]=f1[n]; for(j=1;j<n;j++) //循环计算差商的值 { k=j; for(p=0;k<n;k++,p++) //用k控制同一维的下标,用j控制维
Input x[n]: O,4 0.55 0.65 0.8 0.9 Input y[n] 0.41075 0.57815 0.69675 0.88811 1.02652 Please input x:0.596 Nn(0.596)=0.631914 1.2牛顿插值 1.2.1基本原理 构造n次多项式Nn(x)=f(x0)+f(x0,x1)(x-x0)+f(x0,x1,x2)(x-x0)(xx1)+… +f(x0,x1,x2,…,xn)(x-x0)(x-x1)…(x-xn) 称为牛顿插值多项式,其中 (二个节点,一阶差商) (三个节点,二阶差商) (n+1个节点,n阶差商) 注意:由于插值多项式的唯一性,有时为了避免拉格朗日余项Rn(x) 中n+1阶导数的运算,用牛顿插值公式Rn (x)=f(x)-Nn(x)=f(x,x0, …,xn)ωn+1(x), 其中ωn+1(x)=(x-x0)(x-x1)…(x-xn) 1.2.2优缺点 牛顿插值法具有承袭性和易变性的特点,当增加一个节点时,只要再增 加一项就可以了即而拉格朗日插值若要增加一个节点时全部基函数都需 要重新算过。牛顿插值法既适合于用来计算函数值,也适合于做理论推 导,比如说可用来推导微分方程的数值求解公式。
1.1.3数值实验 程序如下:
#include<stdio.h> #define TRUE 1 #define FALSE 0 #define N 10 #define M 2 void main(void) { double x[N],y[N],a,l[N]; int i,j,n,flag; double answer=0.00f; do{ printf("创建Lagrange插值多项式共用到N组(X,Y)值,请输入N:"); scanf("%d",&n); if(n<=N&&n>=M) flag=FALSE; else if(n>N||n<=1) { printf("对不起,你输入错误!\n请确保你输入的N满足 2<=N<=%d.",N); printf("\n"); flag=TRUE; } }while(flag==TRUE); printf("\n请输入需要计算的X值:"); scanf("%lf",&a); for(i=0;i<n;i++) { printf("请输入第%d组(X,Y)的值:",i+1); scanf("%lf%lf",x+i,y+i); } for(i=0;i<n;i++) { l[i]=1.0f; for(j=0;j<N;j++) if(i!=j) l[i]*=(a-x[j])/(x[i]-x[j]); else continue; answer+=l[i]*y[i]; } printf("f(%.3lf)=%lf\n",a,answer); } 实验结果 Input n:4
பைடு நூலகம்
1.2.3数值实验 一、差商相关公式 二、题目 已知函数表如下: 0.0 0.84147 0.5 0.85770 1.0 0.89924 1.5 0.94898 2.0 0.98777 2.5 0.99955
1.计算用3次Newton插值多项式。 2.计算用5次Newton插值多项式。 三、程序思想 根据实际计算理论,利用Newton插值多项式计算,事先应知道其节 点个数。所以,本程序设置在100个节点即最高次可达99次的多项式计 算,通过输入节点个数来控制每次要计算的多项式的次数。 首先,计算各阶的函数值。 根据节点的个数与每阶阶商具有的阶商个数循环计算各阶商的值, 并根据相应的节点下标控制输出各阶商值。 其次,输出最高阶表达式。 由于最高阶表达式是从0位开始计算的,所以,在知道节点下标的 基础上,每次以二维数组两下标是否相等来输出相应的阶商,及x的值 与节点的起止下标输出相应的表达式。 最后,根据输入的节点数计算其对应的函数值。 3阶计算表达式,任意输入节点值,根据输入的节点值的大小判断其 所在的范围,以输出表达式同样的思想计算节点对应的函数值。最高阶 表达式,亦是通过循环计算获得相应的函数值。
数,用p控制节点的起始下标 f[k][j]=(f[k][j-1]-f[k-1][j-1])/(x[k]-x[p]); } printf(" xi f(xi) 1阶差商"); //输出固定格式 for(i1=1;i1<n-1;i1++) //用i1作循环,循环 输出(i1+1)阶差商作固定格式 printf(" %d阶差商",(i1+1)); for(i1=0;i1<n;i1++) //循环输出节点的值 { { if(x[i1]>=0) //作判断一控制输出空格的 长度以使每次输出起始位置对齐 if(x[i1]>=10&&x[i1]<100) printf("\n%.5f ",x[i1]); else if(x[i1]>=100) printf("\n%.5f ",x[i1]); else printf("\n%.5f ",x[i1]); else if(x[i1]<=-10) printf("\n%.5f ",x[i1]); else if(x[i1]<=-100) printf("\n%.5f ",x[i1]); else printf("\n%.5f ",x[i1]); } for(i2=0;i2<=i1;i2++) //此循环嵌在上一循环里作循环输 出并判断,控制输出空格的长度使输出对齐 if(f[i1][i2]>=0) { if(f[i1][i2]>10) { if(f[i1][i2]>=100) printf("%.5f ",f[i1][i2]); else printf("%.5f ",f[i1][i2]); } else printf("%.5f ",f[i1][i2]); } else { if(f[i1][i2]<=-10) { if(f[i1][i2]<=-100) printf("%.5f ",f[i1][i2]); else printf("%.5f ",f[i1][i2]); } else printf("%.5f ",f[i1][i2]); } } printf("\nN%d(x)=%.5f+",n-1,f[0][0]); //输出最高阶表 达式 for(i1=1;i1<n;i1++) for(j=1;j<n;j++) if(i1==j) //用i1,j的下标相等 的差商值输出 { if(f[i1][j]<0) //负数加括号输出
节点的值
printf("(%.5f)",f[i1][j]); else printf("%.5f",f[i1][j]); for(k=0;k<j;k++)
//用k循环控制输出
printf("(x-%.5f)",x[k]); printf("\n"); if(j<n-1) //根据判断在输出每 一项后是否输出“+” printf(" +"); } printf("输入节点x1(用3次多项式计算),x2(用%d次多项式计 算):\n",n-1); scanf("%f%f",&x1,&x2); //提示输入两个要计算 的节点 for(i1=0;i1<n;i1++) //对x1进行判断早出 其所在的区间的节点的下标值 if(x1>x[i1]) break; //判断下标后退出 if((n-i1)>=3) //判断其下标后是否还 有3个节点,如果有就以次区间作计算 i2=i1; else //如果次下标后没有3个节 点,将下标i1减2再作判断 { i1=i1-2; if(i1>=0) i2=i1; //此时i1>=0就以次下标 开始作区间 else { i2=i1+1; //在前边i1-2如果<0,则将 其下标加1 i1=i2; } } N1=f[i1][0]; for(j=1;j<4;j++,i1++) { N2=N2*f[i1+1][i1+1]; //根据节点的区间和阶商的具 有同一下标的关系,循环计算阶商的值 for(k=i2;k<i2+j;k++) //在前一循环基础上循环计算 每阶商后对应节点间的值,并控制节点的末位 N2=N2*(x1-x[k]); N3=N2+N3; N2=1.0; } N3=N1+N3; //将计算的值赋给N3并输出 printf("N3(%.5f)=%.5f\n",x1,N3); N3=0.0; N1=f[0][0]; for(i1=1;i1<n;i1++) //以同样的方式计算最高阶的 值
代数插值法
1. 插值法概述 插值法是函数逼近的重要方法之一,有着广泛的应用 。在生产和实 验中,函数f(x)或者其表达式不便于计算复杂或者无表达式而只有函数 在给定点的函数值(或其导数值) ,此时我们希望建立一个简单的而便 于计算的函数(x),使其近似的代替f(x),有很多种插值法,其中以拉格 朗日(Lagrange)插值和牛顿(Newton)插值为代表的多项式插值最有特 点,常用的插值还有Hermit插值,分段插值和样条插值.这里主要介绍拉 格朗日(Lagrange)插值和牛顿(Newton)插值。 1.1拉格朗日插值 1.1.1基本原理 构造n次多项式Pn (x)= yk lk (x)=y0l0 (x)+y1l1 (x),这是不超过n次的多项式,其中基函数lk(x)= 显然lk (x)满足lk (xi)= 此时 Pn(x)≈f(x),误差Rn(x)=f(x)-Pn(x)= 其中∈(a,b)且依赖于x,=(x-x0)(x-x1)…(x-xn) 很显然,当n=1、插值节点只有两个xk,xk+1时 P1(x)=yklk(x)+yk+1lk+1(x) 其中基函数lk(x)= lk+1(x)= 1.1.2优缺点 可对插值函数选择多种不同的函数类型,由于代数多项式具有简单 和一些良好的特性,故常选用代数多项式作为插值函数。利用插值基函 数很容易得到拉格朗日插值多项式,公式结构紧凑,在理论分析中甚为 方便,但当插值节点增减时全部插值基函数Lk(x)(k=0,1,…,n)均要随 之变化,整个公式也将发生变化,这在实际计算中是很不方便的,为了 克服这一缺点,提出了牛顿插值可以克服这一缺点。 (x)+…+ynln
{ for(i2=0;i2<i1;i2++) N2=N2*(x2-x[i2]); N2=N2*f[i1][i1]; N3=N2+N3; N2=1.0; } N3=N1+N3; printf("N%d(%.5f)=%.5f\n",n-1,x2,N3); 节点的值 } 2.误差分析
//输出最高阶计算
依据f(x)数据表构造出来它的插值函数P(x),然后, 在给定点x计算P(x)的值作为f(x)的近似值,这一过程称 插值。所谓“插值”,通俗地说,就是依据f(x)所给的函 数表“插出”所要的函数值。由于插值函数P(x)通常只是 近似地刻划了原来的函数f(x),在插值点x处计算P(x)作为 f(x)的函数值,一般地说总有误差,称R(x)= f(x)-P(x) 为插值函数的截断误差,或称插值余项。用简单的插值函数 P(x)来替代很复杂的的函数f(x),这种做法究竟是否有效, 要看截断误差是否满足所要求的精度。取n+1个节点进行插值 时,插值多项式是唯一的,即此时拉格朗日插值多项式和牛 顿插值多项式是相等的,因此其余项也相等。
相关文档
最新文档