第五章 常用插值算法


第五章 常用插值算法 §5.1 线性插值算法 线性插值是代数插值的最简 单形式。假设变量 和自变量y x ,XG2ÏV Ò 5- 1 中曲线 所示。已知 在点 和 的对应值 和 ;现在要 求用一线性插值函数 ,近似代替 。 根据插值条件,应满足: )(xfy = y 1 1 1 a 0x x 0y y baxxg +=)( )(xf 00 ybax =+ 1 ybax =+ 解该方程组,便可确定线性插值函数 的参数 和 。由图可知,线性插值的几何意义 是用通过点 和点 的直线近似地代替曲线 )(xg b ),( 00 yxA ),( 11 yxB )(xfy = 。我们很容易求得该 直线表达式: )()( 0 01 01 0 xxxx yyyxg −− −+= (点斜式) 或: )()()( 10 0 1 01 1 0 xx xxyxx xxyxg − −+− −= (两点式) 由图 5- 1 也可以看出,插值节点 和 之间的间距越小,那么在这一区间 与 之间的误差就越小。若插值点 0x 1x )(xg )(xf x ü 和 之间,称为内插,否则称为外插或外推。在这里, 我们只考虑内插。在进行插值运算前,还要考虑下面两个具体问题: 0x 1x 插值节点的选取:在单片机的应用中,往往把常用的函数以表格的形式固化在程序 存储器中。例如某物理量的温度补偿值是非线性的,表格中的值是在若干个温度点 实测得到的补偿值;又比如等间距角度的正弦函数值组成的表格等等。对于任一给 定的插值点 È Ã¹EîE›1T ),XE¤1k.BnÔE¥,Xøþ¦&• 和 以及在表中对 应的函数值 和 ,然后就可以进行插值运算,求得插值点 0x x 0y 1y Íh,X 值。 x 1 x y 图 5- 1 用直线拟合求准确峰位示意图 f(x) Y B g(x) y1 y Ay0 X x0 x x1 0 为了提高插值精度,大多数情况下都是采用浮点运算,因此参与插值运算的数据和 表格应事先转换成规格化浮点。 以点斜式线性插值算法为例,当给定两个插值点的坐标后,就可以通过如下插值算法得 到插值点的函数近似值: 首先定义宏如下: M_GetValue: .MACRO Index //参数 Index=0,1,2,3,4,5,6; //Index表示参数在程序调用时的位置,最左边编号为 0 r1=Index; r1=r1 lsl 1; r1+=bp; //得到参数在堆栈中的位置 r3=[r1++]; //读取参数的值 r4=[r1]; .ENDM M_StoreValue: .MACRO Index //参数 Index=0,1,2,3,4,5,6; //Index表示参数在程序调用时的位置,最左边编号为 0 r3=Index; r3=r3 lsl 1; r3+=bp; //得到参数在堆栈中的位置 [r3++]=r1; //将 r1,r2 的值存入该参数 [r3]=r2; .ENDM //====================================================== // 程序名称: F_LinearInsert // 功能描述: 计算(x-x0)x(y1-y0)/(x1-x0)+y0,实现线性插值算法. // 输入: 浮点数 x0,y0,x1,y1,x // 输出: 浮点数 y->r1,r2 // 破坏: r1,r2,r3,r4; // 使用: r1,r2,r3,r4,bp,sp; // 占用堆栈: 14; //====================================================== .public F_LinearInsert; .public _F_LinearInsert; .code F_LinearInsert: _F_LinearInsert: .proc push bp to [sp]; bp=sp; bp+=4; //bp指向参数 x0 M_GetValue 0; //取 x0 push r3,r4 to [sp]; M_GetValue 4; //取 x push r3,r4 to [sp]; call __subf2; //计算 x-x0 sp+=4; M_StoreValue 4; //x-x0 存入参数 x M_GetValue 1; //取 y0 push r3,r4 to [sp]; M_GetValue 3; //取 y1 push r3,r4 to [sp]; call __subf2; //计算 y1-y0 sp+=4; M_StoreValue 3; //y1-y0 存入参数 y1 M_GetValue 0; //取 x0 push r3,r4 to [sp]; M_GetValue 2; //取 x1 push r3,r4 to [sp]; call __subf2; //计算 x1-x0 sp+=4; M_StoreValue 2; //x1-x0 存入参数 x1 M_GetValue 4; //取 x,即 x-x0 push r3,r4 to [sp]; M_GetValue 3; //取 y1,即 y1-y0 push r3,r4 to [sp]; call __mulf2; //计算(x-x0)x(y1-y0) sp+=4; M_StoreValue 4; //(x-x0)x(y1-y0)存入参数 x M_GetValue 2; //取 x1,即 x1-x0 push r3,r4 to [sp]; M_GetValue 4; //取 x,即(x-x0)x(y1-y0) push r3,r4 to [sp]; call __divf2; //计算(x-x0)x(y1-y0)/(x1-x0) sp+=4; push r1,r2 to [sp]; M_GetValue 1; //取 y0 push r3,r4 to [sp]; call __addf2; //计算(x-x0)x(y1-y0)/(x1-x0)+y0 sp+=4; pop bp from [sp]; retf; .endp §5.2 抛物线插值算法 5.2.1 算法概述 抛物线插值又称为二次插 值,它是以一元二次多项式去 拟合某一段曲线。精度自然要 比线性插值高。如图 5- 2 所示, 已知一条曲线 上的 三点 , , ;过此三点可以作一 抛物线,即一条二次曲线 ,且是唯一的。 ) 22 (xfy = ),( 00 yxA ),( 11 yxB ),( yxC )(xg 设: cbxaxxg ++= 2)( 已知: )()( ii xfxg = 其中: 2,1,0=i ; 由此可得下列方程组: 00 2 0 ycbxax =++ 111 2 ycbxax =++ 222 2 ycbxax =++ 解此方程组可得 的系数 、 和 ,但是这样运算很麻烦。实际计算中,我们可 以把 写成各种形式的二次多项式,然后运用待定系数法把 确定下来。这些方法包 括抛物线插值的拉各朗日(Lagrange)形式,抛物线插值的牛顿(Newton)形式,逐次线性 插值法等。在这里,我们只讨论逐次线性插值法,因为它能充分利用前面线性插值程序,也 容易在计算机上实现。 )(xg a cb )(xg )(xg 5.2.2 逐次线性插值算法 已知三点 , , 及插值点的),( 00 yx ),( 11 yx ),( 22 yx x È"Íh,X 值。 y 用直线点斜式公式: 第一步:过点 , 作直线 ,即 ),( 00 yx ),( 11 yx 01L )( 0 01 01 001 xxxx yyyL −− −+= (8.1) 第二步:过点 , 作直线 ,即 ),( 00 yx ),( 22 yx 02L )( 0 02 02 002 xxxx yyyL −− −+= (8.2) 图 5- 2 抛物线插值示意图 )(xg )(xf C AY B X x0 x1 x2 0 第三步:将 , 也理解为“点”,过这两点作“直线”,记之为 , 即 ),( 011 Lx ),( 022 Lx 012L )( 1 12 0102 01012 xxxx LLLL −− −+= (8.3) 第四步:把式(8.1)和(8.2)代入式(8.3),得 ))(()( 10 12 01 01 02 02 0 01 01 0012 xxxxxx xx yy xx yy xxxx yyyL −−             − − −−− − +−− −+= (8.4) 不难看出, 是关于012L x ,X` õÑDÈJè$µC‡ sÆ-¹&•G2ÏÖ ii yxL =)(012 )2,1,0( =i 所以, 就是所要求的二次插值多项式 。 012L )(xg 仔细观察式(8.4)后可以看出, )()( 0101 xxyy −÷− 是一阶差商,而方括号内的分式 是二阶差商。式(8.3)是通过两个线性插值的结果获得 ,所以称为逐次线性插值。显 然,式(8.1)、(8.2)和(8.3)都是线性插值中的点斜式表达式,因此,可以直接调用前面 的线性插值程序。 )(xg 因为只考虑内插,所以插值点 x h!b [ ]的区间内。当我们将三个节点的坐标和 插值点的横坐标代入下面的程序后,就可以得到插值点的函数近似值。 20 , xx //====================================================== // 程序名称: F_QuadraticInsert // 功能描述: 实现逐次线性插值算法: // 1、计算 L01=y0+(y1-y0)(x-x0)/(x1-x0) // 2、计算 L02=y0+(y2-y0)(x-x0)/(x2-x0) // 3、计算 L012=L01+(L02-L01)(x-x1)/(x2-x1) // 输入: 浮点数 x0,y0,x1,y1,x2,y2,x // 输出: 浮点数 y->r1,r2 // 破坏: r1,r2,r3,r4; // 使用: r1,r2,r3,r4,bp,sp; // 占用堆栈: 28; //====================================================== .public F_QuadraticInsert; .public _F_QuadraticInsert; F_QuadraticInsert: _F_QuadraticInsert: .proc push bp to [sp]; bp=sp+4; //bp指向参数 x0 M_GetValue 6; //取 x push r3,r4 to [sp]; M_GetValue 3; //取 y1 push r3,r4 to [sp]; M_GetValue 2; //取 x1 push r3,r4 to [sp]; M_GetValue 1; //取 y0 push r3,r4 to [sp]; M_GetValue 0; //取 x0 push r3,r4 to [sp]; call F_LinearInsert; //计算 L01 sp+=10; M_StoreValue 3; //L01 存入 y1 M_GetValue 6; //取 x push r3,r4 to [sp]; M_GetValue 5; //取 y2 push r3,r4 to [sp]; M_GetValue 4; //取 x2 push r3,r4 to [sp]; M_GetValue 1; //取 y0 push r3,r4 to [sp]; M_GetValue 0; //取 x0 push r3,r4 to [sp]; call F_LinearInsert; //计算 L02 sp+=10; M_StoreValue 5; //L02 存入 y2 M_GetValue 6; //取 x push r3,r4 to [sp]; M_GetValue 5; //取 L02 push r3,r4 to [sp]; M_GetValue 4; //取 x2 push r3,r4 to [sp]; M_GetValue 3; //取 L01 push r3,r4 to [sp]; M_GetValue 2; //取 x1 push r3,r4 to [sp]; call F_LinearInsert; //计算 L012 sp+=10; pop bp from [sp]; retf; .endp
还剩5页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

ttcchh2008

贡献于2014-05-06

下载需要 5 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf