-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbisection_method.py
More file actions
57 lines (50 loc) · 2.13 KB
/
Copy pathbisection_method.py
File metadata and controls
57 lines (50 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# @source: https://github.com/lihiSabag/Numerical-Analysis-2023.git
import math
import numpy as np
from colors import bcolors
"""
Receives 3 parameters:
1. a - start value.
2. b - end value.
3. err - value of tolerable error
Returns variables:
1. S - The minimum number of iterations required to reach the desired accuracy
"""
def max_steps(a, b, err):
s = int(np.floor(- np.log2(err / (b - a)) / np.log2(2) - 1))
return s
"""
Performs Iterative methods for Nonlinear Systems of Equations to determine the roots of the given function f
Receives 4 parameters:
1. f - continuous function on the interval [a, b], where f (a) and f (b) have opposite signs.
2. a - start value.
3. b - end value.
4. tol - the tolerable error , the default value will set as 1e-16
Returns variables:
1. c - The approximate root of the function f
"""
def bisection_method(f, a, b, tol=1e-6):
if np.sign(f(a)) == np.sign(f(b)):
raise ValueError("The scalars a and b do not bound a root")
c, k = 0, 0
steps = max_steps(a, b, tol) # calculate the max steps possible
print("{:<10} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15}".format("Iteration", "a", "b", "f(a)", "f(b)", "c", "f(c)"))
# while the diff af a&b is not smaller than tol, and k is not greater than the max possible steps
while abs(b - a) > tol and k < steps:
c = a + (b - a) / 2 # Calculation of the middle value
if f(c) == 0:
return c # Procedure completed successfully
if f(c) * f(a) < 0: # if sign changed between steps
b = c # move forward
else:
a = c # move backward
print("{:<10} {:<15.6f} {:<15.6f} {:<15.6f} {:<15.6f} {:<15.6f} {:<15.6f}".format(k, a, b, f(a), f(b), c, f(c)))
k += 1
return c # return the current root
if __name__ == '__main__':
fun = lambda x: x**2 - 4 * math.sin(x)
try:
roots = bisection_method(fun, 1, 3)
print(bcolors.OKBLUE, f"\nThe equation f(x) has an approximate root at x = {roots}",bcolors.ENDC,)
except ValueError as e:
print(str(e))