二次插值

二次插值,第1张

已知(xi,yi),i=0,1,2是三个互异点,二次插值就是求过这三个已知点的抛物线方程,即构造一个二次代数多项式L2(x):

地球物理数据处理基础

使其满足:

地球物理数据处理基础

显然,满足条件(6-10)的插值多项式函数(6-9)可由下面的方程组确定:

地球物理数据处理基础

此方程中a0,a1,a2为未知数,写成矩阵形式为

地球物理数据处理基础

于是,只要从式(6-12)中求解出a0,a1,a2,则插值多项式L2(x)便唯一确定。

但是,通过解方程组的办法来求取插值多项式通常是比较麻烦的,尤其是当插值节点增多时,计算量大。因此,我们有必要寻找构造插值函数的其他途径,下面我们介绍构造二次插值函数的Lagrange差值法。

根据插值问题的唯一性,参照线性插值函数形式,令

地球物理数据处理基础

li(x)(i=0,1,2)应该具有相似的形式,由于插值函数L2(x)是二次多项式,那么li(x)(i=0,1,2)也应该是二次多项式形式。不妨令

地球物理数据处理基础

由插值条件式(6-10)得

地球物理数据处理基础

于是得到二次插值函数:

地球物理数据处理基础

其中,li(x)(i=0,1,2)表示如下:

地球物理数据处理基础

li(x)称为二次插值的基函数或形函数。li(x)满足

地球物理数据处理基础

同样,对于n+1个已知观测点,我们仍可以先将观测区间[x0,xn]划分为n/2(n为偶数)段,在相邻的三个观测点构成的子区间[xi-1,xi+1](i=1,3,…,n-1)进行分段二次插值。

不难得到插值函数

地球物理数据处理基础

其中:

地球物理数据处理基础

因此,对于区间[xi-1,xi+1]内的任意点x,只要求出相应的lj(x),即可根据式(6-18)计算出x处的近似值。

楼主的程序基本没错,就是在t = t .* (xx - x(1,i))./(x(1,j) - x(1,i))这一行里xx前面多了个(

以下程序正确:(要是只做2次插值的话令n=3就行了)

function yy = Nlagrange(x,y,xx)

yy = 0

j = 1

n = 3

while j <= n

t = 1

for i = 1:n

if i ~= j

t = t .* (xx - x(1,i))./(x(1,j) - x(1,i))

end

end

yy = yy + t .* y(1,j)

j = j + 1

end

end

另外输入的变量y多个逗号就不吐槽了,但采用大括号很令人费解,一般向量都是用中括号的。

像这样在Command Window输入:

x = [4 9 16]

y = [2 3 4]

xx = 7

yy = Nlagrange(x,y,xx)

结果:

yy =

2.6286

我的程序是牛顿插值和拉格朗日插值合起来,你自己看下,用的是C++

#include <iostream>

#include <iomanip>

#include <stdlib.h>

using namespace std

#define N 100

void lagrange()

{

int n,k,m,q=1

float x[N],y[N],xx,yyy1,yyy2,yy1,yy2,yy3

cout<<"请输入X的个数:"

cin>>n

for(k=0k<=n-1k++)

{

cout<<"请输入X"<<k<<"的值:"

cin>>x[k]

cout<<"请输入Y"<<k<<"的值:"

cin>>y[k]

}

system("cls")

cout<<"则Xi与Yi表格如下:"<<endl

cout<<"Xi"<<" "for(k=0k<=n-1k++)cout<<setiosflags(ios::left)<<setw(10)<<x[k]

cout<<endl

cout<<"Yi"<<" "for(k=0k<=n-1k++)cout<<setiosflags(ios::left)<<setw(10)<<y[k]

cout<<endl

while(q)

{

cout<<"请输入所求x的值:"

cin>>xx

while(xx>x[k-1]||xx<x[0])

{

cout<<"输入错误,请重新输入:"

cin>>xx

}

for(k=0k<=n-1k++)

{

if(xx<x[k])

{

m=k-1

k=n-1

}

}

yyy1=y[m]*((xx-x[m+1])/(x[m]-x[m+1]))+y[m+1]*((xx-x[m])/(x[m+1]-x[m]))

cout<<"则拉格朗日分段线性插值为:"<<yyy1<<endl

for(k=0k<=n-1k++)

{

if(xx<x[k])

{

m=k-1

k=n-1

}

}

if((xx-x[m])>(x[m+1]-xx))m=m+1

else m=m

yy1=y[m-1]*((xx-x[m])*(xx-x[m+1]))/((x[m-1]-x[m])*(x[m-1]-x[m+1]))

yy2=y[m]*((xx-x[m-1])*(xx-x[m+1]))/((x[m]-x[m-1])*(x[m]-x[m+1]))

yy3=y[m+1]*((xx-x[m-1])*(xx-x[m]))/((x[m+1]-x[m-1])*(x[m+1]-x[m]))

yyy2=yy1+yy2+yy3

cout<<"则拉格朗日分段二次插值为:"<<yyy2<<endl

cout<<"是否输入其余要求x的值[是(1),否(0)]:"

cin>>q

}

system("cls")

}

void main()

{

lagrange()

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7801896.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存