数值分析拉格朗日实验题MATLAB程序,数值分析实验报告(拉格朗日插值牛顿插值最小二乘法)...

实验1

拉格朗日插值法

一、方法原理

n次拉格朗日插值多项式为:Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)

n=1时,称为线性插值,L1(x)=y0(x-x1)/(x0-x1)+

y1(x-x0)/(x1-x0)=y0+(y1-x0)(x-x0)/(x1-x0)

n=2时,称为二次插值或抛物线插值,精度相对高些

L2(x)=y0(x-x1)(x-x2)/(x0-x1)/(x0-x2)+y1(x-x0)(x-x2)/(x1-x0)/(x1-x2)+y2(x-x0)(x-x1)/(x2-x0)/(x2-x1)

二、主要思路

使用线性方程组求系数构造插值公式相对复杂,可改用构造方法来插值。

对节点xi(i=0,1,…,n)中任一点xk(0<=k<=n)作一n

次多项式lk(xk),使它在该点上取值为1,而在其余点xi(i=0,1,…,k-1,k+1,…,n)上为0,则插值多项式为Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)

上式表明:n

个点xi(i=0,1,…,k-1,k+1,…,n)都是lk(x)的零点。可求得lk

三.计算方法及过程:1.输入节点的个数n

2.输入各个节点的横纵坐标

3.输入插值点

4.调用函数,返回z

函数语句与形参说明

程序源代码如下:

形参与函数类型

参数意义

int n

节点的个数

double x[n](double *x)

存放n个节点的值

double y[n](double *y)

存放n个节点相对应的函数值

double p

指定插值点的值

double fun()

函数返回一个双精度实型函数值,即插值点p处的近似函数值

#include

#include

using namespace std;

#define N

100

double fun(double *x,double *y, int n,double

p);

void main()

