-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrootAlgo.py
executable file
·91 lines (83 loc) · 3.19 KB
/
rootAlgo.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
# Functions implementing root finding algorithms
import scipy
import scipy.linalg
import difCal
def ScaNewRapSolve(fun, x0, funD = None, tol=0.5e-5, miniter = 1, maxiter=100, h =0.1e-5):
'''
Uses Newton Raphson algorithm to calculate a root x of the given scalar
function: fun(x) = 0
'''
#Initializations
i = 0
newx = x0
funEva = fun(newx)
if funD == None:
derEva = difCal.NumDerivative(fun,newx,h)
else:
derEva = funD(newx)
# Iterate for i less than maxiter and fun(x)>tol
while(i<miniter or (i<maxiter and abs(funEva)>tol)):
newx = newx - funEva/derEva
funEva = fun(newx)
if funD == None:
derEva = difCal.NumDerivative(fun,newx,h)
else:
derEva = funD(newx)
i = i+1
#print '[ScaNewRapSolve] Iteration ', str(i),', newx = ', str(newx),', funEva = ', str(funEva)
if i == maxiter:
Warning('[ScaNewRapSolve] Convergence not attained for the initial value, tolerance and maxiter given')
return None
else:
return newx
def VecNewRapSolve(funVec, X0, funjac = None, tol=0.1e-5, miniter = 1, maxiter=100, h =0.1e-5):
'''
Uses Newton Raphson algorithm to calculate a vector root X of the given vector
function: funVec(X) = (0,...,0)
'''
#Initializations
i=0
newX = scipy.array(X0)
funVecEva = funVec(newX)
if funjac == None:
jacEva = difCal.NumJacobian(funVec,newX,h)
else:
jacEva = funjac(newX)
#Check for correct size relations for X0 and jac if given
if (len(X0),len(X0)) != jacEva.shape:
raise ValueError, '[VecNewRapSolve] Sizes of the jacobian given are not correct'
tolerr = False
for i in range(len(funVecEva)):
if abs(funVecEva[i]) > tol:
tolerr = True
i=0
# Iterate for i less than maxiter and funVec(X)>tol
while(i<miniter or (i<maxiter and tolerr)):
for j in range(len(jacEva)):
for k in range(len(jacEva)):
if str(jacEva[j][k])=='' or str(jacEva[j][k])=='nan':
Warning('[VecNewRapSolve] Undefined jacobian encountered. Try with different values')
return None
if scipy.linalg.det(jacEva) == 0.:
Warning('[VecNewRapSolve] Non invertible jacobian encountered. Try a different initial value')
return None
else:
invJac = scipy.linalg.inv(jacEva)
newXlast = newX
newX = newXlast - scipy.dot(invJac,funVecEva)
funVecEva = scipy.array(funVec(newX))
if funjac == None:
jacEva = difCal.NumJacobian(funVec,newX,h)
else:
jacEva = funjac(newX)
i = i+1
#print '[VecNewRapSolve] Iteration ', str(i),', newX = ', str(newX),', funEva = ', funVecEva,'jacEva=',jacEva
tolerr = False
for j in range(len(funVecEva)):
if abs(funVecEva[j]) > tol:
tolerr = True
if i == maxiter:
Warning('[VecNewRapSolve] Convergence not attained for the initial value, tolerance and maxiter given')
return None
else:
return newX