首页/文章/ 详情

基于Mathematica插值函数的振荡现象

1年前浏览1144

今天木木所要分享的是高阶插值多项式的振荡问题,初学插值函数的时候,常常在想,是不是取的节点越多,插值阶数越高,近似解就越精确呢?答案并不是这样的。当插值节点越多时,高次多项式插值经常会出现振荡现象,该多项式并不一致收敛于函数本身。我们从以下三个例题中感受基于Mathematica插值函数的振荡现象。

例1:给定函数f(x)=  ,使用节点  =0.49,0.64,0.81,1构造三次插值多项式l(x),并求出f(x)在x=1点的3次泰勒展开式t(x),分别由l(x)和t(x)计算x=0.98和x=0.5处f(x)的近似值,哪个更精确?进一步在坐标系下绘制f(x)-l(x)和f(x)-t(x)的误差图形,观察发生的现象。

    pt=Table[{i,Sqrt[i]},{i,{0.49,0.64,0.81,1}}];(*构造插值节点*)l[x_]=InterpolatingPolynomial[pt,x]//Expand(*插值多项式*)t[x_]=Normal[Series[Sqrt[x],{x,1,3}]];(*泰勒展开式*){c1=Sqrt[0.98],c2=l[0.98],c1-c2,c3=t[0.98],c1-c3}Needs["PlotLegends`"](*绘制f(x),l(x),t(x)*)Plot[{Sqrt[x],l[x],t[x]},{x,0.49,1},PlotStyle->{{Red,Thick,Dashed},Blue,Black},AxesLabel->{x,y},AxesStyle->Thick,BaseStyle->{FontSize->15,Bold},PlotLegend->{Style["f(x)",14,Italic,Bold],Style["l(x)",14,Italic,Bold],Style["t(x)",14,Italic,Bold]},LegendBorder->Thick,LegendSize->{0.7,0.4}](*绘制误差函数图*)Plot[{Sqrt[x]-l[x],Sqrt[x]-t[x]},{x,0.49,1},PlotStyle->{{Red,Thick,Dashed},Blue},AxesLabel->{x,error},AxesStyle->Thick,BaseStyle->{FontSize->15,Bold},PlotLegend->{Style["f(x)-l(x)",14,Italic,Bold],Style["f(x)-t(x)",14,Italic,Bold]},LegendBorder->Thick,LegendSize->{0.7,0.4}]

    得出三次插值多项式、三次泰勒多项式:

      0.260062 + 1.11977 x - 0.523162 x^2 + 0.143332 x^31 + 1/2 (-1 + x- 1/8 (-1 + x)^2 + 1/16 (-1 + x)^3
      精确解
      三次多项式
      误差
      三次泰勒
      误差
      0.9899490.9898930.00005670610.98995-6.33883e-9

      如图所示,三次插值多项式还没表现“振荡现象”,函数的插值多项式误差在插值区间上分布均匀,而其泰勒多项式误差具有局部性质,即在泰勒展开点附近逼近效果较好,越远离该点,则逼近效果越差。

      例2:给定函数f(x)=  ,使用节点0,0.01,...,0.81,1,使得f(x)的之每次增加1,构造10次插值多项式并求出f(x)在x=1处的泰勒10次展开式t(x)。(注意高阶插值多项式振荡现象

        pt = Table[{i^2, i}, {i, 0, 1, 0.1}];(*构造插值节点*)l[x_] = InterpolatingPolynomial[pt, x] // Expand(*插值多项式*)t[x_] = Normal[Series[Sqrt[x], {x, 1, 10}]](*泰勒展开式*)Needs["PlotLegends`"](*绘制f(x),l(x),t(x)*)Plot[{Sqrt[x], l[x], t[x]}, {x, 0, 1}, PlotStyle -> {{Red, Thick, Dashed}, Blue, Black}, AxesLabel -> {x, y}, AxesStyle -> Thick, BaseStyle -> {FontSize -> 15, Bold}, PlotLegend -> {Style["f(x)", 14, Italic, Bold],   Style["l(x)", 14, Italic, Bold],   Style["t(x)", 14, Italic, Bold]}, LegendBorder -> Thick, LegendSize -> {0.7, 0.4} ]

        得出10次插值多项式、10次泰勒多项式:公式太长,这里不便给出,感兴趣的小伙伴可以自行运行~

        由图可以看出,f(x)的10次插值函数l(x)发生了严重的振荡现象,其结果已无法使用,而10次泰勒多项式t(x)在零点附近逼近效果较差。

        例3:给定f(x)=ln(1+x),  ,使用节点x=0,0.2,...,2,其中步长为0.2,构造10次插值多项式l(x),并求出f(x)在x=0点的10次泰勒展开式t(x)。

          pt = Table[{i, Log[i + 1]}, {i, 0, 2, 0.2}];(*构造插值节点*)l[x_] = InterpolatingPolynomial[pt, x] // Expand(*插值多项式*)t[x_] = Normal[Series[Log[x + 1], {x, 0, 10}]];(*泰勒展开式*)Needs["PlotLegends`"]Plot[{Log[x + 1], l[x], t[x]}, {x, 0, 2}, PlotStyle -> {{Red, Thick, Dashed}, Blue, Black}, AxesLabel -> {x, y}, AxesStyle -> Thick, BaseStyle -> {FontSize -> 15, Bold}, PlotLegend -> {Style["f(x)", 14, Italic, Bold],   Style["l(x)", 14, Italic, Bold],   Style["t(x)", 14, Italic, Bold]}, LegendBorder -> Thick, LegendSize -> {0.7, 0.4} ]

          这个例题主要说明使用泰勒展开式需注意其收敛域,当x>1时,泰勒展开式发散,而插值多项式吻合效果很好。

          总结:插值具有整体性,但高次插值可能会发生振荡现象,泰勒展开式具有局部现象,在应用时必须注意收敛域,这样得出来的结果才有意义。

          来源:易木木响叮当
          Mathematica
          著作权归作者所有,欢迎分享,未经许可,不得转载
          首次发布时间:2023-06-01
          最近编辑:1年前
          易木木响叮当
          硕士 有限元爱好者
          获赞 187粉丝 175文章 282课程 2
          点赞
          收藏
          未登录
          还没有评论
          课程
          培训
          服务
          行家
          VIP会员 学习 福利任务 兑换礼品
          下载APP
          联系我们
          帮助与反馈