-
Notifications
You must be signed in to change notification settings - Fork 199
/
Copy pathnonlinear_solvers.py
94 lines (82 loc) · 2.57 KB
/
nonlinear_solvers.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
import sys
def bisection(f, x_L, x_R, eps, return_x_list=False):
f_L = f(x_L)
if f_L*f(x_R) > 0:
print "Error! Function does not have opposite \
signs at interval endpoints!"
sys.exit(1)
x_M = float(x_L + x_R)/2
f_M = f(x_M)
iteration_counter = 1
if return_x_list:
x_list = []
while abs(f_M) > eps:
if f_L*f_M > 0: # i.e., same sign
x_L = x_M
f_L = f_M
else:
x_R = x_M
x_M = float(x_L + x_R)/2
f_M = f(x_M)
iteration_counter += 1
if return_x_list:
x_list.append(x_M)
if return_x_list:
return x_list, iteration_counter
else:
return x_M, iteration_counter
def Newton(f, dfdx, x, eps, return_x_list=False):
f_value = f(x)
iteration_counter = 0
if return_x_list:
x_list = []
while abs(f_value) > eps and iteration_counter < 100:
try:
x = x - float(f_value)/dfdx(x)
except ZeroDivisionError:
print "Error! - derivative zero for x = ", x
sys.exit(1) # Abort with error
f_value = f(x)
iteration_counter += 1
if return_x_list:
x_list.append(x)
# Here, either a solution is found, or too many iterations
if abs(f_value) > eps:
iteration_counter = -1 # i.e., lack of convergence
if return_x_list:
return x_list, iteration_counter
else:
return x, iteration_counter
def secant(f, x0, x1, eps, return_x_list=False):
f_x0 = f(x0)
f_x1 = f(x1)
iteration_counter = 0
if return_x_list:
x_list = []
while abs(f_x1) > eps and iteration_counter < 100:
try:
denominator = float(f_x1 - f_x0)/(x1 - x0)
x = x1 - float(f_x1)/denominator
except ZeroDivisionError:
print "Error! - denominator zero for x = ", x
sys.exit(1) # Abort with error
x0 = x1
x1 = x
f_x0 = f_x1
f_x1 = f(x1)
iteration_counter += 1
if return_x_list:
x_list.append(x)
# Here, either a solution is found, or too many iterations
if abs(f_x1) > eps:
iteration_counter = -1
if return_x_list:
return x_list, iteration_counter
else:
return x, iteration_counter
from math import log
def rate(x, x_exact):
e = [abs(x_ - x_exact) for x_ in x]
q = [log(e[n+1]/e[n])/log(e[n]/e[n-1])
for n in range(1, len(e)-1, 1)]
return q