数值分析实验用程序实现Hermite插值法.docx
- 文档编号:7297092
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:15
- 大小:103.99KB
数值分析实验用程序实现Hermite插值法.docx
《数值分析实验用程序实现Hermite插值法.docx》由会员分享,可在线阅读,更多相关《数值分析实验用程序实现Hermite插值法.docx(15页珍藏版)》请在冰豆网上搜索。
数值分析实验用程序实现Hermite插值法
《数值分析》实验报告
实验序号:
实验六实验名称:
Hermite插值法
1.实验目的:
学会Hermite插值法,并应用该算法于实际问题.
2.实验内容:
求一个函数
(x)用来近似函数f(x),用分段三次Hermit插值的方法来求解近似函数
(x)并画出近似函数图像及原函数图像。
设在区间[a,b]上,给定n+1个插值节点
和相应的函数值
以及一阶导数值
,求一个插值函数
,满足以下条件:
(1)
(2)
在每一个小区间[
]上是三次多项式。
对于给定函数
。
在区间
上画出f(x)和分段三次Hermit插值函数
的函数图像。
3.实验分析:
算法分析:
1.分段三次Hermit插值的算法思想:
分段三次Hermit插值的做法是在每一个小区间上作三次Hermit插值,因此在每一个插值节点上都需要构造两个插值基函数
,然后再作它们的线性组合。
分段三次Hermit插值基函数如下:
分段三次Hermit插值函数是:
4.实验代码:
//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)); } } } 5.实验截图 6.实验结果分析: 通过本次实验我对分段三次Hermit插值有了更深刻更全面的掌握,它在给定了节点处的函数值和导数值以后,构造了一个整体上具有一阶连续微商的插值函数。 分段三次Hermit插值降低了插值多项式的次数,而且保证了插值函数在节点处一阶导数连续,从而使插值函数的光滑性更好。 但是在实际问题中给出节点处的函数值比较方便,给出导数值就很困难了。 分段三次Hermit插值函数属于插值曲线,适合于已知曲线上的某些点而生成曲线的情形,在许多实际问题中缺少灵活性和直观性。 况且它只具有一阶光滑性,但很多实际问题中需要更好的光滑性,这就要求有更好的方法来解决问题,比如Bezier曲线,B样条曲线等。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数值 分析 实验 程序 实现 Hermite 插值法