使用Fortran 90的牛顿-拉夫森法

时间:2019-03-31 13:09:54

标签: fortran scientific-computing polynomials newtons-method

我开发了以下代码来查找给定多项式的根。它工作正常,但我需要对其进行调整以找到所有根,而不是在收敛时停止。我该怎么做呢?我曾考虑过为x的值创建一个外部do循环,但是我不确定这是否是正确的方法。感谢您的任何帮助。

PROGRAM nr
integer :: i
real :: x, f, df
write(*,*) "x=?"
read (*,*)  x           
write (*,*) '# Initial value: x=',x

 do i=1,100
     f= x**4 - 26*(x**3) + 131*(x**2) - 226*x + 120
     df = 4*(x**3) - 3.0*26*(x**2) + 2.0*131*x - 226
     write (*,*) i,x,f,df
     x = x-f/df
 end do

 write (*,*) '#x = ',x




END PROGRAM

1 个答案:

答案 0 :(得分:3)

找到多项式P的所有根的可能算法包括:

  • 使用牛顿算法从某个X0开始,找到根R。
  • 将P除以(X-R):除法是精确的(直到数值误差),因为R是根。 (此步骤称为放气
  • 如果商的度数> 1,则从头开始。

有一些细微之处:

  • 如果多项式具有实系数,且X0为实,则仅会找到实根(如果有)。要找到复杂的根,则必须从复杂的X0开始,当然要使用复杂的算术。
  • 并非所有X0值都可以保证收敛,因为Newton-Raphson是 local 方法。请参阅牛顿方法的Newton-Kantorovitch theorembasins of attraction
  • 如果存在多个根,则收敛会慢得多。有多种方法可以使牛顿方法适应这一问题。
  • 在放气步骤中引入的数值误差加起来,通常会导致后续根的准确性降低。对于高次多项式(实际取决于多少),这尤其是一个问题。在极端情况下,计算出的根数可能与精确的根数相去甚远。此外,某些多项式比其他多项式更“难”:例如参见Wilkinson's polynomial
  • 有多种方法可以找到关于根的信息(绑定在绝对值上,将根围成圆...),这有助于在算法中选择一个好的X0:请参见Geometrical properties of polynomial roots。如果您只在寻找实多项式的实根,则先找到界限,然后使用Sturm's theorem查找包围根的区间。在实际情况下,另一种方法是先找到导数P'的根(然后找到它的根,先找到P''的根,等等),因为P'的根将P的根分开(除了多根)。
  • 另一本建议阅读:Roots of polynomials。注意,有比牛顿+放气更好的算法。还有一些旨在查找所有根的算法。

但是,如果您只对这个特定的多项式感兴趣,我建议您先看一下问题,因为它比一般情况下要容易得多:WolframAlpha。 在这里,从X0的整数值开始将很好地工作...