Preface
This tutorial was made solely for the purpose of education and it was designed for students taking Applied Math 0330. It is primarily for students who have very little experience or have never used Mathematica before and would like to learn more of the basics for this computer algebra system. As a friendly reminder, don't forget to clear variables in use and/or the kernel.
Finally, the commands in this tutorial are all written in bold black font, while Mathematica output is in normal font. This means that you can copy and paste all commands into Mathematica, change the parameters and run them. You, as the user, are free to use the scripts for your needs to learn the Mathematica program, and have the right to distribute this tutorial and refer to this tutorial as long as this tutorial is accredited appropriately.
Return to computing page for the second course APMA0340
Return to Mathematica tutorial for the second course APMA0330
Return to Mathematica tutorial for the first course APMA0340
Return to the main page for the course APMA0340
Return to the main page for the course APMA0330
Return to Part III of the course APMA0330
Bracketing Methods
In this section we develop two bracketing methods for finding a zero/null of a real and continuous function f(x). All bracketing methods always converge, whereas open methods (discussed in the next section) may sometimes diverge. We must start with an initial interval [a,b], where f(a) and f(b) have opposite signs. Since the graph \( y = f(x) \) of a continuous function is unbroken, it will cross the abscissa at a zero x = r that lies somewhere within the interval [a,b]. One of the ways to test a numerical method for solving the equation \( f(x) =0 \) is to check its performance on the Wilkinson polynomials
I. The Bisection Method of Bolzano

- If f(a) and f(c) have opposite signs, a zero lies in [a,c] .
- If f(b) and f(c) have opposite signs, a zero lies in [c,b] .
- If \( f(c) =0 , \) then the zero is c.
After arriving at the n-th interval \( [a_n , b_n ] , \) which brackets r and has midpoint cn, the new interval \( [a_{n+1} , b_{n+1} ] \) is constructed, which also brackets r and is half as wide as \( [a_n , b_n ] . \) So
Theorem (Bolzano): Suppose that f is a continuous function on the closed interval [a,b] and that there exists a number r from this interval such that \( f(r) =0 . \) If f(a) and f(b) have opposite signs, and \( \left\{ c_n \right\}_{n\ge 0} \) represents the sequence of midpoints generated by the bisection algorithm, then
Pseudocode for Bisection Method:
input a,v,eps
external f
fa = f(a)
fb = f(b)
if f(a)*f(b) > 0 then stop
n = fix((log(b-a) - log(eps))/log(2)) + 1
for i=1 to n do
c = a+0.5*(b-a)
fc = f(c)
if fa*fc < 0 then
b = c
fb = fc
else
if fa*fc > 0 then
a = c
fa = fc
else
alpha = c
return
endif
endif
endfor
Example: Consider the function \( f(x) = e^x\, \cos x - x\, \sin x \) that has three nulls on the interval [0,10], and Mathematica confirms
FindRoot[f[x] == 0, {x, 1.5}]
Now we show step by step how it works using Mathematica. First we plot the function to roughly identify the roots.
Plot[f[x], {x, 0, 8}, PlotStyle -> {Thick, Blue}]

Then we define the range of x you want to see the function
curve = Plot[f[x], {x, xa, xb}, PlotLabel -> "Entered function on given interval", LabelStyle -> {FontSize -> 11}];
step = (xb - xa)/10;
x[0] = xa;
Do[ x[i] = x[i - 1] + step; If[f[x[i]] > maxi, maxi = f[x[i]]; If[f[x[i]] < mini, mini = f[x[i]]]];
Print["i= ", i, ", x[i]= ", x[i], ", f[x[i]]= ", N[f[x[i]]]]; , {i, 1, 10}]
Show[Graphics[Line[{{xa, maxi}, {xa, mini}}]], curve, Graphics[Line[{{xb, maxi}, {xb, mini}}]], Axes -> True,
PlotLabel -> "Entered function on given interval with upper and lower guesses",
LabelStyle -> {FontSize -> 11}, PlotRange -> {{0.25, 2}, {-1.3, 0.6}}]

