点击(此处)折叠或打开
- !cccccccccccccccccccccccccccccccccccccccccccccccc!
- ! chap1c.f90
- ! Finding roots
- program main
- !cccccccccccccccccccccccccccccccccccccccccccccccc!
- !
- ! variables
- implicit none
- real :: x=1.0
- real :: func ! func=x*x-5
- real :: fold ! use as the sign,用于记录初始值的符号
- real :: dx=0.5 ! step
- real,parameter :: tolx=1.0E-06 ! tolernce for the search
- integer :: iter=0 ! counter
- func=x*x-5.0
- fold=func
- do while(abs(dx)>tolx)
- iter=iter+1
- x=x+dx
- func=x*x-5.0
- if(fold*func<0)then
- x=x-dx
- dx=dx/2.0
- end if
- end do
- write(*,*)"exact:",sqrt(5.0),"root:",x,"counter:",iter
- stop
- end program main
迭代次数33次。
更有效的方法:Newton-Raphson法,但是需要知晓函数导数值。
折中一些的做法是割线法。
下面是Newton-Raphson法的程序,
点击(此处)折叠或打开
- !cccccccccccccccccccccccccccccccccccccccccccccccc!
- ! chap1c.f90
- ! Newton method:Finding roots
- ! function: sin(x),df(x)/dx=cos(x)
- program main
- !cccccccccccccccccccccccccccccccccccccccccccccccc!
- !
- ! variables
- implicit none
- real :: x1=1.0,x2
- real :: funa
- real :: dfun
- real,parameter :: tolx=1.0E-06 ! tolernce for the search
- integer :: iter=0 ! counter
- funa=sin(x1)
- do while(abs(funa)>tolx)
- iter=iter+1
- dfun=cos(x1)
- funa=sin(x1)
- x2=x1-funa/dfun
- x1=x2
- end do
- write(*,*)"root:",x1,"counter:",iter
- stop
- end program main
当初值为2时,结果为: root: 3.14159274 counter: 6,即迭代6次。
计算速度明显比上一种普通迭代法要快的多。