{int i,n;

cout<

cin>>n;

double x[N], y[N],p;

cout<

xiangliang x= "<

for(i=0;i>x[i];

cout<

xiangliang y= "<

for(i=0;i>y[i];

cout<

LagelangrichazhiJieDian p=

"<

cin>>p;

cout<

"<

system("pause") ;}

double fun(double x[],double y[], int n,double

p)

{double z=0,s=1.0;

int k=0,i=0;

double L[N];

while(k

{ if(k==0)

{

for(i=1;i

L[0]=s*y[0];

k=k+1;}

else

{s=1.0;

for(i=0;i<=k-1;i++)s=s*((p-x[i])/(x[k]-x[i]));

for(i=k+1;i

s=s*((p-x[i])/(x[k]-x[i]));

L[k]=s*y[k];

k++;}

}

for(i=0;i

return z;

}

四.运行结果测试:

五.实验分析

n=2时,为一次插值,即线性插值

n=3时,为二次插值,即抛物线插值

n=1,此时只有一个节点,插值点的值就是该节点的函数值

n<1时,结果都是返回0的;这里做了n=0和n=-7两种情况

3

常用的是线性插值和抛物线插值,显然,抛物线精度相对高些

n次插值多项式Ln(x)通常是次数为n的多项式,特殊情况可能次数小于n.例如:通过三点的二次插值多项式L2(x),如果三点共线,则y=L2(x)就是一条直线,而不是抛物线,这时L2(x)是一次式。

拟合曲线光顺性差

实验2

牛顿插值法

一、方法原理及基本思路

在拉格朗日插值方法中,若增加一个节点数据,其插值的多项式需重新计算。现构造一个插值多项式Nn(x),只需对Nn-1(x)作简单修正(如增加某项)即可得到,这样计算方便。

利用牛顿插值公式,当增加一个节点时,只需在后面多计算一项,而前面的计算仍有用;另一方面Nn(x)的各项系数恰好又是各阶差商,而各阶差商可用差商公式来计算。

由线性代数知,对任何一个不高n次的多项式P(x)=b0+b1x+b2x2+…+bnxn (幂基) ①

也可将其写成P(x)=a0+a1(x-x0)+a2(x-x0)

(x-x1)+…+an(x-x0)

…(x-xn-1)

其中ai为系数,xi为给定节点,可由①求出ai 一般情况下,牛顿插值多项式Nn(x)可写成:

Nn(x)=

a0+a1(x-x0)+a2(x-x0)

(x-x1)+…+an(x-x0)

…(x-xn-1))

只需求出系数ai,即可得到插值多项式。

二、计算方法及过程

1.先后输入节点个数n和节点的横纵坐标,插值点的横坐标,最后输入精度e

2. 用do-while循环语句得到跳出循环时k的值

3.将k值与n-1进行比较,若在达到精度时k

函数语句与形参说明

形参与函数类型

参数意义

int n

节点的个数

float x[MAX]

存放n个节点的值(从小到大)

Float y[MAX];

存放n个节点相对应的函数值

float x0,y0

指定插值点的横纵坐标

float e

精度

程序源代码如下:

#include

#include

using namespace std;

#define MAX

100

void main()

{ float x[MAX],y[MAX];

float

x0,y0,e,N1;

float

N0=0;

int i,k,n;

cout<

cin>>n;

cout<

for(i=0;i

cin>>x[i];

cout<

for(i=0;i

cin>>y[i];

cout<

cin>>x0;

cout<

cin>>e;

y0=1; N1=y[0]; k=0;

do { k++;

N0=N1;

y0=y0*(x0-x[k-1]);

for(i=0;i

y[k]=(y[k]-y[i])/(x[k]-x[i]);

N1=N0+y0*y[k];

} while (fabs(N1-N0) > e

&& k

if (k==(n-1))

cout<

if

(k

cout<

system("pause");

}

三.运行结果测试:

题一:已知f(x)=sh(x)的函数表如下:计算f(0.23)的近似值

xi

0

0.20

0.30

0.50

Sh(xi)

0

0.20134

0.30452

0.52110

题二:已知根号100等于10,根号121等于11,根号144等于12; 用二次插值和三次插值计算根号115的近似值。

四.实验分析

显然,题二中当n=2,n=3时,k的值没有在n-1前满足各自的精度要求,所以计算失败

从题一中可以看出,插值点的个数、精度、插值点的选择都会影响实验的结果;

我们通常会选择与插值点最接近的节点,可以提高精度;

在可以计算出结果的情况下,插值点越多,结果越精确。

实验3

最小二乘法求拟合曲线

一、方法原理及思路

已知数据对(xj, yj)(j=1,2,…,n),求多项式

为最小,这就是一个最小二乘问题。

二、计算方法及过程:

1. 先后输入数据的对数m,近似多项式的最高次数n及各个数据的横纵坐标

2. 用for循环语句得到线性方程组Ga=d

3. 用高斯列主元消去法得到的解即为近似多项式的系数ai(i=0,1,…,n)

函数语句与形参说明

形参与函数类型

参数意义

int m

数据的对数,即坐标的个数

int n

近似多项式的最高次数

float x[MAX]

存放m个横坐标的值(从小到大)

Float y[MAX];

存放m个纵坐标的值(与相应的横坐标对应)

Float a[ MAX +1],

近似多项式的系数

float G[ MAX +1][ MAX +1]

法方程的系数矩阵,且为对称的,正定的

float s[2 * MAX +1]

系数矩阵G中的元素

Float b[ MAX +1];

法方程中等号右边的列向量

程序原代码如下

#include

#include

#define MAX 100

using namespace std;

int

main()

{ float

t;

int

i,j,k,r,m,n;

cout<

cin>>m;

cout<

cin>>n;

float y[

MAX],x[ MAX ],x1[ MAX ],a[ MAX +1],G[ MAX +1][ MAX +1], s[2* MAX

+1],b[ MAX +1];

cout<

for

(i=0;i>x[i];

cout<

for

(i=0;i>y[i];

s[0]=m;

b[0]=0.0;

for(j=0;j

{b[0]=b[0]+y[j];

x1[j]=1.0;

}

for

(i=1;i<=n;i++)

{b[i]=0.0; s[2*i-1]=0.0;s[2*i]=0.0;

for(j=0;j

{x1[j]=x1[j]*x[j];

b[i]=b[i]+x1[j]*y[j];

s[2*i-1]=s[2*i-1]+

x1[j]*x1[j]/x[j];

s[2*i]=s[2*i]+x1[j]*x1[j];}

}

for(i=0;i<=n;i++)

{ for(j=0;j<=n;j++)

G[i][j]=s[i+j]; }

for(k=0;k

{ t=abs(G[k][k]);

r=k;

for(i=k+1;i<=n;i++)

{

if(t

{ t=G[i][k];

r=i; }

}

if(r>k)//行交换

{ for(j=k;j<=n;j++)

{ t=G[k][j];

G[k][j]=G[r][j];

G[r][j]=t; }

t=b[k]; b[k]=b[r];

b[r]=t; }

for(i=k+1;i<=n;i++)//消元

{

t=G[i][k]/G[k][k];

for(j=k+1;j<=n;j++)

G[i][j]=G[i][j]-t*G[k][j];

b[i]=b[i]-t*b[k];

}

}

a[n]=b[n]/G[n][n];//回代

for(k=1;k<=n;k++)

{ i=n-k; a[i]=b[i];

for(j=i+1;j<=n;j++)a[i]=a[i]-G[i][j]*a[j];

a[i]=a[i]/G[i][i]; }

cout<

//输出答案

for(i=0;i<=n;i++)cout<

system("pause");

}

三:运行结果测试:

四.实验分析

由于曲线拟合的最小二乘法一般是经过描点,确定其近似多项式的形式,但由于给定的点有误差,所以拟合曲线的数学模型并不是一开始就能选的好的,往往要通过分析确定若干模型后,再经过实际计算,才能选到较好的模型。

对我的博文感兴趣的话,关注我哦~~~~

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值