Untitled
unknown
python
4 years ago
6.8 kB
7
Indexable
from functools import total_ordering
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import expm
from scipy import integrate
a = 3
b = 9
c = 15
d = 15
lamb = 1
def testeq(_,u): #
l = np.array([[lamb]])
return l*u
def testeqnbr(_,u): #
return lamb*u
def solution(y0, tg):
l = np.array([[lamb]])
return np.array([np.dot(np.exp(l*t), y0) for t in tg])
def RK34Step(f, told, uold, h):
unew = RK4Step(f, told, uold, h)
hY1 = h*f(told,uold)
hY2 = h*f(told+h/2, uold+hY1/2)
hY3 = h*f(told+h/2, uold+hY2/2)
hY4 = h*f(told+h, uold+hY3)
hZ3 = h* f(told + h, uold - hY1 + 2*hY2)
err = (2*hY2 + hZ3 -2*hY3 - hY4)/6
return [unew, err]
def RK4Step(f, told, uold, h): #f är lambdauttryck motsvarande, tar in 2 parametrar
hY1 = h*f(told,uold)
hY2 = h*f(told+h/2, uold+hY1/2)
hY3 = h*f(told+h/2, uold+hY2/2)
hY4 = h*f(told+h, uold+hY3)
return uold + (hY1 + 2*hY2 + 2*hY3 + hY4)/6
def newstep(tol, err, errold, hold, k):
return ( (tol/abs(err))**(2/(3*k)) * (tol/abs(errold))**(-1/(3*k)) )*hold
def adaptiveRK34(f, t0, tf, y0, tol):
t = [t0]
y = [y0]
tn = t0
yn = y0
rn = tol
hm = abs(tf-t0)*np.power(tol, 1/4)/(100*(1 + np.linalg.norm(f(None, y0))))
nbrSteps = 0
while(hm < tf - tn):
yn, err = RK34Step(f, tn, yn, hm)
tn= tn+hm
t.append(tn)
y.append(yn)
rold = rn
rn = np.linalg.norm(err)
hm = newstep(tol, rn, rold, hm, 4)
nbrSteps += 1
t.append(tf)
y.append(RK34Step(f, tn, yn, tf - tn)[0] )
nbrSteps += 1
return [np.array(t), np.array(y), nbrSteps]
def RK4Solve(f, t0, tf, y0, N):
tg = np.linspace(t0,tf,N+1)
h =(tf-t0)/N
approx=np.array([y0])
yn = y0
tn = t0
for _ in range(N):
yn = RK4Step(f, tn, yn, h)
tn = tn+h
approx = np.append(approx, yn)
err = solution(y0, tg) - approx
return [tg, approx, err]
def lotkaVolterraSolver():
u_f0 = np.array([1,1])
u2_f0 = np.array([1.7, 0.1])
tol = 1e-7
tmax = 100
lotka = lambda t, u: np.array([a*u[0] - b*u[0]*u[1], c*u[0]*u[1] - d*u[1] ])
[t, y, _] = adaptiveRK34(lotka, 0, tmax, u_f0, tol)
[t2, y2, _] = adaptiveRK34(lotka, 0 , tmax, u2_f0, tol)
title = "Solution to initial condition over time t with u_f0 = [ "
add = ",".join(str(x) for x in u_f0)
add2 = ",".join(str(x) for x in u2_f0)
figure, axis = plt.subplots(2,2)
axis[0, 0].plot(t, y)
axis[0, 0].set_title(title + add + " ]")
axis[0, 1].plot(y[:,0], y[:,1], 'm')
axis[0, 1].set_title("Phase portrait when u_f0 = [ " + add + " ]")
axis[1, 0].plot(t2, y2)
axis[1, 0].set_title(title + add2 + " ]")
axis[1, 1].plot(y2[:,0], y2[:,1], 'm')
axis[1, 1].set_title("Phase portrait when u_f0 = [ " + add2 + " ]")
plt.show()
plt.figure(2)
plt.title("H:s change over time")
plt.semilogy(t, [abs(H(u ,a ,b ,c ,d)/H(u_f0 , a, b ,c ,d) - 1) for u in y], 'r')
plt.show()
def H(u, *parameters):
x, y = u
a, b, c, d = parameters
sol = c*x + b*y - d*np.log(x) - a*np.log(y)
return sol
def errVSh(f, t0, tf, y0):
nbr = 11
N = 2**np.linspace(1, nbr, num=nbr, dtype=int)
h = np.divide(tf-t0, N)
E = []
for n in N:
_, _, err = RK4Solve(f,t0,tf,y0,n)
E.append(np.linalg.norm(err[-1][-1])) #ska vara två [][] för matris!!!!!!!!
plt.figure(1)
plt.loglog(h,E)
plt.loglog(h, h**4)
plt.title("Error plot")
plt.show()
def task1Solver():
y0 = np.array([1])
t0 = 0
tf = 1
[tg, app, err] = RK4Solve(testeq,t0,tf,y0, 100)
print(err)
errVSh(testeq, 0 ,1 ,y0)
t = np.linspace(0, 1 ,1000)
plt.figure(2)
plt.plot(tg, app, 'k')
plt.plot(t, solution(y0,t), 'r--' )
plt.show()
t,y = adaptiveRK34(testeqnbr, 0, 1, 1, 10**(-6))
tbig = np.linspace(0,1,1000)
plt.plot(t,y)
plt.plot(tbig, solution(np.array([1]), tbig))
plt.show()
def VanDerPolSolver():
mu = 100
tol = 1e-7
t0 = 0
tf = 300
u_f0 = np.array([2, 0])
u2_f0 = np.array([3 , 1])
vanDerPol = lambda t, u: np.array([u[1] , mu*(1-u[0]**2)*u[1] -u[0] ])
[t, y , _] = adaptiveRK34(vanDerPol, t0, tf, u_f0, tol)
[t2, y2, _] = adaptiveRK34(vanDerPol, t0, 3*tf, u2_f0, tol)
title = "Solution to initial condition over time t with u_f0 = [ "
add = ",".join(str(x) for x in u_f0)
add2 = ",".join(str(x) for x in u2_f0)
figure, axis = plt.subplots(2,2)
axis[0, 0].plot(t, y[:,1])
axis[0, 0].set_title(title + add + " ]")
axis[0, 1].plot(y[:,0], y[:,1], 'm')
axis[0, 1].set_title("Phase portrait when u_f0 = [ " + add + " ]")
axis[1, 0].plot(t2, y2[:,1], 'r')
axis[1, 0].set_title(title + add2 + " ]")
axis[1, 1].plot(y2[:,0], y2[:,1], 'm')
axis[1, 1].set_title("Phase portrait when u_f0 = [ " + add2 + " ]")
plt.show()
#Task 3.2
def VanDerPol32():
muus = np.array([10, 15, 22, 33, 47, 68, 100, 150, 220, 330, 470, 680, 1000]) #1000 läggs till så blir det 13 fönster
tol = 1e-7
t0 = 0
tf = 50
u_f0 = np.array([2, 0])
Ns = []
Ns2 = []
for i in range (0, 13,1):
vanDerPol = lambda t, u: np.array([u[1] , muus[i]*(1-u[0]**2)*u[1] -u[0] ])
_, _, nbr = adaptiveRK34(vanDerPol, t0, tf, u_f0, tol)
Ns.append(nbr)
sol = integrate.solve_ivp(vanDerPol, [t0,tf], u_f0, method='BDF' )
implicit = len(sol.t) - 1
Ns2.append(implicit)
print(Ns)
print(Ns2)
plt.figure(1)
plt.plot(muus,Ns, 'm')
plt.plot(muus, Ns2, 'b')
plt.title("Stiffness: Number of Steps Against Müh")
plt.show()
#Task 3.3 only
muus2 = np.array([10, 15, 22, 33, 47, 68, 100, 150, 220, 330, 470, 680, 1000, 4000, 10000])
print(muus2)
vanDerPol4000 = lambda t, u: np.array([u[1] , 4000*(1-u[0]**2)*u[1] -u[0] ])
sol4000 = integrate.solve_ivp(vanDerPol4000, [t0,tf], u_f0, method='BDF' )
implicit = len(sol4000.t) - 1
Ns2.append(implicit)
vanDerPol10000 = lambda t, u: np.array([u[1] , 10000*(1-u[0]**2)*u[1] -u[0] ])
sol10000 = integrate.solve_ivp(vanDerPol10000, [t0,tf], u_f0, method='BDF' )
implicit = len(sol10000.t) - 1
Ns2.append(implicit)
plt.figure(2)
plt.semilogy(muus2, Ns2)
plt.title("Only implicit BDF Method")
plt.show()
if __name__ == '__main__':
# task1Solver()
# lotkaVolterraSolver()
# VanDerPolSolver()
VanDerPol32()
Editor is loading...