On Jul 1, 2012, at 12:23 PM, "Ondřej Čertík" <[email protected]> wrote:
> On Sun, Jul 1, 2012 at 7:54 AM, Aaron Meurer <[email protected]> wrote: >> On Jul 1, 2012, at 1:20 AM, "Ondřej Čertík" <[email protected]> wrote: >> >>> On Sat, Jun 30, 2012 at 7:48 PM, Aaron Meurer <[email protected]> wrote: >>>> On Jun 30, 2012, at 8:38 PM, "[email protected]" >>>> <[email protected]> wrote: >>>> >>>>> Two reasons basically: >>>>> >>>>> - the original lambdify has a very convoluted logic and seems hard to >>>>> maintain (the new one is not that great either, however it does not >>>>> break as easily) (in the commit history one can see how stuff >>>>> completely unrelated to the functionality of lambdify was bolted on >>>>> it) >>>>> >>>>> - there were serious differences between what the docstring says and >>>>> what lambdify does in many corner cases >>>>> >>>>> I have discussed a lot why I dislike the original lambdify back in >>>>> November when I was writing the plotting module. I can bring these >>>>> discussions back if there is interest. I have also documented this in >>>>> details at the beginning of the source file for the new lambdify. It >>>>> would be nice to merge them together, but there is too much cruft in >>>>> the old lambdify so this will be difficult (even useless, I would >>>>> prefer simply removing both lambdify functions and relying on good >>>>> code in sympy for performance, not on some strange combination of >>>>> libraries and eval(str) operations) >>>> >>>> +1 to this. Each function should know how to numerically evaluate >>>> itself using numpy or stdlib math (or whatever), and you should be >>>> able to just do it directly, like expr.evalf(library=numpy) or >>>> something like that. I don't see any reason why that wouldn't work. >>>> eval'ing strings feels like a hack, but actually imo anything that >>>> works by rebuilding the expression tree in some what or another is >>>> inefficient because we already have the expression tree. >>> >>> The idea is quite simple. In SymPy, sin(x)+cos(x) is equivalent to >>> Add(sin(x), cos(x)) and so if you need to evaluate it at x=5, you >>> need to run a couple function calls, recursively, and finally >>> you just call math.sin or math.cos from the Python's math module. >>> >>> Using Python's math module directly, sin(x)+cos(x) is just >>> two function calls and a "+" on two floats. So it is much faster. >>> >>> How can this be done without lambdify()? >> >> I see. So basically one has to convert the SymPy expression into a >> literal Python code closure in order to be efficient. > > Exactly. That is one approach, using pure Python. > > The other (orthogonal) approach is to use numpy, and use the > fact that in plotting you usually need to evaluate things for many points > at once, and so there you simply use numpy to do the quick evaluations > for many points at once, and you can (probably?) live with the Python/SymPy > overhead of function calls. Then no eval() is necessary, just regular SymPy > methods. > > However, I think we need both approaches, because for many use cases, > (i.e. numerical ODE integration), you don't know the points in advance, > so the numpy approach doesn't provide enough speedup, as the SymPy > overhead will kill you. > >> >> The only other way I know how to do this is to use the ast module. >> That should be more robust than string processing, but probably a >> little harder to do. The code converting SymPy -> ast could probably >> be useful for other things as well, though. > > Ah, yes! So if you have the code in AST, is it possible to compile it to > Python > byte code? Yep. Use the builtin compile() function. See http://pythonic.pocoo.org/2008/3/29/ast-compilation-from-python for a simple example. Aaron Meurer > That would be the way to go, for both Python and numpy approach. > > The AST can (hopefully) be built using SymPy methods --- clean and robust, > i.e. each SymPy class will have a method like "get_ast" or something. > Depending > on the arguments to get_ast(), you would determine whether to use Python > built-in math, or numpy, or any other library. And then you simply compile > the AST. > > If this works, that would indeed be the best. > > Ondrej > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/sympy?hl=en. > -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