If[f[xa]*f[xc] <= 0, xb = xc]
N[f[xb]]
-0.472425
Graphics[Line[{{3/2, maxi}, {3/2, mini/2}}]],
Graphics[Line[{{27/20, maxi}, {27/20, mini/2}}]], Axes -> True,
PlotLabel -> "Entered function on given interval with upper and lower guesses
and estimated root", LabelStyle -> {FontSize -> 10}, PlotRange -> {{0.5, 1.8}, {-0.6, 0.2}}]

N[xc]
1.275
If[f[xa]*f[xc] <= 0, xb = xc]
Graphics[Line[{{3/2, maxi}, {3/2, mini/4}}]],
Graphics[Line[{{51/40, maxi}, {51/40, mini/4}}]],
Graphics[Line[{{27/20, maxi}, {27/20, mini/4}}]], Axes -> True,
PlotLabel -> "Function on given interval with estimated root",
LabelStyle -> {FontSize -> 10}, PlotRange -> {{0.8, 1.7}, {-0.35, 0.1}}]

Here the bisection method algorithm is applied to generate the values of the roots, true error, absolute relative true error, approximate error, absolute relative approximate error, and the number of significant digits at least correct in the estimated root as a function of number of iterations.
For[i = 1; xu = xb; xl = xa, i <= nmaximum, i++, xr[i] = (xu + xl)/2;
If[f[xr[i]]*f[xu] <= 0, xl = xr[i], xu = xr[i]]]
s = FindRoot[Exp[x]*Cos[x] - x*Sin[x] == 0, {x, 1.2}]
xactual = Evaluate[x /. s]
For[i = 1, i <= nmaximum, i++, Et[i] = Abs[xactual - xr[i]]]
For[i = 1, i <= nmaximum, i++, et[i] = Abs[Et[i]/xactual*100]]
For[i = 1, i <= nmaximum, i++, If[i <= 1, Ea[i] = 0, Ea[i] = Abs[xr[i] - xr[i - 1]]]]
For[i = 1, i <= nmaximum, i++, If[i <= 1, ea[i] = 0, ea[i] = Abs[Ea[i]/xr[i]*100]]]
For[i = 1, i <= nmaximum, i++,
If[(ea[i] >= 5) || (i <= 1), sigdig[i] = 0,
sigdig[i] = Floor[(2 - Log[10, Abs[ea[i]/0.5]])]]]
ListPlot[xrplot, Joined -> True, PlotRange -> All,
AxesOrigin -> {1, Min[xrplot]},
PlotLabel -> "Estimated root as a function of number of iterations"]

ListPlot[Etplot, Joined -> True, PlotRange -> All,
AxesOrigin -> {1, Min[Etplot]},
PlotLabel -> "Absolute true error as a function of number of iterations"]

ListPlot[etplot, Joined -> True, PlotRange -> All,
AxesOrigin -> {1, Min[etplot]},
PlotLabel -> "Absolute relative true error as a function of number of iterations"]

ListPlot[Eaplot, Joined -> True, PlotRange -> All,
AxesOrigin -> {1, Min[Eaplot]}, PlotLabel ->
"Absolute approximate error as a function of number of iterations"]

ListPlot[eaplot, Joined -> True, PlotRange -> All,
AxesOrigin -> {1, Min[eaplot]}, PlotLabel ->
"Absolute relative approximate error as a function of number of iterations"]

BarChart[sigdigplot]

