(1)普通寻根法:初始猜测值与真实值偏差较大,迭代次数很多;有多个根时,可能会出现错误。

点击(此处)折叠或打开

  1. !cccccccccccccccccccccccccccccccccccccccccccccccc!
  2. !  chap1c.f90
  3. !  Finding roots
  4. program main
  5. !cccccccccccccccccccccccccccccccccccccccccccccccc!
  6. !
  7. !  variables
  8.  implicit none
  9.  real :: x=1.0
  10.  real :: func   ! func=x*x-5
  11.  real :: fold   ! use as the sign,用于记录初始值的符号
  12.  real :: dx=0.5   ! step
  13.  real,parameter :: tolx=1.0E-06   ! tolernce for the search
  14.  integer :: iter=0  ! counter

  15.  func=x*x-5.0
  16.  fold=func

  17.  do while(abs(dx)>tolx)
  18.   iter=iter+1
  19.   x=x+dx
  20.   func=x*x-5.0
  21.   if(fold*func<0)then
  22.    x=x-dx
  23.    dx=dx/2.0
  24.   end if
  25.  end do

  26.  write(*,*)"exact:",sqrt(5.0),"root:",x,"counter:",iter

  27.  stop

  28. end program main
  计算结果: exact:   2.23606801     root:   2.23606682     counter:          33
  迭代次数33次。
  更有效的方法:Newton-Raphson法,但是需要知晓函数导数值。
  折中一些的做法是割线法。
  下面是Newton-Raphson法的程序,

点击(此处)折叠或打开

  1. !cccccccccccccccccccccccccccccccccccccccccccccccc!
  2. ! chap1c.f90
  3. ! Newton method:Finding roots
  4. ! function: sin(x),df(x)/dx=cos(x)
  5. program main
  6. !cccccccccccccccccccccccccccccccccccccccccccccccc!
  7. !
  8. ! variables
  9.  implicit none
  10.  real :: x1=1.0,x2
  11.  real :: funa
  12.  real :: dfun
  13.  real,parameter :: tolx=1.0E-06  ! tolernce for the search
  14.  integer :: iter=0  ! counter
  15.  funa=sin(x1)
  16.  do while(abs(funa)>tolx)
  17.   iter=iter+1
  18.   dfun=cos(x1)
  19.   funa=sin(x1)
  20.   x2=x1-funa/dfun
  21.   x1=x2
  22.  end do
  23.  write(*,*)"root:",x1,"counter:",iter
  24. stop
  25. end program main
  当初值是1时,结果为: root:   0.00000000     counter:           5,即迭代5次。
  当初值为2时,结果为: root:   3.14159274     counter:           6,即迭代6次。
  计算速度明显比上一种普通迭代法要快的多。




09-14 14:51