Newton插值多项式的C程序实例
MAAB牛顿插值法例题与程序
题目一:多项式插值某气象观测站在8:00(AM )开始每隔10分钟对天气作如下观测,用三次多项式插值函数(Newton )逼近如下曲线,插值节点数据如上表,并求出9点30分该地区的温度(x=10)。
二、数学原理假设有n+1个不同的节点及函数在节点上的值(x 0,y 0),……(x n ,y n ),插值多项式有如下形式:)())(()()()(n 10n 102010n x -x )(x -x x -x x P x x x x x x -⋯⋯-+⋯⋯+-++=αααα(1) 其中系数i α(i=0,1,2……n )为特定系数,可由插值样条i i n y x P =)((i=0,1,2……n )确定。
根据均差的定义,把x 看成[a,b]上的一点,可得f(x)=f (0x )+f[10x x ,](0x -x ) f[x,0x ]=f[10x x ,]+f[x,10x x ,](1x -x )……f[x,0x ,…x 1-n ]=f[x,0x ,…x n ]+f[x,0x ,…x n ](x-x n )综合以上式子,把后一式代入前一式,可得到:f(x)=f[0x ]+f[10x x ,](0x -x )+f[210x x x ,,](0x -x )(1x -x )+…+f[x,0x ,…x n ](0x -x )…(x-x 1-n )+f[x,0x ,…x n ,x ])(x 1n +ω=N n (x )+)(x n R 其中N n (x )=f[0x ]+f[10x x ,](0x -x )+f[210x x x ,,](0x -x )(1x -x )+ …+f[x,0x ,…x n ](0x -x )…(x-x 1-n )(2))(x n R =f(x)-N n (x )=f[x,0x ,…x n ,x ])(x 1n +ω(3) )(x 1n +ω=(0x -x )…(x-x n ) Newton 插值的系数i α(i=0,1,2……n )可以用差商表示。
Newton插值的C++实现
Newton插值的C++实现Newton(⽜顿)插值法具有递推性,这决定其性能要好于Lagrange(拉格朗⽇)插值法。
其重点在于差商(Divided Difference)表的求解。
步骤1. 求解差商表,这⾥采⽤⾮递归法(看着挺复杂挺乱,这⾥就要⾃⼰动笔推⼀推了,闲了补上其思路),这样,其返回的数组(指针)就是差商表了,/** 根据插值节点及其函数值获得差商表* 根据公式⾮递归地求解差商表* x: 插值节点数组* y: 插值节点处的函数值数组* lenX: 插值节点的个数* return: double类型数组*/double * getDividedDifferenceTable(double x[], double y[], int lenX) {double *result = new double[lenX*(lenX - 1) / 2];for (int i = 0; i < lenX - 1; i++) {result[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);}int step = lenX - 1; // 增加步长int yindex = lenX - 1; // 分⼦的基准值,线性减速递增int xgap = 2; // 分母的间距,每次+1int xstep = 2;while (step >= 1) {for (int i = 0; i < step - 1; i++) {result[yindex + i] = (result[yindex - step + i + 1] - result[yindex - step + i]) / (x[xstep + i] - x[xstep + i - xgap]);}yindex += (step - 1);xstep++;step--;xgap++;}return result;}步骤 2. 取得差商表每⼀列的第⼀个作为基函数的系数/*** 从差商表中获取⼀定阶数的某个差商* dd: 差商表* len: 差商表的长度* rank: 所取差商的阶数* index: rank阶差商的第index个差商* return: 返回double类型所求差商*/double getDividedDifference(double dd[], int len, int rank, int index) {// 根据差商表的长度求解差商的最⾼阶数// 由于差商表是三⾓形的,因此有规律可循,解⽅程即可int rankNum = (int)(0.5 + sqrt(2 * len + 0.25) - 1);printf("%d 阶差商 \n", rank);int pos = 0;int r = 1;// 根据n+(n+1)+...+(n-rank)求得rank阶差商在差商表数组中的索引while (rank > 1){// printf("geting dd's index, waiting...\n");pos += rankNum;rank--;rankNum--;}pos += index; // 然后加上偏移量,意为rank阶差商的第index个差商return dd[pos];}步骤3. Newton 插值主流程/** Newton Interpolating ⽜顿插值主要代码* x: 插值节点数组* y: 插值节点处的函数值数组* lenX: 插值节点个数(数组x的长度)* newX: 待求节点的数组* lennx: 待求节点的个数(数组lenX的长度)*/double *newtonInterpolation(double x[], double y[], int lenX, double newX[], int lennx) {// 计算差商表double *dividedDifferences = getDividedDifferenceTable(x, y, lenX);//double *result = new double[lennx];// 求差商表长度int ddlength = 0;for (int i = 1; i < lenX; i++){ddlength += i;}// 打印差商表信息printf("=======================差商表的信息=======================\n");printf("差商个数有:%d, 待插值节点个数:%d\n =======================差商表=======================", ddlength, lennx); int ifnextrow = 0; // 控制打印换⾏for (int i = 0; i < ddlength; i++) {if (ifnextrow == (i)*(i + 1) / 2)printf("\n");printf("%lf, ", dividedDifferences[i]);ifnextrow++;}printf("\n");// 计算Newton Interpolating 插值double ddi = 0;double coef = 1;for (int i = 0; i < lennx; i += 2) {coef = (double)1;result[i] = y[i];printf("=============打印计算过程=============\n");for (int j = 1; j < lenX -1; j++) {coef *= (newX[i] - x[j - 1]);ddi = getDividedDifference(dividedDifferences, ddlength, j, 0);printf("取得差商: %lf\n", ddi);result[i] = result[i] + coef * ddi;printf("计算result[%d] + %lf * %lf", i, coef, ddi);printf("获得结果result %d: %lf\n", i, result[i]);}printf("result[%d] = %lf\n", i, result[i]);// =======================选做题:求误差==========================printf("求解截断误差所需差商:%lf\n", getDividedDifference(dividedDifferences, ddlength, lenX-1, 0));// printf("求解截断误差所需多项式:%lf\n", coef);printf("求解截断误差所需多项式的最后⼀项:%lf - %lf\n", newX[i] , x[lenX - 2]);result[i + 1] = getDividedDifference(dividedDifferences, ddlength, lenX - 1, 0)*coef*(newX[i] - x[lenX - 2]);// ===============================================================}if (dividedDifferences) {delete[] dividedDifferences;}return result;}步骤4. 主函数⽰例int main(){std::cout << "Hello World!\n";printf("Newton插值!\n");double x[] = {0.40, 0.55, 0.65, 0.80, 0.90, 1.05};//double x[] = { 1.5, 1.6, 1.7 };int lenX = sizeof(x) / sizeof(x[0]);double y[] = {0.41075, 0.57815, 0.69675, 0.88811, 1.02652, 1.25382};//double y[] = { 0.99749, 0.99957, 0.99166 };double newx[] = {0.596};//double newx[] = { 1.609 };// 计算⽜顿插值结果和截断误差double *result = newtonInterpolation(x, y, lenX, newx, 1);printf("=====================最终结果=====================\n");printf("求得sin(1.609)的近似值为:%lf\n", *result);printf("截断误差:%.10lf\n", *(result + 1));if (result) {delete[] result;}return0;}。
C语言编写牛顿插值多项式的实现
1实验名称:Newton 插值多项式实验目的了解Newton 插值多项式实验类型设计型实验环境Windows XP TC实验内容相关知识:通过n+1个节点的次数不超过n 的Newton 插值多项式为:)())(](,,,[))(](,,[)](,[)()(11010102100100----++--+-+=n n n x x x x x x x x x f x x x x x x x f x x x x f x f x N数据结构:两个一维数组或一个二维数组算法设计:(略)实验用例: 已知函数y=f(x)的一张表(同上一个试验)试验要求:利用Newton 插值多项式)(x N n 求被插值函数f(x)在点x=65处的近似值。
建议:画出Newton 插值多项式)(x N n 的曲线。
编写代码:#include<stdio.h>#include <graphics.h>double Juncha(double a[13][2],int f,int l){double m;if((l-f)>1){m=(Juncha(a,f+1,l)-Juncha(a,f,l-1))/(a[l][0]-a[f][0]); }elsem=(a[l][1]-a[f][1])/(a[l][0]-a[f][0]);return m;}double Newton(double a[13][2],double x) {double m,n,y;int i,j;y=a[0][1];i=j=1;while(i!=13){j=0;m=n=1.0;m=Juncha(a,j,i);while(j!=i){n=(x-a[j][0])*n;j++;}y=y+m*n;i++;}return y;}double Lglr(double a[13][2],double x) {double m,n,y;int i,j;m=n=1.0;i=j=y=0;while(i!=13){j=0;m=n=1;while(j<13){if(j!=i)m=(x-a[j][0])*m;j++;}j=0;while(j<13){if(j!=i)n=(a[i][0]-a[j][0])*n;j++;}y=y+m/n*a[i][1];i++;}return y;}void main(){double a[13][2]={0,5,10,1,20,7.5,30,3,40,4.5,50,8.8,60,15.5,70,6.5,80,-5,90,-10,100,-2,110,4.5,120,7}; double x,x1;int arw[6]={515,235,520,240,515,245};int arw1[6]={315,45,320,40,325,45};int gdriver=VGA;int gmode=VGAHI;initgraph(&gdriver, &gmode, "c:\\TC20\\BGI");c leardevice();printf("input x:\n");scanf("%lf",&x);x1=x;printf("y=%f\n",Newton(a,x));s etbkcolor(7);s etcolor(14);s etlinestyle(0,0,3);d rawpoly(3,arw);d rawpoly(3,arw1);l ine(120,240,520,240);l ine(320,40,320,440);s etlinestyle(1,0,1);line(320,150,320,340);line(330,150,330,340);line(340,150,340,340);line(350,150,350,340);line(360,150,360,340);line(370,150,370,340);line(380,150,380,340);line(390,150,390,340);line(400,150,400,340);line(410,150,410,340);line(420,150,420,340);line(430,150,430,340);line(440,150,440,340);setcolor(3);outtextxy(320,30,"Y");outtextxy(310,245,"O");outtextxy(525,240,"X");settextstyle(4,0,4);outtextxy(450,400,"Newton...");x=0;s etcolor(2);s etlinestyle(0,0,3);m oveto((x+320),(240-Newton(a,x)));w hile(x<=119){x=x+1;lineto((x+320),(240-Newton(a,x)));}x=0;s etcolor(6);s etlinestyle(0,0,1);m oveto((x+320),(240-Lglr(a,x)));w hile(x<=119){x=x+1;lineto((x+320),(240-Lglr(a,x)));}s etcolor(4);s etlinestyle(1,0,1);l ine((x1+320),((240-Newton(a,x1))-80),(x1+320),((240-Newton(a,x1))+120)); getch();c losegraph();}实验结果(测试用例、实验结果)实验总结与心得通过本次实验,对Newton插值多项式有了更深刻的了解!。
牛顿插值多项式
{ printf("x[%d]:",i); scanf("%f",&x[i]);/*从键盘上输入 x[i]的值,并 在屏幕上显示*/ } printf("\n"); for(i=0;i<=n-1;i++) { printf("y[%d]:",i);scanf("%f",&y[i]);} /*从键盘上 输入 y[i]的值,并在屏幕上显示*/ printf("\n"); difference(x,(float *)y,n); printf("Input xx:"); scanf("%f",&xx); yy=y[20]; for(i=n-1;i>=0;i--) yy=yy*(xx-x[i])+y[i]; /*牛顿插值 多项式算法公式*/ printf("NewtonInter(%f)=%f",xx,yy); /*输出结果*/ getch(); } 1. 数据输入与输出:
牛顿插值多项式公式为 Pn(x)=
-4-
f ( x0 ) f [ x0 , x1 ]( x x0 ) ... f [ x0 ..., xn1 ] ( x x j )
j 0 n2
f [ x0 , x1..., xn ] ( x x f ).
j 0
n1
程序窗口
-6-
结果输出为:-9615.
2. 总结与归纳:
牛顿插值多项式具有承袭性,可以在原有插值多项式的基 础上补上个节点进行补算。为了验证电脑计算与人工计算 进行结果对比, 所以 N 值设得较小, 但 N 的值只体现插值 的精度。
牛顿插值多项式
# include <iostream># include<cmath>using namespace std;void main(){double z,r,r1,error,error1;double p5,p50,p51,p52,p53,p54,p55;double p4, p40,p41,p42,p43,p44;double z0=0.30,z1=0.30,z2=0.32,z3=0.32,z4=0.35,z5=0.35;double f0=0.29552,f1=0.29552,f2=0.31457,f3=0.31457,f4=0.34290,f5=0.34290;double f00=0.95534,f11=0.94924,f22=0.93937;double f01,f12,f23,f34,f45;double f012,f123,f234,f345;double f0123,f1234,f2345;double f01234,f12345;double f012345;double a0,a1,a2,a3,a4,a5;double z01,z012,z0123,z01234;double g01,g02,g03,g04;double g12,g13,g14,g23,g24,g34;double g012,g013,g014,g023,g024,g034,g123,g124,g134,g234;double g0123,g0124,g0134,g0234,g1234;double g01234;z01=z0+z1;z012=z0+z1+z2;z0123=z0+z1+z2+z3;z01234=z0+z1+z2+z3+z4;g01=z0*z1,g02=z0*z2,g03=z0*z3,g04=z0*z4;g12=z1*z2,g13=z1*z3,g14=z1*z4;g23=z2*z3,g24=z2*z4;g34=z3*z4;g012=z0*z1*z2,g013=z0*z1*z3,g014=z0*z1*z4,g023=z0*z2*z3,g024=z0*z2*z4,g034=z0* z3*z4;g123=z1*z2*z3,g124=z1*z2*z4,g134=z1*z3*z4;g234=z2*z3*z4;g0123=z0*z1*z2*z3,g0124=z0*z1*z2*z4,g0134=z0*z1*z3*z4,g0234=z0*z2*z3*z4;g1234=z1*z2*z3*z4;g01234=z0*z1*z2*z3*z4;f01=f00;f12=(f2-f1)/(z2-z1);f23=f11;f34=(f4-f3)/(z4-z3);f45=f22;f012=(f12-f01)/(z2-z0);f123=(f23-f12)/(z3-z1);f234=(f34-f23)/(z4-z2);f345=(f45-f34)/(z5-z3);f0123=(f123-f012)/(z3-z0);f1234=(f234-f123)/(z4-z1);f2345=(f345-f234)/(z5-z2);f01234=(f1234-f0123)/(z4-z0);f12345=(f2345-f1234)/(z5-z1);f012345=(f12345-f01234)/(z5-z0);a0=f0,a1=f01,a2=f012,a3=f0123,a4=f01234,a5=f012345;cout<<endl;cout<<"a0="<<a0<<endl;cout<<"a1="<<a1<<endl;cout<<"a2="<<a2<<endl;cout<<"a3="<<a3<<endl;cout<<"a4="<<a4<<endl;cout<<"a5="<<a5<<endl;cout<<endl;cout<<"请输入要计算的值z=";cin>>z;cout<<endl;r=sin(z);r1=cos(z);//p5=a0+a1*(z-z0)+a2*(z-z0)*(z-z1)+a3*(z-z0)*(z-z1)*(z-z2)+a4*(z-z0)*(z-z1)*(z-z2)*(z-z3)+ a5*(z-z0)*(z-z1)*(z-z2)*(z-z3)*(z-z4);p50=a0;p51=a1*(z-z0);p52=a2*(pow(z,2)-z01*z+g01);p53=a3*(pow(z,3)-z012*pow(z,2)+(g01+g02+g12)*z-g012);p54=a4*(pow(z,4)-z0123*pow(z,3)+(g01+g02+g03+g12+g13+g23)*pow(z,2)-(g012+g013+ g023+g123)*z+g0123);p55=a5*(pow(z,5)-z01234*pow(z,4)+(g01+g02+g03+g04+g12+g13+g14+g23+g24+g34)*p ow(z,3)-(g012+g013+g014+g023+g024+g034+g123+g124+g134+g234)*pow(z,2)+(g0123+ g0124+g0134+g0234+g1234)*z-g01234);p5=p50+p51+p52+p53+p54+p55;p40=a1;p41=a2*(2*z-z01);p42=a3*(3*pow(z,2)-2*z012*z+(g01+g02+g12));p43=a4*(4*pow(z,3)-z0123*3*pow(z,2)+(g01+g02+g03+g12+g13+g23)*2*z-(g012+g013+ g023+g123));p44=a5*(5*pow(z,4)-z01234*4*pow(z,3)+(g01+g02+g03+g04+g12+g13+g14+g23+g24+g34)*3*pow(z,2)-(g012+g013+g014+g023+g024+g034+g123+g124+g134+g234)*2*z+(g0123+g0124+g0134+g0234+g1234));p4=p40+p41+p42+p43+p44;cout<<"牛顿插值多项式的值p5("<<z<<")="<<p5<<endl<<endl;cout<<"牛顿插值多项式一阶导数的值p4("<<z<<")="<<p4<<endl;cout<<endl<<endl;cout<<"原来函数的值sin("<<z<<")="<<r<<endl<<endl;cout<<"一阶导数的值cos("<<z<<")="<<r1<<endl;cout<<endl;error=fabs(p5-sin(z));error1=fabs(p4-cos(z));cout<<"函数值误差:"<<error<<endl<<endl;cout<<"一阶导数函数值的误差:"<<error1<<endl<<endl;}运行结果:。
用C语言实现牛顿向前插值计算
用C语言实现牛顿向前插值计算,程序代码如下:#include "stdlib.h"#include "stdio.h"#include "conio.h"#include "string.h"#include "math.h"#define N 100typedef struct{float x;float y;}POINT;float CreTable(int n,POINT Table[N],float y[N][N]){int i,j,count=0;for(i=0;i<n;i++){printf("Input %dth point(x%d,y%d):",i+1,i+1,i+1);scanf("%f,%f",&Table[i].x,&Table[i].y);}for(i=0;i<n;i++)y[i][0]=Table[i].y;for(j=1;j<n;j++,count++){i=count;for(;i<n-1;i++)y[i+1][j]=y[i+1][j-1]-y[i][j-1];}}float ShowTable(int n,POINT Table[N],float y[N][N]){int i,j;printf("\nForward difference table:\n");printf(" x y\n");for(i=0;i<n;i++){printf("%10.5f",Table[i].x);for(j=0;j<=i;j++){printf("%10.5f",y[i][j]);if(j==i) printf("\n");}}}float Calculus(int n,POINT Table[N],float y[N][N]) {int i,j,k,count[N]={0};float tmp1,tmp2,tmp3,sum,a[N],h[N],x[N],t[N];printf("\nNumber of x:");scanf("%d",&k);for(j=0;j<k;j++){printf("Input x0[%d]:",j+1);scanf("%f",&a[j]);printf("Input x[%d]:",j+1);scanf("%f",&x[j]);printf("Input h[%d]:",j+1);scanf("%f",&h[j]);t[j]=(x[j]-a[j])/h[j];printf("t[%d]=%.5f\n",j+1,t[j]);for(i=0;i<n;i++)if(Table[i].x==a[j]){count[j]=i;break;}}printf("\nThe results:");for(j=0;j<k;j++){tmp1=1;tmp2=1;sum=y[count[j]][0];for(i=1;;i++){tmp1=tmp1*(t[j]-i+1);tmp2=tmp2*i;tmp3=tmp1*y[count[j]+i][i]/tmp2;sum=sum+tmp3;if(count[j]+i==n-1) break;}printf("\n N(%f)= %f",x[j],sum);}}int main(){int n;float y[N][N],x[N];POINT Table[N];printf("Number of points n=");scanf("%d",&n);CreTable(n,Table,y);ShowTable(n,Table,y);Calculus(n,Table,y);getch();}。
牛顿插值法的C语言编程
Newton 插值Newton 插值函数 Newton 插值函数是用差商作为系数,对于01,,,n x x x …这1n +个点,其一般形式为:00100120101011()[][,]()[,,]()()[,,,]()()()n n n N x f x f x x x x f x x x x x x x f x x x x x x x x x −=+−+−−++−−−…………对于011,,,n x x x −…这n 个点,100100120101012()[][,]()[,,]()()[,,,]()()()n n n N x f x f x x x x f x x x x x x x f x x x x x x x x x −−=+−+−−++−−−…………差商的定义 若已知函数()f x 在点(0,1,2,,)i x i n =⋅⋅⋅处的函数值()i f x 。
则称:00[]()f x f x =为函数()f x 在点0x 的0阶差商;100110[][][,]f x f x f x x x x −=−为函数()f x 关于01,x x 的1阶差商;120101220[,][,][,,]f x x f x x f x x x x x −=−为函数()f x 过点012,,x x x 的2阶差商;依此类推,一般地称121012101210[,,,,][,,,,][,,,,,]k k k k k k k f x x x x f x x x x f x x x x x x x −−−−⋅⋅⋅−⋅⋅⋅⋅⋅⋅=−为函数()f x 关于01,,,k x x x ⋅⋅⋅的k 阶差商。
表1 差商表i x ()i f x 1阶差商 2阶差商3阶差商4阶差商0x 1x 2x 3x 4x……0()f x 1()f x 2()f x 3()f x 4()f x ……01[,]f x x12[,]f x x 23[,]f x x 34[,]f x x……012[,,]f x x x 123[,,]f x x x 234[,,]f x x x ……0123[,,,]f x x x x 1234[,,,]f x x x x ……01234[,,,,]f x x x x x……根据Newton 插值函数编写的C 语言编程根据Newton 插值函数并对照上面的差商表,可编写出Newton 插值法的C 语言程序如下: #include<stdio.h> #include<iostream.h> #include <stdlib.h>double NewtonInterpolation(double *x,double *y,int n,double xx,double *pyy) {double *f=(double *)malloc(n*sizeof(double));int i,k;for(i=1;i<=n-1;i++)f[i]=y[i];for(k=1;k<=n-1;k++)for(i=k;i<=n-1;i++){f[i]=(y[i]-y[i-1])/(x[i]-x[i-k]);if(i==n-1)for(i=k;i<n;i++)y[i]=f[i];}*pyy=y[n-1];for(i=n-2;i>=0;i--)*pyy=(*pyy)*(xx-x[i])+y[i];free(f);return 0;}void main(){int n=5;double x[5]={1.0,2.7,3.2,4.8,5.6},y[5]={14.2,17.8,22.0,38.3,51.7},xx=3,yy; NewtonInterpolation(x,y,n,xx,&yy);printf("%lf\n",yy);}。
拉格朗日和牛顿插值法的C 方法实现(数值分析上机实验)
数值分析上机实验实验一一.上机题目:已知: 4 =2,9 =3,16 =4分别用二次Lagrange和Newton插值法求7 的近似值。
二.解题方法:1.lagrange方法:设x0=4,y0=2,x1=9,y1=3,x2=16,y2=4代入方程:(x1-X)(x2-X)/(x1-x0)(x2-x0)*y0+(x0-X)(x2-X)/(x0-x1)(x2-x1)*y1+(x1-X)(x0-X)/(x1-x2)(x0-x2)*y2令X=7代入方程得 Y=2.628572.Newton方法:设x0=4,y0=2,x1=9,y1=3,x2=16,y2=4建表4 29 3 0.216 4 0.14286 -0.00476f(x)=f(x0)+f[x0,x1](X-x0)+f[x0,x1,x2](X-x0)(X-x1)(X-x2)令X=7代入方程得Y=2.62857三.算法公式步骤:grange方法:通过公式写出算法并得出最后的值Y:for(b=0;b<m;b++)//完成公式f(Xn)外层嵌套循环f[b]=i//{double l=1;//保证每次跳出内层循环将L置1 不会将第一项的值带入下一项//for(a=0;a<m;a++)//完成公式f(Xn)内层嵌套循环f[a]=j//{if(a!=b)//完成定义i=1,i!=j//l=(f[a]-F)/(f[a]-f[b])*l;//完成(j-m)/(j-i)//la=l*g[b];//完成公式的F(X0)=f(X0)*Y0并累乘输出结果// }Y=la+Y;//累加x0y0+x1y1+...得最后结果//}2.Newton方法:先建表,通过二维数组的思想建表for(l=2;l<m+2;l++)//外层循环控制y阶数//{for(k=1;k<m+1;k++)//内层循环控制x个数//{a[k][l]=(a[k][l-1]-a[k-1][l-1])/(a[k][0]-a[k-l+1][0]);//完成f(x0,x1,...,xn)并存表//}}填表。
插值法 牛顿插值 cpp源代码 数值计算
数值分析实验报告(六) 一.实验名称:插值法二.实验目的:牛顿插值三.题目:(验证用)数据:1.00.76519771.3 0.62008601.6 0.45540221.9 0.28181862.2 0.1103623在1.5处的值。
四.程序:牛顿插值、拉格朗日插值附件:1-26liaoli_6_Newton_Interpolation.cpp#include<stdio.h>//Newton插值法void Newton_Interpolation(int n, double *_x, double **_F){f or(int i = 1; i <= n; i++){for(int j = 1; j <= i; j++){_F[i][j] = (_F[i][j-1] - _F[i-1][j-1]) / (_x[i] - _x[i-j]);}}}//输出结果void Printf_Order_n(int n, double *_x, double **_F){p rintf("i\tx[i]\t\tf...\n");f or(int i = 0; i <= n; i++){printf("%d\t%lf",i,_x[i]);for(int j = 0; j <= i; j++){printf("\t%lf",_F[i][j]);}printf("\n");}}//计算P(x)double Compute_P(int n, double _x, double *x, double **_F) {//_x为所求P(_x)d ouble _result = 0;d ouble _sum;f or(int i = 0;i <= n;i++){_sum = 1;for(int j = 0; j <= i-1;j++){_sum *= (_x - x[j]);}_result += (_F[i][i] * _sum);}r eturn _result;}void main(){i nt n;d ouble *x;d ouble **F;//输入数据p rintf("请输入n\t(以0开始,0--n!)\t\t:");s canf("%d",&n); //0开始F = new double*[n+1];x = new double[n+1];p rintf("请输入%d对数据x[i] f(x[i])\t:\n",n+1);f or(int i = 0; i <= n; i++){scanf("%lf",&x[i]);F[i] = new double[n+1];scanf("%lf",&F[i][0]);}//计算差商N ewton_Interpolation(n, x, F);//输出差商P rintf_Order_n(n, x, F);//计算P(_x)d ouble _x;p rintf("请输入x-----P(x)\t:");s canf("%lf",&_x);p rintf("P(x) = %lf\n",Compute_P(n, _x, x, F)); }五.运行结果:牛顿插值:六.体会:信计20100810010126 liaoli。
Newton插值多项式的C程序实例
附录(一)等距结点的Newton 插值法的程序算法步骤步骤 按照差分公式,求差分.然后利用Newton 前插公式或Newton 后插公式并把数值带入.即可以求得n 次多项式. 它在计算机上的应用步骤如下:步骤1 输入所要求的牛顿多项式的次数n ,步长h ,并依次输入1+n 个节点),(i i y x .步骤2 求得各界差分步骤3 代入牛顿插值公式,可计算得出结果(二)等距节点下Newton 插值的实例例题1 已知的值列表如下:近似计算325.1tan ,305.1tan . 解:采用Newton 向后插公式.为此,做差分表).2)(1(!30016.0)1(!20128.01690.00723.4)(3++++++=t t t t t t x p 将5.001.033.1325.1-=-=t 代入上式,得tan1.325≈P 3(1.325)=3.9861将5.201.033.1305.1-=-=t 上式中可以得到tan1.305≈P 3(1.305)=3.6733C程序如下:#include<stdio.h>void main(){float x[11],y[11][11],xx,temp,newton,t,h;int i,j,n;printf("Newton插值:\n请输入要运算的值:x=");scanf("%f",&xx);printf("请输入插值的次数(n<11):n=");scanf("%d",&n);printf("步长:\n请输入要运算的值:h=");scanf("%f",&h);printf("请输入%d组值:\n",n+1);for(i=0;i<n+1;i++){printf("x%d=",i);scanf("%f",&x[i]);printf("y%d=",i);scanf("%f",&y[0][i]);}t=(xx-x[n])/h;//计算各阶差分printf("--------------------------\n");printf("各阶差分分别为:\n");for(i=1;i<n+1;i++)for(j=i;j<n+1;j++){y[i][j]=(y[i-1][j]-y[i-1][j-1]); printf("%f\n",y[i][j]);}//利用牛顿插值公式,计算结果temp=1;newton=y[0][n];for(i=1;i<n+1;i++){temp=temp*((t+i-1)/i);newton=newton+y[i][n]*temp;}printf("求得的结果为:N(%.4f)=%9f\n",xx,newton);}运行结果如下所示:x0 0.2 0.4 0.6 0.8 1.0)(x f 1.0 0.818731 0.670320 0.548812 0.449329 0.367879 试利用插值公式求)3.0(f的值.解:差分表如下:分析首先我们可以通过程序求出差分表:从而,有p5(x)=1.0+(−0.181269)t+0.032858t(t−1)/2!+⋯+(−0.000191)t(t−1)(t−2)(t−3)(t−4)/5!将t=(0.3−0)/0.2代入上式,得)3.0(f≈p5(x)=0.740818利用C语言程序步骤如下:首先输入所求插值的次数5和步长0.2.然后输入各个节点,并输入所要求的点0.3既可以求出该点的函数值.#include<stdio.h>void main(){float x[11],y[11][11],xx,temp,newton,t,h;int i,j,n;printf("Newton插值:\n请输入要运算的值:x=");scanf("%f",&xx);printf("请输入插值的次数(n<11):n=");scanf("%d",&n);printf("步长:\n请输入要运算的值:h=");scanf("%f",&h);printf("请输入%d组值:\n",n+1);for(i=0;i<n+1;i++){printf("x%d=",i);scanf("%f",&x[i]);printf("y%d=",i);scanf("%f",&y[0][i]);}t=(xx-x[0])/h;printf("--------------------------\n");printf("各阶差分分别为:\n");for(i=1;i<n+1;i++)for(j=0;j<=n-i;j++){y[i][j]=(y[i-1][j+1]-y[i-1][j]);printf("%f\n",y[i][j]);}temp=1;newton=y[0][0];for(i=1;i<n+1;i++){temp=temp*((t-i+1)/i);newton=newton+y[i][0]*temp;}printf("求得的结果为:N(%.4f)=%9f\n",xx,newton);}运行结果:(三)总结由以上例子我们看到例1用了牛顿后插公式,例2用了牛顿前插公式,我们该怎样选取.这个经过验证得出,如果所要求的点较靠近节点x0,则采用前插公式;如果靠近x n,则采用牛顿后插公式.。
牛顿插值C语言
数值分析 实验三Newton插值多项式
数学与软件科学学院实验报告学期:至第学期年月日课程名称:___计算机数值方法_ 专业:信心与计算科学 08 级 6班实验编号:3 实验项目Newton插值多项式指导教师__张莉_姓名:田文晓学号:2008060632 实验成绩:一、实验目的及要求实验目的:掌握Newton插值多项式的算法,理解Newton插值多项式构造过程中基函数的继承特点,掌握差商表的计算特点。
实验要求:1. 给出Newton插值算法2. 用C语言实现算法二、实验内容1. 用下列插值节点数据,构造Newton插值多项式,并计算2. 用下列插值节点数据,构造一个三次Newton插值多项式,并计算f(1.2)的值。
三、实验步骤(该部分不够填写.请填写附页)步骤1:算法描述:输入n值,及(x_i,y_i),i=0,1,2,…n;记f(x_i)=y_i;For i=0,1,2…n计算差商f[x0,x1,x2,…x_k]=(f[x1,x2,…x_k]-f[x0,x1,x_k-1])/(x_k-x0) 其中 f[x_i]=f(x_i);对给定的x ,由N_n(x)=f(x0)+(x-x0)f[x0,x1]+(x-x0)(x-x1)f[x0,x1.x2]+...(x-x0)(x-x 1)(x-x2)...(x-x_n-1)f[x0,x1,...x_n]计算出N_n(x)的值输出N_n(x)的值步骤2:程序代码如下:#include<stdio.h>#define MAX_N 30typedef struct tagPOINT /*the structer of point */{double x;double y;}POINT;int main(){int n,i,j;POINT points[MAX_N+1];double tmp,newton=0;double diff[MAX_N+1];double x;clrscr();printf("\nInput n value :"); /*the number of the points inserted*/scanf("%d",&n);if(n>MAX_N){printf("The input n is larger than MAX_N,please redefine the MAX_N.\n");return 1;}if(n<=0){printf("Please input a number between 1 and %d.\n",MAX_N);return 1;}printf("Now input the (x_i,y_i),i=0,...%d:\n",n);for(i=0;i<=n;i++)scanf("%lf %lf",&points[i].x,&points[i].y);printf("Now input the x value:"); /*the value of x*/scanf("%lf",&x);for(i=0;i<=n;i++) diff[i]=points[i].y;for(i=0;i<n;i++){for(j=n;j>i;j--){diff[j]=(diff[j]-diff[j-1])/(points[j].x-points[j-1-i].x); }}tmp=1;newton=diff[0];for(i=0;i<n;i++){tmp=tmp*(x-points[i].x);newton=newton+tmp*diff[i+1];}printf("newton(%f)=%f\n",x,newton);return 0;}四,实验结果与分析:当输入x=0.9时,利用牛顿二次插值得到结果如下:Input n value :2Now input the (x_i,y_i),i=0,...2:0 11 22 19Now input the x value:0.9newton(0.900000)=1.180000当输入x=0.9时,利用牛顿三次插值得到结果如下:Input n value :3Now input the (x_i,y_i),i=0,...3:-2 170 12 191 2Now input the x value:0.9newton(0.900000)=1.303750输入当x=1.2时,得到结果如下:Input n value :3Now input the (x_i,y_i),i=0,...3:-1.00 3.002.00 5.003.00 7.004.005.00Now input the x value:1.2newton(1.200000)=2.401600注:实验成绩等级分为(90-100分)优,(80-89分)良,(70-79分)中,(60-69分)及格,(59分)不及格。
插值运算newton算法c++
class
public
std::doublestd::double
//初始化差商表
int
:double0.0
//计算差商表
forint0
0
forint1
forint
111
//计算插值多项式的值
doubledouble
double00
double1.0
forint1
牛顿插值法(Newton's Interpolation)是一种插值多项式的方法,通常用于通过已知数据点推导出一个插值多项式。这个插值多项式可以用于在给定数据点之间进行估计。
以下是一个使用C++实现牛顿插值的简单示例。这里使用的是差商(divided differences)的概念:
#include<iostream>
1
return
private
std::double
std::double
std::std::double
int
//示例数据
std::double1.02.03.04.0
std::double2.03.05.08.0
//创建牛顿插值对象
//在新的x值上进行插值
double2.5
double
std::"Interpolated value at x = "": "std::
return0
此示例演示了如何使用牛顿插值法进行插值。你可以根据需要更改示例数据。在NewtonInterpolation类中,interpolate方法接受一个x值,返回插值多项式在该点的估计值。
牛顿插值法的C语言实现
牛顿插值法的C 语言实现摘要:拉格朗日插值法具有明显的对称性,公式中的每一项与所有的插值节点有关。
因此,如果需要增加一个插值节点,则拉格朗日插值公式中的每一项都要改变,在有的应用中就显得不太方便。
因此,可以利用另外一种差值方法来弥补这种缺陷,就牛顿插值法。
本文通过对牛顿插值法的数学分析,主要给出其C 语言实现方法。
关键字:差商 差分 C 语言算法1差商及其牛顿插值公式1.1 差商及其主要性质定义 若已知函数()f x 在点(0,1,2,,)i x i n =⋅⋅⋅处的函数值()i f x 。
则称:00[]()f x f x =为函数()f x 在点0x 的0阶差商; 010101[][][,]f x f x f x x x x -=-为函数()f x 过点01,x x 的1阶差商;010201212[,][,][,,]f x x f x x f x x x x x -=-为函数()f x 过点012,,x x x 的2阶差商;以此类推,一般地称012101201211[,,,,][,,,,][,,,,,]k k k k k k k kf x x x x f x x x x f x x x x x x x -----⋅⋅⋅-⋅⋅⋅⋅⋅⋅=-为函数()f x 过点01,,x x ,⋅⋅⋅k x 的k 阶差商。
性质1 阶差商表示为函数值01(),(),,()k f x f x f x ⋅⋅⋅的线性组合。
即0120011()[,,,,]=()()()()kj k j j j j j j j k f x f x x x x x x x x x x x x =-+⋅⋅⋅-⋅⋅⋅--⋅⋅⋅-∑0()()kj kj ji i i jf x xx ==≠=-∑∏性质2 若函数()f x 在包含节点的区间[,]a b 上存在k 阶导数,则k 阶差商与导数的关系为()01()[,,,],[,]!k k f f x x x a b k ξξ⋅⋅⋅=∈ 1.2 牛顿插值公式通过1n +个互异点上的次数不超过n 的插值多项式()n P x 可以表示如下形式:0010101201()[][,]()[,,]()()n P x f x f x x x x f x x x x x x x =+-+--+⋅⋅⋅0101[,,,]()()n n f x x x x x x x -+⋅⋅⋅-⋅⋅⋅-这种形式的插值多项式称为牛顿插值多项式,一般记为0010101201()[][,]()[,,]()()n N x f x f x x x x f x x x x x x x =+-+--+⋅⋅⋅0101[,,,]()()n n f x x x x x x x -+⋅⋅⋅-⋅⋅⋅-由牛顿插值多项式可以看出,当增加一个插值点时,当前已有的各项不变,只需要在后面增加一项即可。
数值计算方法实验报告--newton插值多项式
数值计算方法实验报告实验报告题目:newton插值多项式实验要求用mat1ab解析Newton插值多项式的程序二、实验分析(包括数学原理,小组分析讨论后确定实验方案和实现思路)根据经过n+1个不同的差值点x1,x2,…,x(n+1),构造牛顿插值公式∕V(x)=y[x1,x2](x-Λ1)+∕[x1,x2,x3](x-Jc1)(x-x2)+∙∙∙+∕[x1,Λ2∕∙∙xn+1](x-x1)(x-x 2)∙∙∙(x-xn)三、实脸步骤(过程)(包括程序及上机的实现的结果)function[p2,z]=newton(x,y,t)n=1ength(x);chaS(1)=y(1);for i=2:nx1=x;y1=y;x1(i+1:n)=[];y1(i+1:n)=[];n1=1ength(x1);s1=0;for j=1:n1t1=1;for k=1:n1if k==j continue;e1set1=t1*(x1(j)-x1(k));ehdehds1=s1+y1(j)∕t1;end chaS(i)=s1;ehd b(1,:)=[zeros(1,n-1)chaS(1)];c1=ce11(1,n-1);for i=2:nυ1=1;for j=1:i-1u1=conv(u1,[1-x(j)]);c1{i-1}=u1;end c1{i-1}chaS(i)*c1{i-1);b(i,:)=[zeros(1,n-i)z c1{i-1}];end四、总结(包括实脸过程遇到的情况等,组长总结组员在整个过程的参与情况)实验过程中大家都积极参与,搞明白了牛顿插值多项式的程序。
有不明白的地方,也通过询问同班学霸,或是网页查询得到了解决。
matlab牛顿插值法例题与程序
M A T L A B牛顿插值法例题与程序(总4页)本页仅作为文档封面,使用时可以删除This document is for reference only-rar21year.March题目一:多项式插值某气象观测站在8:00(AM )开始每隔10分钟对天气作如下观测,用三次多项式插值函数(Newton )逼近如下曲线,插值节点数据如上表,并求出9点30分该地区的温度(x=10)。
二、数学原理假设有n+1个不同的节点及函数在节点上的值(x 0,y 0),……(x n ,y n ),插值多项式有如下形式:)())(()()()(n 10n 102010n x -x )(x -x x -x x P x x x x x x -⋯⋯-+⋯⋯+-++=αααα (1)其中系数i α(i=0,1,2……n )为特定系数,可由插值样条i i n y x P =)((i=0,1,2……n )确定。
根据均差的定义,把x 看成[a,b]上的一点,可得f(x)= f (0x )+f[10x x ,](0x -x ) f[x, 0x ]= f[10x x ,]+f[x,10x x ,] (1x -x )……f[x, 0x ,…x 1-n ]= f[x, 0x ,…x n ]+ f[x, 0x ,…x n ](x-x n )综合以上式子,把后一式代入前一式,可得到:f(x)= f[0x ]+f[10x x ,](0x -x )+ f[210x x x ,,](0x -x )(1x -x )+…+ f[x, 0x ,…x n ](0x -x )…(x-x 1-n )+ f[x, 0x ,…x n ,x ])(x 1n +ω= N n (x )+)(x n R 其中N n (x )= f[0x ]+f[10x x ,](0x -x )+ f[210x x x ,,](0x -x )(1x -x )+ …+ f[x, 0x ,…x n ](0x -x )…(x-x 1-n ) (2))(x n R = f(x)- N n (x )= f[x, 0x ,…x n ,x ])(x 1n +ω (3) )(x 1n +ω=(0x -x )…(x-x n ) Newton 插值的系数i α(i=0,1,2……n )可以用差商表示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
附录
(一)等距结点的Newton 插值法的程序算法步骤
步骤 按照差分公式,求差分.然后利用Newton 前插公式或Newton 后插公式并把数值带入.即可以求得n 次多项式. 它在计算机上的应用步骤如下:
步骤1 输入所要求的牛顿多项式的次数n ,步长h ,并依次输入1+n 个节点
),(i i y x .
步骤2 求得各界差分
步骤3 代入牛顿插值公式,可计算得出结果
(二)等距节点下Newton 插值的实例
例题1 已知的值列表如下:
近似计算325.1tan ,305.1tan . 解:
采用Newton 向后插公式.为此,做差分表
).2)(1(!
30016
.0)1(!20128.01690.00723.4)(3+++++
+=t t t t t t x p 将5.001
.033
.1325.1-=-=
t 代入上式,得
tan1.325≈P 3(1.325)=3.9861
将5.201
.033
.1305.1-=-=t 上式中可以得到
tan1.305≈P 3(1.305)=3.6733
C程序如下:
#include<stdio.h>
void main()
{
float x[11],y[11][11],xx,temp,newton,t,h;
int i,j,n;
printf("Newton插值:\n请输入要运算的值:x=");
scanf("%f",&xx);
printf("请输入插值的次数(n<11):n=");
scanf("%d",&n);
printf("步长:\n请输入要运算的值:h=");
scanf("%f",&h);
printf("请输入%d组值:\n",n+1);
for(i=0;i<n+1;i++)
{
printf("x%d=",i);
scanf("%f",&x[i]);
printf("y%d=",i);
scanf("%f",&y[0][i]);
}
t=(xx-x[n])/h;
//计算各阶差分
printf("--------------------------\n");
printf("各阶差分分别为:\n");
for(i=1;i<n+1;i++)
for(j=i;j<n+1;j++)
{
y[i][j]=(y[i-1][j]-y[i-1][j-1]); printf("%f\n",y[i][j]);
}
//利用牛顿插值公式,计算结果
temp=1;
newton=y[0][n];
for(i=1;i<n+1;i++)
{
temp=temp*((t+i-1)/i);
newton=newton+y[i][n]*temp;
}
printf("求得的结果为:N(%.4f)=%9f\n",xx,newton);
}
运行结果如下所示:
x0 0.2 0.4 0.6 0.8 1.0
)(x f 1.0 0.818731 0.670320 0.548812 0.449329 0.367879 试利用插值公式求)3.0(f的值.
解:
差分表如下:
分析首先我们可以通过程序求出差分表:
从而,有
p5(x)=1.0+(−0.181269)t+0.032858t(t−1)/2!+⋯+(−0.000191)t(t
−1)(t−2)(t−3)(t−4)/5!
将t=(0.3−0)/0.2代入上式,得
)3.0(f≈p5(x)=0.740818
利用C语言程序步骤如下:
首先输入所求插值的次数5和步长0.2.然后输入各个节点,并输入所要求的点0.3既可以求出该点的函数值.
#include<stdio.h>
void main()
{
float x[11],y[11][11],xx,temp,newton,t,h;
int i,j,n;
printf("Newton插值:\n请输入要运算的值:x=");
scanf("%f",&xx);
printf("请输入插值的次数(n<11):n=");
scanf("%d",&n);
printf("步长:\n请输入要运算的值:h=");
scanf("%f",&h);
printf("请输入%d组值:\n",n+1);
for(i=0;i<n+1;i++)
{
printf("x%d=",i);
scanf("%f",&x[i]);
printf("y%d=",i);
scanf("%f",&y[0][i]);
}
t=(xx-x[0])/h;
printf("--------------------------\n");
printf("各阶差分分别为:\n");
for(i=1;i<n+1;i++)
for(j=0;j<=n-i;j++)
{
y[i][j]=(y[i-1][j+1]-y[i-1][j]);
printf("%f\n",y[i][j]);
}
temp=1;
newton=y[0][0];
for(i=1;i<n+1;i++)
{
temp=temp*((t-i+1)/i);
newton=newton+y[i][0]*temp;
}
printf("求得的结果为:N(%.4f)=%9f\n",xx,newton);
}
运行结果:
(三)总结
由以上例子我们看到例1用了牛顿后插公式,例2用了牛顿前插公式,我们该怎样选取.这个经过验证得出,如果所要求的点较靠近节点x0,则采用前插公式;如果靠近x n,则采用牛顿后插公式.。