We present some scripts for application of bisection method.
Module[{interval}, interval = {a, (a + b)/2, b};
Last@Flatten[ Select[Thread@(Partition[#, 2, 1] & /@ {Sign /@ (func /@ interval), interval}),
Times @@ (First@#) < 0 &], 1]]
(*===================================================\[Equal]*)
biSection[func_, {a0_?NumericQ, b0_?NumericQ}, \[Xi]_?NumericQ] :=
NestWhile[shrinkInterval[func, #] &, {a0, b0}, Abs@(Subtract @@ #) > \[Xi] &]
a[1] = 0;
b[1] = 3;
Do[p[n] = N[1/2 (a[n] + b[n])];
If[N[f[b[n]] f[p[n]]] < 0, a[n + 1] = p[n]; b[n + 1] = b[n],
a[n + 1] = a[n]; b[n + 1] = p[n]], {n, 1, 20}]
TableForm[ Table[{a[n], b[n], p[n], N[f[a[n]]], N[f[b[n]]], N[f[p[n]]]}, {n, 1, 20}]]
f[x_] = Exp[x]*Cos[x] - x*Sin[x]
Plot[f[x], {x, 0, 9}];
a = Input["Enter a"];
b = Input["Enter b"];
tol = Input["Enter tolerance"];
n = Input["Enter total iteration"]; If[f[a]*f[b] > 0, {Print["No solution exists"] Exit[]}];
Print[" n a b c f(c)"];
Do[{c = (a + b)/2; If[f[a]*f[c] > 0, a = c, b = c],
Print[PaddedForm[i, 5], PaddedForm[N[a], {10, 6}], PaddedForm[N[b], {10, 6}], PaddedForm[N[c], {10, 6}], PaddedForm[N[f[c]], {10, 6}]]
If[ Abs[a - b] < tol, {Print["The solution is: ", c] Exit[]}]}, {i, 1, n}]; Print["The maximum iteration failed"];
II. False Position Method
The poor convergence of the bisection method as well as its poor adaptability to higher dimensions (i.e., systems of two or more non-linear equations) motivate the use of better techniques. Another popular algorithm is the method of false position or the regula falsi method. A better approach is obtained if we find the point c on the abscissa where the secant line crosses it. To determine the value of c, we write down two versions of the slope m f the line that connects the points \( (a, f(a)) \quad\mbox{and} \quad (b, f(b)) : \)
- If f(a) and f(c) have opposite signs, a zero lies in [a,c] .
- If f(b) and f(c) have opposite signs, a zero lies in [c,b] .
- If \( f(c) =0 , \) then the zero is c.
Example: We reconsider the function \( f(x) = e^x\, \cos x - x\, \sin x \) on interval [0,3]. From the previous example, we know that f has the null r = 1.22539. We ask Mathematica for help:
a = Input["Enter a"];
b = Input["Enter b"];
tol = Input["Enter tolerance"];
n = Input["Enter total iteration"];
x0 = a;
x1 = b;
If[f[x0]*f[x1] > 0, {Print["There is no root in this interval"], Exit[]}];
Print[" n x0 x1 x2 f(x2)"];
Do[x2 = x0 - (f[x0]/(f[x1] - f[x0]))*(x1 - x0) // N;
Print[PaddedForm[i, 5], PaddedForm[x0, {12, 6}],
PaddedForm[x1, {12, 6}],
PaddedForm[x2, {12, 6}], PaddedForm[f[x2], {12, 6}]];
If[Abs[x2 - x1] < tol || Abs[x2 - x0] < tol, {Print["The root is: ", x2], Exit[]}];
If[f[x0]*f[x2] > 0, x0 = x2, x1 = x2], {i, 1, n}];
Print["Maximum iteration failed"];
III. Ridders’ Method
A powerful variant on false position is due to Ridders (Ridders, C.J.F. 1979, IEEE Transactions on Circuits and Systems, vol. CAS-26, pp. 979–980). When a root is bracketed between x1 and x2. Ridders’ method first evaluates the function at the midpoint \( x_3 = \left( x_1 + x_2 \right) /2 . \) It then factors out that unique exponential function which turns the residual function into a straight line. Specifically, it solves for a factor eQ that gives
IV. Location of Roots
To roughly estimate the locations of the roots of the equation \( f(x) =0 \) over the interval [a,b], it make sense to make a uniform partition of the interval by sample points \( \left( x_n , y_n = f(x_n )\right) \) and use the following criteria:
Return to Mathematica page
Return to the main page (APMA0330)
Return to the Part 1 (Plotting)
Return to the Part 2 (First Order ODEs)
Return to the Part 3 (Numerical Methods)
Return to the Part 4 (Second and Higher Order ODEs)
Return to the Part 5 (Series and Recurrences)
Return to the Part 6 (Laplace Transform)
Return to the Part 7 (Boundary Value Problems)