|
|
Example:
Function: f(x) = x2 - 4
Roots: x = -2, x = 2
Because:
f(-2) = (-2)2 - 4 = 4 - 4 = 0
f(2) = (2)2 - 4 = 4 - 4 = 0
|
|
(We can use the property sign of f(a) ≠ sign of f(b) to find such an initial interval)
The root is then approximately equal to any value in the final (very small) interval.
|
In other cases, we may need to changed the end point b to obtain a smaller interval that still contains a root
Here is an example where you have to change the end point a:
|
There is a root between [0,4] because::
f(0) = 02 − 5 = −5
f(4) = 42 − 5 = 11
Start:
a = 0; f(a) = -5
b = 4; f(b) = 11
Iteration 1:
m = (a + b)/2 = 2
f(m) = 22 − 5 = -1
Because f(m) < 0, we replace a with m
a = 2; f(a) = -1
b = 4; f(b) = 11
Iteration 2:
m = (a + b)/2 = 3
f(m) = 32 − 5 = 4
Because f(m) > 0, we replace b with m
a = 2; f(a) = -1
b = 3; f(b) = 4
Iteration 3:
m = (a + b)/2 = 2.5
f(m) = 2.52 − 5 = 1.25
Because f(m) > 0, we replace b with m
a = 2; f(a) = -1
b = 2.5; f(b) = 1.25
And so on....
|
Given: interval [a..b] such that: sign of f(a) ≠ sign of f(b) |
Re-writing the pseudo code in term of a while-statement:
Given: interval [a..b] such that: sign of f(a) ≠ sign of f(b) |
|
|
Steps taken by the Bisection Method:
|
// Bisection Method - Solves: x^2 - 3 = 0
public class Bisection01
{
public static void main(String[] args)
{
final double epsilon = 0.00001;
double a, b, m, y_m, y_a;
a = 0; b = 4;
while ( (b-a) > epsilon )
{
m = (a+b)/2; // Mid point
y_m = m*m - 3.0; // y_m = f(m)
y_a = a*a - 3.0; // y_a = f(a)
if ( (y_m > 0 && y_a < 0) || (y_m < 0 && y_a > 0) )
{ // f(a) and f(m) have different signs: move b
b = m;
}
else
{ // f(a) and f(m) have same signs: move a
a = m;
}
System.out.println("New interval: [" + a + " .. " + b + "]");
// Print progress
}
System.out.println("Approximate solution = " + (a+b)/2 );
}
}
|
Output:
Initial interval: [0.0 .. 4.0] New interval: [0.0 .. 2.0] (We did the first 3 by hand above) New interval: [1.0 .. 2.0] New interval: [1.5 .. 2.0] New interval: [1.5 .. 1.75] New interval: [1.625 .. 1.75] New interval: [1.6875 .. 1.75] New interval: [1.71875 .. 1.75] New interval: [1.71875 .. 1.734375] New interval: [1.7265625 .. 1.734375] New interval: [1.73046875 .. 1.734375] New interval: [1.73046875 .. 1.732421875] New interval: [1.7314453125 .. 1.732421875] New interval: [1.73193359375 .. 1.732421875] New interval: [1.73193359375 .. 1.732177734375] New interval: [1.73193359375 .. 1.7320556640625] New interval: [1.73199462890625 .. 1.7320556640625] New interval: [1.732025146484375 .. 1.7320556640625] New interval: [1.7320404052734375 .. 1.7320556640625] New interval: [1.7320480346679688 .. 1.7320556640625] Approximate solution = 1.7320518493652344 |
How to run the program:
|
f(x) = x3 + x - 3
|
in the interval [0..4]
// Solves: x^3 + x - 3 = 0
public class Bisection02
{
public static void main(String[] args)
{
final double epsilon = 0.00001;
double a, b, m, y_m, y_a;
a = 0; b = 4;
while ( (b-a) > epsilon )
{
m = (a+b)/2; // Mid point
y_m = m*m*m + m - 3.0; // y_m = f(m)
y_a = a*a*a + a - 3.0; // y_a = f(a)
if ( (y_m > 0 && y_a < 0) || (y_m < 0 && y_a > 0) )
{ // f(a) and f(m) have different signs: move b
b = m;
}
else
{ // f(a) and f(m) have same signs: move a
a = m;
}
System.out.println("New interval: [" + a + " .. " + b + "]");
}
System.out.println("Approximate solution = " + (a+b)/2 );
}
}
|
How to run the program:
|
This is very inconvenient
y_m = f(m); y_a = f(a); |
When we solve a different function, we make changes to the function definition f()
This is indeed possible in Java...
However, we have not study user-defined methods yet.
But we will get there very soon.