I am using the attached code to integrate a version of Fitzhugh-Nagumo model :
from scipy.integrate import odeint
import numpy as np
import time
P = {'epsilon':0.1,
'a1':1.0,
'a2':1.0,
'b':2.0,
'c':0.2}
def fhn_rhs(V,t,P):
u,v = V[0],V[1]
u_t = u - u**3 - v
v_t = P['epsilon']*(u - P['b']*v - P['c'])
return np.stack((u_t,v_t))
def integrate(func,V0,t,args,step='RK4'):
start = time.clock()
P = args[0]
result=[V0]
for i,tmp in enumerate(t[1:]):
result.append(RK4step(func,result[i],tmp,P,(t[i+1]-t[i])))
print "Integration took ",time.clock() - start, " s"
return np.array(result)
def RK4step(rhs,V,t,P,dt):
k_1 = dt*rhs(V,t,P)
k_2 = dt*rhs((V+(1.0/2.0)*k_1),t,P)
k_3 = dt*rhs((V+(1.0/2.0)*k_2),t,P)
k_4 = dt*rhs((V+k_3),t,P)
return V+(1.0/6.0)*k_1+(1.0/3.0)*k_2+(1.0/3.0)*k_3+(1.0/6.0)*k_4
Comparing between my integrate
and scipy.integrate.odeint
gives the following:
In [8]: import cProfile
In [9]: %timeit integrate(fhn_rhs,np.stack((0.1,0.2)),np.linspace(0,100,1000),args=(P,))
10 loops, best of 3: 36.4 ms per loop
In [10]: %timeit odeint(fhn_rhs,np.stack((0.1,0.2)),np.linspace(0,100,1000),args=(P,))
100 loops, best of 3: 3.45 ms per loop
In [11]: cProfile.run('integrate(fhn_rhs,np.stack((0.1,0.2)),np.linspace(0,100,1000),args=(P,))')
45972 function calls in 0.098 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.098 0.098 <string>:1(<module>)
3996 0.011 0.000 0.078 0.000 fhn.py:20(fhn_rhs)
1 0.002 0.002 0.097 0.097 fhn.py:42(integrate)
999 0.016 0.000 0.094 0.000 fhn.py:52(RK4step)
1 0.000 0.000 0.000 0.000 function_base.py:9(linspace)
7994 0.011 0.000 0.021 0.000 numeric.py:484(asanyarray)
3997 0.029 0.000 0.067 0.000 shape_base.py:282(stack)
11991 0.008 0.000 0.008 0.000 shape_base.py:337(<genexpr>)
3997 0.002 0.000 0.002 0.000 {len}
999 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'astype' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.arange}
7995 0.010 0.000 0.010 0.000 {numpy.core.multiarray.array}
3997 0.006 0.000 0.006 0.000 {numpy.core.multiarray.concatenate}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.result_type}
Any suggestions on how I can make my code run faster? Can I use numba
somehow to accelerate it?
timeit
? – Subjectifyh
with one parallel step of size2h
and use Richardson extrapolation for the error. – Subjectify