How can I speed up symbolic function evaluation?

i like this post (click again to cancel)
1
i dont like this post (click again to cancel)

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!

asked Mar 12 '11

Ryan Hinton gravatar image Ryan Hinton
11 3

updated Apr 28 '11

Kelvin Li gravatar image Kelvin Li
453 1 10 17

2 Answers:

i like this answer (click again to cancel)
1
i dont like this answer (click again to cancel)

You may be able to use Cython 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):

Good luck!

link

posted Mar 12 '11

kcrisman gravatar image kcrisman
7802 20 78 170
i like this answer (click again to cancel)
1
i dont like this answer (click again to cancel)

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...

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))
link

posted Mar 30 '11

Joaquim Puig gravatar image Joaquim Puig
171 5 9
But didn't the original poster already use scipy.odeint and fast_callable/fast_float? Let's hope it works, though! kcrisman (Mar 30 '11)

Your answer

Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
Login/Signup to Post

Question tools

Tags:

Stats:

Asked: Mar 12 '11

Seen: 236 times

Last updated: Mar 30 '11

powered by ASKBOT version 0.7.22
Copyright Sage, 2010. Some rights reserved under creative commons license.