(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"
#include"L.h"
#include"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
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCLDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLDlg)
//NOTE:
theClassWizardwilladdDDXandDDVcallshere
//}}AFX_DATA_MAP
}
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)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CLDlgmessagehandlers
BOOLCLDlg:
:
OnInitDialog()
{
CDialog:
:
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);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
//TODO:
Addextrainitializationhere
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCLDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
voidCLDlg:
:
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);
}
else
{
CDialog:
:
OnPaint();
}
}
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORCLDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidCLDlg:
:
OnOK()
{
intx00=300,y00=350,i,j;
doublex;
CDC*pDC=GetDC();
pDC->SetMapMode(MM_LOMETRIC);
pDC->SetViewportOrg(x00,y00);
//画坐标轴与原函数
for(i=-700;i<=700;i++)
{
pDC->SetPixel(i,0,RGB(0,0,0));
pDC->SetPixel(0,i,RGB(0,0,0));
}
for(x=-1;x<=1;x+=0.001)
{
doublej=400.0/(1+25*x*x);
pDC->SetPixel(x*500,j,RGB(255,0,0));
}
pDC->TextOut(-30,-10,"0");
pDC->TextOut(-30,430,"1");
pDC->TextOut(490,-10,"1");
pDC->TextOut(-490,-10,"-1");
pDC->MoveTo(-10,680);//x箭头
pDC->LineTo(0,700);
pDC->MoveTo(0,700);
pDC->LineTo(10,680);
pDC->MoveTo(680,10);//y箭头
pDC->LineTo(700,0);
pDC->MoveTo(700,0);
pDC->LineTo(680,-10);
pDC->TextOut(-30,700,"y");
pDC->TextOut(700,-10,"x");
}
voidCLDlg:
:
OnLargri()
{
intx00=300,y00=350,i,j;
doublex;
CDC*pDC=GetDC();
pDC->SetMapMode(MM_LOMETRIC);
pDC->SetViewportOrg(x00,y00);
//画坐标轴
for(i=-700;i<=700;i++)
{
pDC->SetPixel(i,0,RGB(0,0,0));
pDC->SetPixel(0,i,RGB(0,0,0));
}
doubleyx[]={-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1};
pDC->TextOut(-30,-10,"0");
pDC->TextOut(-30,430,"1");
pDC->TextOut(490,-10,"1");
pDC->TextOut(-490,-10,"-1");
pDC->MoveTo(-10,680);//x箭头
pDC->LineTo(0,700);
pDC->MoveTo(0,700);
pDC->LineTo(10,680);
pDC->MoveTo(680,10);//y箭头
pDC->LineTo(700,0);
pDC->MoveTo(700,0);
pDC->LineTo(680,-10);
pDC->TextOut(-30,700,"y");
pDC->TextOut(700,-10,"x");
//拉格朗日差值的函数
doubleyy[12],lx[12],ly[12];
doublel_fenzi[12],l_fenmu[12];
doublel_x,l_y;
for(i=0;i<=10;i++)
{
yy[i]=1.0/(1+25*yx[i]*yx[i]);
}
for(i=0;i<=10;i++)
{
l_fenmu[i]=1.0;
for(j=0;j<=10;j++)
{
if(i!
=j)
l_fenmu[i]=l_fenmu[i]*(yx[i]-yx[j]);
}
}
doubleqq,pp;
for(qq=-1;qq<=1;qq+=0.0003)
{
for(i=0;i<=10;i++)
{
l_fenzi[i]=1.0;
for(j=0;j<=10;j++)
{
if(i!
=j)
l_fenzi[i]=l_fenzi[i]*(qq-yx[j]);
}
}
pp=0;
for(i=0;i<=11;i++)
{
pp=pp+1.0/(1+25*yx[i]*yx[i])*l_fenzi[i]/l_fenmu[i];
}
pDC->SetPixel(qq*500,pp*390+5,RGB(132,112,225));
}
}
voidCLDlg:
:
OnButton2()
{
intx00=300,y00=350,i,j;
doublex;
CDC*pDC=GetDC();
pDC->SetMapMode(MM_LOMETRIC);
pDC->SetViewportOrg(x00,y00);
//画坐标轴与原函数
for(i=-700;i<=700;i++)
{
pDC->SetPixel(i,0,RGB(0,0,0));
pDC->SetPixel(0,i,RGB(0,0,0));
}
doubleyx[]={-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1};
doubleyy[14];
for(i=0;i<=10;i++)
{
yy[i]=1.0/(1+25*yx[i]*yx[i]);
}
pDC->TextOut(-30,-10,"0");
pDC->TextOut(-30,430,"1");
pDC->TextOut(490,-10,"1");
pDC->TextOut(-490,-10,"-1");
pDC->MoveTo(-10,680);//x箭头
pDC->LineTo(0,700);
pDC->MoveTo(0,700);
pDC->LineTo(10,680);
pDC->MoveTo(680,10);//y箭头
pDC->LineTo(700,0);
pDC->MoveTo(700,0);
pDC->LineTo(680,-10);
pDC->TextOut(-30,700,"y");
pDC->TextOut(700,-10,"x");
//线性分段差值的图像
CPenpen;
CPen*oldpen;
pen.CreatePen(PS_SOLID,5,RGB(0,0,0));
oldpen=pDC->SelectObject(&pen);
for(i=0;i<10;i++)
{
pDC->MoveTo(yx[i]*480,yy[i]*400);
pDC->LineTo(yx[i+1]*480,yy[i+1]*400);
}
}
voidCLDlg:
:
OnHermite()
{
intx00=300,y00=350,i,j;
doublex;
CDC*pDC=GetDC();
pDC->SetMapMode(MM_LOMETRIC);
pDC->SetViewportOrg(x00,y00);
//画坐标轴与原函数
for(i=-700;i<=700;i++)
{
pDC->SetPixel(i,0,RGB(0,0,0));
pDC->SetPixel(0,i,RGB(0,0,0));
}
doubleyx[]={-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1};
doubleyy[12];
for(i=0;i<=10;i++)
{
yy[i]=1.0/(1+25*yx[i]*yx[i]);
}
pDC->TextOut(-30,-10,"0");
pDC->TextOut(-30,430,"1");
pDC->TextOut(490,-10,"1");
pDC->TextOut(-490,-10,"-1");
pDC->MoveTo(-10,680);//x箭头
pDC->LineTo(0,700);
pDC->MoveTo(0,700);
pDC->LineTo(10,680);
pDC->MoveTo(680,10);//y箭头
pDC->LineTo(700,0);
pDC->MoveTo(700,0);
pDC->LineTo(680,-10);
pDC->TextOut(-30,700,"y");
pDC->TextOut(700,-10,"x");
//分段三次Hermite差值的函数
doublex0,x1,yd1,yd0,y1,y0;
for(i=0;i<10;i++)
{
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;qq{
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现象。
分段线性插值因为在每一段小区间上都是线性插值而极大地降低了插值多项式的次数,从几何图形上可以看出,当节点取得较多时插值函数的逼近效果还是很好的,但是所求函数是一条以型值点为顶点的折线,这也表现出了它的缺点就是所求得的插值函数的光滑性较差,这就要求一种更好的方法来克服这一缺点了。