(1)普通寻根法:初始猜测值与真实值偏差较大,迭代次数很多;有多个根时,可能会出现错误。
-
!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
计算结果: exact: 2.23606801 root: 2.23606682 counter: 33
迭代次数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
当初值是1时,结果为: root: 0.00000000 counter: 5,即迭代5次。
当初值为2时,结果为: root: 3.14159274 counter: 6,即迭代6次。
计算速度明显比上一种普通迭代法要快的多。
阅读(1357) | 评论(0) | 转发(0) |