分段线性插值法文档格式.docx
《分段线性插值法文档格式.docx》由会员分享,可在线阅读,更多相关《分段线性插值法文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
,然后再作它们的线性组合。
分段线性插值基函数的特点是在对应的插值节点上函数值取1,其它节点上函数值取0。
插值基函数如下:
设在节点a≤x0<
x1<
…≤b=f(xi),(i=0,1,2,…,n)求折线函数L(x)满足:
(1)L(x)∈C[a,b]
(2)L(x[i]=y[i])
(3)L(x)在每个小区间(x[i],x[i+1])上是线性
插值函数¢(x)叫做区间[a,b]上对数据(x[j],y[j])(j=0,1,2,…,n)的分段区间函数。
利用一介拉格朗日函数,直接得到线性插值函数为:
L(x0)=(x-x[1])/x[0]-x[1];
(x[0]≤x≤x[1])
L(x0)=0(x[1]≤x≤x[n])
分段线性方程的表达式:
¢(x)=∑(j=0,..,n)y[j]*L[j](x);
3、实验代码:
//LDlg.cpp:
implementationfile
//
#include"
stdafx.h"
L.h"
LDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
IDD)
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
voidCAboutDlg:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CLDlgdialog
CLDlg:
CLDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CLDlg:
IDD,pParent)
//{{AFX_DATA_INIT(CLDlg)
//NOTE:
theClassWizardwilladdmemberinitializationhere
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
voidCLDlg:
//{{AFX_DATA_MAP(CLDlg)
theClassWizardwilladdDDXandDDVcallshere
BEGIN_MESSAGE_MAP(CLDlg,CDialog)
//{{AFX_MSG_MAP(CLDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_LARGRI,OnLargri)
ON_BN_CLICKED(IDC_BUTTON2,OnButton2)
ON_BN_CLICKED(IDC_HERMITE,OnHermite)
//CLDlgmessagehandlers
BOOLCLDlg:
OnInitDialog()
OnInitDialog();
//Add"
About..."
menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&
0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<
0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->
AppendMenu(MF_SEPARATOR);
AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'
smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);
//Setbigicon
SetIcon(m_hIcon,FALSE);
//Setsmallicon
//TODO:
Addextrainitializationhere
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
OnSysCommand(UINTnID,LPARAMlParam)
if((nID&
0xFFF0)==IDM_ABOUTBOX)
CAboutDlgdlgAbout;
dlgAbout.DoModal();
else
CDialog:
OnSysCommand(nID,lParam);
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
OnPaint()
if(IsIconic())
CPaintDCdc(this);
//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&
rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
OnPaint();
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORCLDlg:
OnQueryDragIcon()
return(HCURSOR)m_hIcon;
OnOK()
intx00=300,y00=350,i,j;
doublex;
CDC*pDC=GetDC();
pDC->
SetMapMode(MM_LOMETRIC);
SetViewportOrg(x00,y00);
//画坐标轴与原函数
for(i=-700;
i<
=700;
i++)
pDC->
SetPixel(i,0,RGB(0,0,0));
SetPixel(0,i,RGB(0,0,0));
for(x=-1;
x<
=1;
x+=0.001)
doublej=400.0/(1+25*x*x);
SetPixel(x*500,j,RGB(255,0,0));
TextOut(-30,-10,"
0"
);
TextOut(-30,430,"
1"
TextOut(490,-10,"
TextOut(-490,-10,"
-1"
MoveTo(-10,680);
//x箭头
LineTo(0,700);
MoveTo(0,700);
LineTo(10,680);
MoveTo(680,10);
//y箭头
LineTo(700,0);
MoveTo(700,0);
LineTo(680,-10);
TextOut(-30,700,"
y"
TextOut(700,-10,"
x"
OnLargri()
//画坐标轴
doubleyx[]={-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1};
//拉格朗日差值的函数
doubleyy[12],lx[12],ly[12];
doublel_fenzi[12],l_fenmu[12];
doublel_x,l_y;
for(i=0;
=10;
yy[i]=1.0/(1+25*yx[i]*yx[i]);
l_fenmu[i]=1.0;
for(j=0;
j<
j++)
if(i!
=j)
l_fenmu[i]=l_fenmu[i]*(yx[i]-yx[j]);
doubleqq,pp;
for(qq=-1;
qq<
qq+=0.0003)
for(i=0;
l_fenzi[i]=1.0;
for(j=0;
{
if(i!
l_fenzi[i]=l_fenzi[i]*(qq-yx[j]);
}
pp=0;
=11;
pp=pp+1.0/(1+25*yx[i]*yx[i])*l_fenzi[i]/l_fenmu[i];
SetPixel(qq*500,pp*390+5,RGB(132,112,225));
OnButton2()
doubleyy[14];
//线性分段差值的图像
CPenpen;
CPen*oldpen;
pen.CreatePen(PS_SOLID,5,RGB(0,0,0));
oldpen=pDC->
SelectObject(&
pen);
10;
MoveTo(yx[i]*480,yy[i]*400);
LineTo(yx[i+1]*480,yy[i+1]*400);
OnHermite()
doubleyy[12];
//分段三次Hermite差值的函数
doublex0,x1,yd1,yd0,y1,y0;
x0=yx[i],x1=yx[i+1];
y0=1.0/(1+25*x0*x0);
y1=1.0/(1+25*x1*x1);
yd0=-(50*x0)*1.0/((1+25*x0*x0)*(1+25*x0*x0));
yd1=-(50*x1)*1.0/((1+25*x1*x1)*(1+25*x1*x1));
for(doubleqq=x0;
x1;
qq+=0.005)
doublepp=y0*(1+2*(qq-x0)/(x1-x0))*(qq-x1)/(x0-x1)*(qq-x1)/(x0-x1)
+y1*(1+2*(qq-x1)/(x0-x1))*(qq-x0)/(x1-x0)*(qq-x0)/(x1-x0)
+yd0*(qq-x0)*(qq-x1)/(x0-x1)*(qq-x1)/(x0-x1)
+yd1*(qq-x1)*(qq-x0)/(x1-x0)*(qq-x0)/(x1-x0);
pDC->
SetPixel(qq*500,pp*400,RGB(225,185,15));
4.实验截图
5.实验结果分析:
分析:
分段线性插值的方法克服了Lagrange插值法当节点不断加密时,构造的插值多项式的次数不断升高,高次多项式虽然是连续的,但是不一定都收敛到相应的被插函数而产生Runge现象。
分段线性插值因为在每一段小区间上都是线性插值而极大地降低了插值多项式的次数,从几何图形上可以看出,当节点取得较多时插值函数的逼近效果还是很好的,但是所求函数是一条以型值点为顶点的折线,这也表现出了它的缺点就是所求得的插值函数的光滑性较差,这就要求一种更好的方法来克服这一缺点了。