On 31 March 2016 at 11:57, Poul Riis <prii...@gmail.com> wrote: > > ... However, the sympy way seems to be about 70 times slower than using the > derivative calculated 'by hand' (try the example below). > Can it be done in a more efficient way? > > Poul Riis > > > > from sympy import * > from time import * > x=Symbol('x') > ftext=diff(sin(x),x) > > def fmsympy(t): > return ftext.evalf(subs={x:t}) > > def fm(t): > return cos(t)
I think you have misunderstood what is going on here. Let's actually try those two methods out: $ isympy IPython console for SymPy 0.7.5 (Python 2.7.9-64-bit) (ground types: gmpy) These commands were executed: >>> from __future__ import division >>> from sympy import * >>> x, y, z, t = symbols('x y z t') >>> k, m, n = symbols('k m n', integer=True) >>> f, g, h = symbols('f g h', cls=Function) Documentation can be found at http://www.sympy.org In [1]: ftext = diff(sin(x), x) In [2]: ftext Out[2]: cos(x) In [3]: ftext.evalf(subs={x:1}) Out[3]: 0.540302305868140 In [4]: cos(1) Out[4]: cos(1) So the first version (your fmsympy) takes the symbolic expression cos(x) represented as a sympy expression tree and substitutes 1 for x (which requires walking the tree to look fo all occurrences of x). Then it evaluates the result to 15 decimal digits of precision using the pure Python mpmath multiprecision math library. To prove that it's not really a float calculation let's increase the precision: In [5]: ftext.evalf(subs={x:1}, n=100) Out[5]: 0.5403023058681397174009366074429766037323104206179222276700972553811003947744717645179518560871830893 Your second version (fm) makes a sympy expression using the cos function from sympy and the argument 1. This creates a symbolic sympy expression cos(1) and returns that. It doesn't do any evaluation of the expression to get the digits of the actual numeric answer. So I'm not surprised that the two operations take different amounts of time. One doesn't evaluate the expression and the other does using a slow multiprecision library. Also note though that sympy uses a cache to accelerate repeated calculations so if you time it doing the exact same thing repeatedly in a loop then you may just be measuring cache-hit performance for two different inputs rather than actual evaluation time. If you want to see one that's a lot faster use the cos function from the math module: In [9]: from math import cos In [10]: cos(1) Out[10]: 0.540302305868 This calculates cos(1) using IEEE 64-bit binary floating point (Python's float type) with hardware acceleration from your processor's FPU instructions. This should be a lot faster then either substituting into symbolic expressions in sympy or evaluating trignometric functions with mpmath. Generally I would use sympy in order to derive the mathematical expressions that I want to compute. However if I then want to evaluate the expressions many times in a loop with different input numbers for example then I would rewrite the expression without using sympy. Sympy has code generation capabilities to automate this but you seemed to be confused about basic sympy usage right now so I wouldn't recommend them without knowing more about what you're trying to do. -- Oscar -- https://mail.python.org/mailman/listinfo/python-list