I'm trying to optimize some python code, which uses scipy.optimize.root for rootfinding.
cProfile tells me that most of the time the programm is evaluating the function called by optimize.root:
e.g. for a total execution time of 80s, 58s are spend on lineSphericalDist to which fun contributes 54s (and about 215 000 calls):
Fri Aug 8 21:09:32 2014 profile2
12796193 function calls (12617458 primitive calls) in 82.707 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.005 0.005 82.710 82.710 BilliardsNumpyClass.py:6(<module>)
1 0.033 0.033 64.155 64.155 BilliardsNumpyClass.py:446(traceAll)
100 1.094 0.011 63.549 0.635 BilliardsNumpyClass.py:404(trace)
91333 7.226 0.000 58.804 0.001 BilliardsNumpyClass.py:244(lineSphericalDist)
214667 49.436 0.000 54.325 0.000 BilliardsNumpyClass.py:591(fun)
...
Here the optimize.root call somehwere in trace:
...
res = optimize.root(self.lineSphericalDist, [tguess], args=(t0, a0), method='lm')
...
The function contains of some basic trigonometric functions:
def lineSphericalDist(self, tt, t0, a0):
x0,y0,vnn = self.fun(t0)[0:3]
beta = np.pi + t0 + a0 - vnn
l = np.sin(beta - t0)/np.sin(beta - tt)
x2,y2 = self.fun(tt)[0:2]
return np.sqrt(x0**2+y0**2)*l-np.sqrt(x2**2+y2**2)
In the easiest case fun is:
def fun(self,t):
return self.r*np.cos(t),self.r*np.sin(t),np.pi/2.,np.mod(t+np.pi/2., np.pi*2.)
Is there a way to speed this up (tguess is already a pretty good starting value) ? Am I doing something wrong? e.g. is it a good idea to return multiple values the way I do it in fun ?
trace(), therefore you should find alternatives tooptimize.root()in order to get a speed improvement...