Given a continuous equation f(x)=0 and two values a and b (a < b), if f(a)*f(b) < 0 (i.e., f(a) and f(b) have opposite signs), it can be proved that there exists a root of f(x)=0 between a and b. More precisely, there exists a c, a <= c <= b, such that f(c)=0 holds.
This result provides us with a method for solving equations. If we take the midpoint of a and b, c=(a+b)/2, and computes its function value f(c), we have the following cases:
Your function Funct() is given below:
This function has a root near -0.89.
Since this process keeps dividing the intervals into two equal halves, it is usually referred to as the bisection method. It is also known as Bozano's method.
Click here to download this program.! -------------------------------------------------------------------- ! This program solves equations with the Bisection Method. Given ! a function f(x) = 0. The bisection method starts with two values, ! a and b such that f(a) and f(b) have opposite signs. That is, ! f(a)*f(b) < 0. Then, it is guaranteed that f(x)=0 has a root in ! the range of a and b. This program reads in a and b (Left and Right ! in this program) and find the root in [a,b]. ! In the following, function f() is REAL FUNCTION Funct() and ! solve() is the function for solving the equation. ! -------------------------------------------------------------------- PROGRAM Bisection IMPLICIT NONE REAL, PARAMETER :: Tolerance = 0.00001 REAL :: Left, fLeft REAL :: Right, fRight REAL :: Root WRITE(*,*) 'This program can solves equation F(x) = 0' WRITE(*,*) 'Please enter two values Left and Right such that ' WRITE(*,*) 'F(Left) and F(Right) have opposite signs.' WRITE(*,*) WRITE(*,*) 'Left and Right please --> ' READ(*,*) Left, Right ! read in Left and Right fLeft = Funct(Left) ! compute their function values fRight = Funct(Right) WRITE(*,*) WRITE(*,*) 'Left = ', Left, ' f(Left) = ', fLeft WRITE(*,*) 'Right = ', Right, ' f(Right) = ', fRight WRITE(*,*) IF (fLeft*fRight > 0.0) THEN WRITE(*,*) '*** ERROR: f(Left)*f(Right) must be negative ***' ELSE Root = Solve(Left, Right, Tolerance) WRITE(*,*) 'A root is ', Root END IF CONTAINS ! -------------------------------------------------------------------- ! REAL FUNCTION Funct() ! This is for function f(x). It takes a REAL formal argument and ! returns the value of f() at x. The following is sample function ! with a root in the range of -10.0 and 0.0. You can change the ! expression with your own function. ! -------------------------------------------------------------------- REAL FUNCTION Funct(x) IMPLICIT NONE REAL, INTENT(IN) :: x REAL, PARAMETER :: PI = 3.1415926 REAL, PARAMETER :: a = 0.8475 Funct = SQRT(PI/2.0)*EXP(a*x) + x/(a*a + x*x) END FUNCTION Funct ! -------------------------------------------------------------------- ! REAL FUNCTION Solve() ! This function takes Left - the left end, Right - the right end, ! and Tolerance - a tolerance value such that f(Left)*f(Right) < 0 ! and find a root in the range of Left and Right. ! This function works as follows. Because of INTENT(IN), this ! function cannot change the values of Left and Right and therefore ! the values of Left and Right are saved to a and b. ! Then, the middle point c=(a+b)/2 and its function value f(c) ! is computed. If f(a)*f(c) < 0, then a root is in [a,c]; otherwise, ! a root is in [c,b]. In the former case, replacing b and f(b) with ! c and f(c), we still maintain that a root in [a,b]. In the latter, ! replacing a and f(a) with c and f(c) will keep a root in [a,b]. ! This process will continue until |f(c)| is less than Tolerance and ! hence c can be considered as a root. ! -------------------------------------------------------------------- REAL FUNCTION Solve(Left, Right, Tolerance) IMPLICIT NONE REAL, INTENT(IN) :: Left, Right, Tolerance REAL :: a, Fa, b, Fb, c, Fc a = Left ! save Left and Right b = Right Fa = Funct(a) ! compute the function values Fb = Funct(b) IF (ABS(Fa) < Tolerance) THEN ! if f(a) is already small Solve = a ! then a is a root ELSE IF (ABS(Fb) < Tolerance) THEN ! is f(b) is small Solve = b ! then b is a root ELSE ! otherwise, DO ! iterate .... c = (a + b)/2.0 ! compute the middle point Fc = Funct(c) ! and its function value IF (ABS(Fc) < Tolerance) THEN ! is it very small? Solve = c ! yes, c is a root EXIT ELSE IF (Fa*Fc < 0.0) THEN ! do f(a)*f(c) < 0 ? b = c ! replace b with c Fb = Fc ! and f(b) with f(c) ELSE ! then f(c)*f(b) < 0 holds a = c ! replace a with c Fa = Fc ! and f(a) with f(c) END IF END DO ! go back and do it again END IF END FUNCTION Solve END PROGRAM Bisection
The following output shows that the function values of the input do not have opposite signs and hence program stops.This program solves equation F(x) = 0 Please enter two values Left and Right such that F(Left) and F(Right) have opposite signs. Left and Right please --> -10.0 0.0 Left = -10. f(Left) = -9.902540594E-2 Right = 0.E+0 f(Right) = 1.25331414 A root is -0.89050293
This program solves equation F(x) = 0 Please enter two values Left and Right such that F(Left) and F(Right) have opposite signs. Left and Right please --> -10.0 -1.0 Left = -10. f(Left) = -9.902540594E-2 Right = -1. f(Right) = -4.495930672E-2 *** ERROR: f(Left)*f(Right) must be negative ***