目录
重根与单根时的牛顿法比较。理解牛顿法的原理及应用,通过比较两种情况下的牛顿法的性能,得出方法的优劣性,并提出对应的改进方案。
-
- 相关解释:
因为对于多数方程式,因不存在求根公式,或者说无法或很难找到标准的可以直接套用的模板公式。因而求精准解非常困难,从而寻找方程的近似根就显得特别重要。本文主要介绍使用牛顿法求解时对于重根华为单根的比较。
2.1目的:
对于大多方程,尤其在求解非线性方程时,无法给出其精确解情况下,可采用迭代大的方式,求出其近似解,本项目主要以牛顿法为主,说明在求解方程时牛顿法对于单根和重根的区别以及改进方法。
2.2要求:
使用牛顿法求解一元方程,对于重根和单根情况接的比较,收敛性判别,收敛速度比较以及改进方式。
2.3注意事项:
此处牛顿法仅针对连续可微函数,对于不可微情况,应采取离散式牛顿法,此项目不予讨论。
3.1牛顿法基本思想
对于非线性函数f(x),根据泰勒公式得到x附近某个点展开的多项式可用来近似函数f(x)的值,该多项式对应的函数为F(x),求得F(x)的极小值作为新的迭代点,然后继续在新的迭代点泰勒公式展开,直到求得的极小值满足一定的精度。
例如,对于一个三次函数,任意找一个曲线上的A点(为什么随便找,根据切线是切点附近的曲线的近似,应该在根点附近找,但是很显然我们现在还不知道根点在哪里)。
图1 切线示意图 |
过点A做一个切线,切线的根(就是和x轴的交点)与曲线的根,还有一定的距离。没关系,我们从这个切线的根出发,做一根垂线,和曲线相交于B点,继续重复刚才的工作:
图2 牛顿法第二步 |
继续重复刚才的工作有:
图3 牛顿法三次近似解 |
此时,我们发现在第四次就已经很接近曲线的根了
图4牛顿法四次近似解 |
容易得出,点的切线方程为 ,要求 ,即相当于求的解,即
3.2 牛顿迭代公式的推导
假设f(x)在R上连续可微,将f(x)泰勒展开有:
忽略无穷小项得到:
令有:
化简后得到:
图像解释:
图5 牛顿法示意图 |
3.3牛顿法收敛性分析及初值选取
3.3.1 牛顿法的收敛性
将牛顿法中迭代公式写为迭代法统一形式有:
对Newton法的迭代函数取导数,有:
假设为 的一个单根,即,则有,所以当x充分靠近时,有成立,从而根据迭代法的局部收敛性条件可知,牛顿法在单根处收敛的,即以下给出局部收敛性定理:
定理1:若为方程的一个单根,即, 在邻域内有连续二阶导数,则由牛顿法迭代格式产生的序列 局部收敛于 ,且收敛速度至少为二阶(若,则收敛速度为二阶)。由上述定理我们发现牛顿法在的邻域内的收敛速度较快的。但此定理只给出了牛顿法收敛的充分条件,在实际运用牛顿法求解方程大的根时,初值的选取对结果的影响至关重要,通常选取距离附近的初值。
选取根的区间就变得极为重要,以下给出牛顿法在区间 内的收敛性判别:
定理2:设在区间[a,b]上存在二阶导数,且有:
不变号,
则牛顿法迭代公式收敛于在内唯一根。
以下给出符合定理2的几种情况:
图6 符合区间的几种情况 |
定理2的条件(1)保证根的存在性;条件(2)表明函数单调,根惟一;条件(3)表明函数的凹凸性不变;条件(4)保证当时, 。
对于定理2中的条件4可等价的表示为:
但对于具有重根情况时,和上述方法不尽相同。
假设为 的m重根,,因此由重根的定义有
由牛顿法的迭代函数 导数表达式:
所以,因此此时仅有线性收敛。
3.3.2 初值的选择
应用Newton法求方程的根,选择初始值极为重要,若取得偏离方程的精确解较大,则会导致牛顿迭代过程不收敛或增加迭代次数。
此处先给出一个统一的方式:
对于方程 ,如果有:
则可以保证其收敛性。
但在实际使用中,不可能遍历所有的点,因此,再给出一种可行的方法:二分法。
可以先使用二分法找到其解的大致区间,然后以区间中点作为初值。因此可先用二分法找出其大致区间,在使用定理2检验区间是否符合条件,即在内部是否收敛。
四、牛顿法的实现
为比较牛顿法再单根和重根时的算法,本文采用控制变量的方式,控制迭代精度均为0.0001,最大迭代次数均为不超过10000次,为避免不同方程的计算难易程度(尤其是线性和非线性之间的计算时差)本文统一使用多项式类型的函数,保证函数的可导和连续性。
本文先使用二分法找到方程精确解的初值,二分法流程图如下:
图7 二分法流程图 |
通过二分法找到x作为带入牛顿法中计算,牛顿法的流程图如下:
图8 牛顿法步骤流程图 |
五、课程设计的结果
本文使用函数如下:
定义本文的范围为
两函数图像如下:
|
使用二分法求解出解的大概区间,并使用定理2检验是否满足收敛性条件,得出接的大致区间:
图10 二分法求解的大致区间和初值点 |
上图绿色点即可作为初值带入至牛顿法中。
使用牛顿法求解该方程的根:
(单根) | (重根) | ||
|
| ||
表1 解的对比 |
此时,两方程解的误差对比图如下:
图13 两种情况收敛速度对比 |
两情况的收敛速度情况对比 | |||
|
|
由上图,我们发现此时单根的收敛速度比重根时大,这说明牛顿法在处理单根问题时性能较好,但处理具有重根问题时的性能较弱。
六、结果分析与改进
6.1 结果的分析
从五中的结果来看,牛顿法再单根时的收敛速度远大于重根时速度,从收敛阶角度来说在单根时具有二阶以上的收敛阶,但再重根时只有线性收敛阶,所以单根时的收敛速度较快。
6.2 重根时牛顿法的改进
由于牛顿法在重根时性能较为弱,因此需要对其改进,为讨论牛顿法的改进,此时分为两种情况讨论:重数已知,充数未知。
6.2.1 重根的重数已知时
设具有连续的m阶导数,为非线性方程的一个m重根 ,则 ,而,在附近的邻域内将和在
处泰勒展开:
因展开式的前m项均为0,带入牛顿法的迭代公式中有:
其中介于之间,当m≥2 时,,构造公式
此时具有二阶收敛速度。
6.2.2 重根的重数未知时
设f(x) 具有连续的m阶导数,为非线性方程的一个重根,但重数未知,此时令,为的单根,从而,对使用牛顿法迭代公式,有,因此可得原公式变换为:
由牛顿法迭代可知,为的单根,从而为二阶收敛。
七、项目的心得与体会
在深入学习求解方程的方法时,我选择了研究牛顿法。牛顿法以其独特的思想和高效的求解过程,吸引了我深入探索。通过这次学习,我不仅掌握了这种方法的基本原理和应用,更对其在实际问题中的应用有了深刻的理解。
学习过程中,我首先了解了牛顿法的数学基础和原理。这是一种迭代方法,通过不断地逼近方程的根,最终找到精确解。这其中涉及到的知识点包括导数、切线、以及函数的零点等。在理解了这些基础知识后,我开始尝试编写程序来实现牛顿法。
然而,在编程过程中,我遇到了许多挑战。比如初始值的选取、迭代过程的控制、以及如何处理可能出现的特殊情况等。通过不断地调试和优化,我逐渐掌握了这些技巧,并能够编写出稳定且高效的代码。
此外,通过学习牛顿法,我更加认识到数学在实际问题中的重要性。这种方法不仅可以用于求解方程,还可以用于优化问题、机器学习等领域。这让我更加坚定了学好数学的决心。
这次学习让我深刻体会到理论与实践相结合的重要性。只有真正将理论知识应用到实践中,才能更好地理解和掌握它。同时,也让我认识到持续学习和探索的重要性。只有不断地学习和实践,才能跟上时代的步伐,解决实际问题。
未来,我计划深入研究其他数学方法和算法,并尝试将其应用于实际问题中。我相信,通过不断地学习和实践,我能够成为一名优秀的数学应用者。
八、参考文献
[1] 唐旭清,王林君.《数值计算方法》[M].北京:科学出版社,2015.
[2] 张保祥.《重根情形的Newton迭代法收敛性加速》[C].淮安:淮阴师范学院数学系,2015
[3] 佚名.《机器学习优化算法中梯度下降,牛顿法和拟牛顿法的优缺点详细介绍》[EB]. 2020-1
https://wenku.baidu.com/view/286f8a6809a1284ac850ad02de80d4d8d05a0136.html?fr=income2-doc-search&_wkts_=1703752780617&wkQuery=%E7%89%9B%E9%A1%BF%E6%B3%95%E6%94%B6%E6%95%9B%E9%80%9F%E5%BA%A6
[4] 佚名.《常见的⼏种最优化⽅法》[EB]. 2020-8
https://wenku.baidu.com/view/f93013c5514de518964bcf84b9d528ea80c72f40.html?fr=income5-doc-search&_wkts_=1704155363252&wkQuery=%E5%B8%B8%E8%A7%81%E7%9A%84%E2%BC%8F%E7%A7%8D%E6%9C%80%E4%BC%98%E5%8C%96%E2%BD%85%E6%B3%95
九、附录
(此处仅给出主要程序):
%main.m
%两函数原始图像
x0=-5:0.01:5;
n0=length(x0);
y01=zeros(n0,1);
y02=zeros(n0,1);
for i=1:n0
y01(i)=y1(x0(i));
y02(i)=y2(x0(i));
end
plot(x0,y01,'r',x0,y02,'b')
legend('f1','f2')
xlabel('x');
ylabel('y')
%%
%单根时的牛顿法求解
x1=zeros(10001,1);
x2=zeros(10001,1);
x1(1)=erfen1(0,4);
x1(2)=x1(1)-y1(x1(1))/dy1(x1(1));
i=2;
dy1(x1(i))
x11=zeros(10001,1);
while abs(y1(x1(i))-y1(x1(i-1)))>0.00001&&i<=10000
i=i+1;
x1(i)=x1(i-1)-y1(x1(i-1))/dy1(x1(i-1));
if abs(dy1(x1(i)))<=0.0001
break;
end
end
for j=1:i-1
x11(j)=abs(x1(j+1)-x1(j));
end
i
n=1:j;
figure(2);
plot(x1(1:i));
title('单根牛顿法迭代')
xlabel('n');
ylabel('x');
figure(3);
plot(x11(1:i));
title('误差1');
xlabel('n');
ylabel('|(x(i)-x(i-1)|');
hold on
%%
%牛顿法在重根时的求解
x2=zeros(10001,1);
x2(1)=0;
x2(2)=x2(1)-y2(x2(1))/dy2(x2(1));
i=2;
dy2(x2(i))
x22=zeros(10001,1);
while abs(y2(x2(i))-y2(x2(i-1)))>0.00001&&i<=100
i=i+1;
x2(i)=x2(i-1)-y2(x2(i-1))/dy2(x2(i-1));
if abs(dy2(x2(i)))<=0.001
break;
end
end
i
for j=1:i-1
x22(j)=abs(x2(j+1)-x2(j));
end
figure(4);
plot(x2(1:i));
title('重根牛顿法迭代')
xlabel('n');
ylabel('x');
figure(3);
plot(x22(1:i),'r');
title('误差2(对比)');
xlabel('n');
ylabel('|(x(i)-x(i-1)|');
legend('单根误差','重根误差')
% 二分法 erfen.m
function x=erfen1(a,b)
%二分法寻找初值
a0=a;
b0=b;
yip=1;
a=a0;
b=b0;
az=[];
bz=[];
k=1;
xx=a0-1:0.01:b0+1;
while abs(b-a)/2>yip&&y1(a)*y1(b)<0
x0=(a+b)/2;
if y1(x0)==0
break;
end
if y1(a)*y1(x0)>0
a=x0;
else
b=x0;
end
az=[az a];
bz=[bz b];
k=k+1;
end
x=(a+b)/2
y0=zeros(length(xx),1);
yy=zeros(length(xx),1);
for i=1:length(xx)
y0(i)=y1(xx(i));
yy(i)=0;
end
figure(1);
plot(xx,y0,'r');
hold on
plot(xx,yy,'b')
hold on
plot((a+b)/2,0,'go')
title('二分法求解')
end
%gaijin.m
%重根时牛顿法的改进
x2=zeros(10001,1);
x2(1)=0;
x2(2)=x2(1)-y2(x2(1))/dy2(x2(1));
i=2;
dy2(x2(i))
x22=zeros(10001,1);
while abs(y2(x2(i))-y2(x2(i-1)))>0.00001&&i<=100
i=i+1;
x2(i)=x2(i-1)-y2(x2(i-1))/dy2(x2(i-1));
if abs(dy2(x2(i)))<=0.001
break;
end
end
i
for j=1:i-1
x22(j)=abs(x2(j+1)-x2(j));
end
figure(4);
plot(x2(1:i));
title('重根牛顿法迭代')
xlabel('n');
ylabel('x');
figure(3);
plot(x22(1:i));
title('误差');
xlabel('n');
ylabel('|(x(i)-x(i-1)|');
hold on
%%
x2=zeros(10001,1);
x2(1)=0;
x2(2)=x2(1)-2*y2(x2(1))/dy2(x2(1));
i=2;
dy2(x2(i))
x22=zeros(10001,1);
while abs(y2(x2(i))-y2(x2(i-1)))>0.00001&&i<=100
i=i+1;
x2(i)=x2(i-1)-2*y2(x2(i-1))/dy2(x2(i-1));
if abs(dy2(x2(i)))<=0.001
break;
end
end
i
for j=1:i-1
x22(j)=abs(x2(j+1)-x2(j));
end
figure(2);
plot(x2(1:i));
title('重根牛顿法迭代')
xlabel('n');
ylabel('x');
figure(3);
plot(x22(1:i),'r');
legend('重根误差(前)','重根误差(后)')
xlabel('n');
ylabel('|(x(i)-x(i-1)|');