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

Reply via email to