I did the following test.  I applied the following patch:

diff --git a/sympy/core/add.py b/sympy/core/add.py
index d2cac9a..d5c3855 100644
--- a/sympy/core/add.py
+++ b/sympy/core/add.py
@@ -271,6 +271,9 @@ def as_coefficients_dict(a):
         di.update(d)
         return di

+    def eval_with_numpy(self, var, value):
+        return sum(i.eval_with_numpy(var, value) for i in self.args)
+
     @cacheit
     def as_coeff_add(self, *deps):
         """
diff --git a/sympy/functions/elementary/trigonometric.py
b/sympy/functions/elementary/trigonometric.py
index 70e9012..8c3f460 100644
--- a/sympy/functions/elementary/trigonometric.py
+++ b/sympy/functions/elementary/trigonometric.py
@@ -1,3 +1,5 @@
+import numpy
+
 from sympy.core.add import Add
 from sympy.core.numbers import Rational
 from sympy.core.basic import C, sympify, cacheit
@@ -165,6 +167,11 @@ def inverse(self, argindex=1):
         """
         return asin

+    def eval_with_numpy(self, var, value):
+        if self.args[0] != var:
+            raise NotImplementedError
+        return numpy.sin(value)
+
     @classmethod
     def eval(cls, arg):
         if arg.is_Number:
@@ -401,6 +408,11 @@ def fdiff(self, argindex=1):
     def inverse(self, argindex=1):
         return acos

+    def eval_with_numpy(self, var, value):
+        if self.args[0] != var:
+            raise NotImplementedError
+        return numpy.cos(value)
+
     @classmethod
     def eval(cls, arg):
         if arg.is_Number:

Then, I ran the following timings:

In [1]: a = sin(x) + cos(x)

In [3]: a.eval_with_numpy(x, 5)
Out[3]: -0.67526208919991215

In [4]: %timeit a.eval_with_numpy(x, 5)
10000 loops, best of 3: 58.5 us per loop

In [9]: import numpy

In [11]: b = lambdify(x, a, numpy)

In [13]: b(5)
Out[13]: -0.67526208919991215

In [12]: %timeit b(5)
100000 loops, best of 3: 9.64 us per loop

So you can see that the lambdify way is more than 6 times faster.  The
interface I made up for the eval_with_numpy is very bad.  A better one
would involve many more function calls and more complex logic, in
order too be correctly modular.  Also, the numpy import would be
inside the functions, which would make it even slower.

6x speedup makes a big difference if you are going to make an
evaluation thousands or even millions of times.

It's not too hard to see why this happens.  The eval_with_numpy way
involves logic, and three recursive function calls.  The lambdify way
is just a fancy way of writing b = lambda x: numpy.sin(x) +
numpy.cos(x), which, like Ondrej noted, only involves two numpy
function calls and float addition.

Aaron Meurer

On Sun, Jul 1, 2012 at 12:35 PM, [email protected]
<[email protected]> wrote:
> The AST stuff may be interesting and amusing, however before any
> actual benchmarking it seems like overly complicated solution.
>
> .evalf() is slow not because it traverses the expression tree (any
> evaluation method would do this, closures would not make less function
> calls which is the expensive part), but because it uses very
> complicated logic to ensure precision. A simple flag "use numpy/python
> math/whatever" that uses for instance methods called '_evalf_numpy'
> and '_evalf_cmath' would be **way** simpler and presumably just as
> fast.
>
> And you will not need to cater specifically to cases where only half
> of the expression can be translated (special functions), you just
> default to multiprecision evalf() and throw away the high precision
> part.
>
> --
> 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.

Reply via email to