|
|
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.