ASKSAGE: Sage Q&A Forum - Individual question feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 30 Mar 2011 10:14:21 -0500How can I speed up symbolic function evaluation?https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/I have a few hundred lines of code that calculate a system of ODEs. The resulting system of several hundred to several thousand equations take a *long* time to integrate. (I'm using SciPy's integrate interface; testing on a small case suggested it's several times faster than GSL's ode_solver for my problem.)
Of course, most of the time is spent in evaluating my equations. I'm already using fast_callable to speed up the calculations. It made a wonderful difference. But it's still taking hours or even days for the larger systems. I want to put this integration inside an optimizer, so any speed gain is great.
Stealing the example from the reference manual (http://www.sagemath.org/doc/numerical_sage/scipy.html), I'm currently doing something like the following.
import scipy
from scipy import integrate
var('x, y')
mu = 10.0
dy = (y, -x + mu*y*(1-x**2))
dy_fc = tuple(fast_callable(expr, domain=float, vars=(x,y)) for expr in dy)
def f_1(y,t):
return [f(*y) for f in dy_fc]
xx=scipy.arange(0,100,.1)
yy=integrate.odeint(f_1,[1,0],xx)
I don't think I can speed up the integrate routine. Can I do anything to speed up `f_1`?
Thanks!
Sat, 12 Mar 2011 12:39:56 -0600https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/Answer by kcrisman for <p>I have a few hundred lines of code that calculate a system of ODEs. The resulting system of several hundred to several thousand equations take a <em>long</em> time to integrate. (I'm using SciPy's integrate interface; testing on a small case suggested it's several times faster than GSL's ode_solver for my problem.)</p>
<p>Of course, most of the time is spent in evaluating my equations. I'm already using fast_callable to speed up the calculations. It made a wonderful difference. But it's still taking hours or even days for the larger systems. I want to put this integration inside an optimizer, so any speed gain is great.</p>
<p>Stealing the example from the reference manual (<a href="http://www.sagemath.org/doc/numerical_sage/scipy.html">http://www.sagemath.org/doc/numerical...</a>), I'm currently doing something like the following.</p>
<pre><code>import scipy
from scipy import integrate
var('x, y')
mu = 10.0
dy = (y, -x + mu*y*(1-x**2))
dy_fc = tuple(fast_callable(expr, domain=float, vars=(x,y)) for expr in dy)
def f_1(y,t):
return [f(*y) for f in dy_fc]
xx=scipy.arange(0,100,.1)
yy=integrate.odeint(f_1,[1,0],xx)
</code></pre>
<p>I don't think I can speed up the integrate routine. Can I do anything to speed up <code>f_1</code>?</p>
<p>Thanks!</p>
https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?answer=12184#post-id-12184You may be able to use [Cython](http://www.cython.org) to speed up such things. In order to do so most efficiently, you'd want to `cdef` certain data types (for instance, the outputs of `dy_fc`?) and the function you are using.
I'm not at all a Cython expert, though; I know it really depends on the specifics of your use case, and of course `fast_callable` is already pretty nice. Here are random links which could conceivably help (or not):
- [Cython for Numpy users](http://wiki.cython.org/tutorials/numpy)
- [Sage and Cython](http://openwetware.org/wiki/Open_writing_projects/Sage_and_cython_a_brief_introduction)
- [Cython documentation](http://docs.cython.org/)
- [This ask.sagemath question](http://ask.sagemath.org/question/12/short-cython-example-in-a-notebook-cell)
Good luck!Sat, 12 Mar 2011 12:57:05 -0600https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?answer=12184#post-id-12184Answer by Joaquim Puig for <p>I have a few hundred lines of code that calculate a system of ODEs. The resulting system of several hundred to several thousand equations take a <em>long</em> time to integrate. (I'm using SciPy's integrate interface; testing on a small case suggested it's several times faster than GSL's ode_solver for my problem.)</p>
<p>Of course, most of the time is spent in evaluating my equations. I'm already using fast_callable to speed up the calculations. It made a wonderful difference. But it's still taking hours or even days for the larger systems. I want to put this integration inside an optimizer, so any speed gain is great.</p>
<p>Stealing the example from the reference manual (<a href="http://www.sagemath.org/doc/numerical_sage/scipy.html">http://www.sagemath.org/doc/numerical...</a>), I'm currently doing something like the following.</p>
<pre><code>import scipy
from scipy import integrate
var('x, y')
mu = 10.0
dy = (y, -x + mu*y*(1-x**2))
dy_fc = tuple(fast_callable(expr, domain=float, vars=(x,y)) for expr in dy)
def f_1(y,t):
return [f(*y) for f in dy_fc]
xx=scipy.arange(0,100,.1)
yy=integrate.odeint(f_1,[1,0],xx)
</code></pre>
<p>I don't think I can speed up the integrate routine. Can I do anything to speed up <code>f_1</code>?</p>
<p>Thanks!</p>
https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?answer=12236#post-id-12236In my opinion, the funcion desolve_odeint (in versions >=4.6) provides what you want. Basically it takes a symbolic expression as the vector field, it compiles it to a fast float expression and then integrates it using the scipy.odeint solver. I have never used with hundreds of variables, but let us know your experiences...
In your case I would do the following:
sage: var('x, y')
sage: mu = 10.0
sage: dy = (y, -x + mu*y*(1-x**2))
sage: dy_fc = [expr for expr in dy]
sage: xx=srange(0,50.05,0.001) # I would plot more points
sage: ics=[1.0,0.0]
sage: sol=desolve_odeint(dy_fc,ics,xx,[x,y])
and if you want a nice plot
sage: line(sol)+plot_vector_field(dy_fc,(x,-2,2),(y,-15,15))Tue, 29 Mar 2011 23:05:10 -0500https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?answer=12236#post-id-12236Comment by kcrisman for <p>In my opinion, the funcion desolve_odeint (in versions >=4.6) provides what you want. Basically it takes a symbolic expression as the vector field, it compiles it to a fast float expression and then integrates it using the scipy.odeint solver. I have never used with hundreds of variables, but let us know your experiences...</p>
<p>In your case I would do the following: </p>
<pre><code>sage: var('x, y')
sage: mu = 10.0
sage: dy = (y, -x + mu*y*(1-x**2))
sage: dy_fc = [expr for expr in dy]
sage: xx=srange(0,50.05,0.001) # I would plot more points
sage: ics=[1.0,0.0]
sage: sol=desolve_odeint(dy_fc,ics,xx,[x,y])
</code></pre>
<p>and if you want a nice plot</p>
<pre><code>sage: line(sol)+plot_vector_field(dy_fc,(x,-2,2),(y,-15,15))
</code></pre>
https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?comment=21937#post-id-21937But didn't the original poster already use scipy.odeint and fast_callable/fast_float? Let's hope it works, though!Wed, 30 Mar 2011 10:14:21 -0500https://ask.sagemath.org/question/7993/how-can-i-speed-up-symbolic-function-evaluation/?comment=21937#post-id-21937