-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBisection.py
139 lines (102 loc) · 3.31 KB
/
Bisection.py
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from matplotlib import pyplot
import numpy as np
from tabulate import tabulate as tb
def func(x):
return x / (1 - x) * ((2 * 3 / (2 + x))) ** 0.5 - 0.05
def showGraph():
x = np.linspace(-5, 5, 1000)
x = list(x)
y = []
for i in x:
y.append(func(i))
for i in range(len(y) - 1):
if i > 0 and abs(y[i] - y[i - 1] > 10):
x[i - 1] = np.nan
x[i - 1] = np.nan
print('Take a closer look at the graph and find the limits around the root.')
pyplot.plot(x, y)
pyplot.xlabel('x')
pyplot.ylabel('y')
pyplot.ylim(-10, 15)
pyplot.title('x / (1 - x) * sqrt(2 * 3 / (2 + x)) - 0.05 = 0')
pyplot.grid(True, which='both')
pyplot.show()
def bisection(low, high, error, maxIteration=100):
iteration = 1
isFirstIteration = True
midOld = 0.0
e = 100 # initializing with 100% error
while True:
mid = (low + high) / 2 * 1.0
if isFirstIteration == False:
e = abs((mid - midOld) / mid) * 100
midOld = mid;
isFirstIteration = False
if func(high) * func(mid) == 0:
return mid
if func(high) * func(mid) < 0:
low = mid
else:
high = mid
iteration += 1
if e <= error:
return mid
if iteration > maxIteration and e > error:
print('Max iteration reached but could not reach sufficiently close to the root.')
print('Returning the root which has an error of:', e, '%')
return mid
def bisectionTable(low, high, error, maxIteration=20):
iteration = 1
isFirstIteration = True
midOld = 0.0
table = [[]]
while True:
mid = (low + high) / 2 * 1.0
if isFirstIteration == False:
e = abs((mid - midOld) / mid) * 100
table.append([iteration, mid, e])
else:
table = [[iteration, mid, 'N/A']]
midOld = mid;
isFirstIteration = False
if func(high) * func(mid) < 0:
low = mid
else:
high = mid
iteration += 1
if iteration > maxIteration:
break
print(tb(table, headers=['Iteration', 'value of root', '|error| %'], tablefmt='orgtbl'))
# ---------------------DEMONSTRATION BELOW-----------------------------#
showGraph()
x_l = input('Enter the lower limit:\n')
x_u = input('Enter the upper limit:\n')
approxError = input('Enter the approximation error:\n')
maxIteration = input('Enter the max iteration:\n')
x_u = float(x_u)
x_l = float(x_l)
approxError = float(approxError)
maxIteration = float(maxIteration)
# division by zero handling
if (x_l == 1):
x_l = 1.00000000001
if (x_u == 1):
x_u = 1.00000000001
if (x_l < -2):
x_l = -1.9999999999999
if (x_u < -2):
x_u = -1.9999999999999
# division by zero handling
while func(x_l) * func(x_u) > 0:
showGraph()
x_l = input('Enter the lower limit:\n')
x_u = input('Enter the upper limit:\n')
approxError = input('Enter the approximation error:\n')
maxIteration = input('Enter the max iteration:\n')
x_u = float(x_u)
x_l = float(x_l)
approxError = float(approxError)
maxIteration = float(maxIteration)
root = bisection(x_l, x_u, approxError, maxIteration)
print('Approximate value of the root =', root)
bisectionTable(x_l, x_u, approxError, maxIteration)