I'm not a SymPy
expert, but I've used it successfully in some of my lectures in the last years. However, sometimes it seems to be very slow with symbolic integration. Here's an example that Mathematica
computes almost instantly while SymPy
needs a long time (more than half a minute) for it on my machine.
from sympy import *
x = symbols("x")
def coeff (f, k, var = x):
return integrate(f(var) * cos(k * var), (var, -pi, pi)) / pi
f = lambda x: (11*sin(x) + 6*sin(2*x) + 2*sin(3*x))/10
[coeff(f, k) for k in range(0, 5)]
Am I doing something wrong or is this the expected behavior? Is there some trick to speed this up?
SymPy
version is 1.0, Python
is 3.5.1 64-Bit (Anaconda) on Windows.
You can help guide the integration by telling SymPy to expand products of sin-cos to sums (see also [1],[2]) before doing the integration:
For example,
In [58]: fprod(f, 4)
Out[58]: (11*sin(x)/10 + 3*sin(2*x)/5 + sin(3*x)/5)*cos(4*x)
In [59]: FU['TR8'](fprod(f, 4))
Out[59]: -sin(x)/10 - 3*sin(2*x)/10 - 11*sin(3*x)/20 + 11*sin(5*x)/20 + 3*sin(6*x)/10 + sin(7*x)/10
The integration is simpler in this form.
Therefore you could use:
import sympy as sym
x = sym.symbols("x")
def f(x):
return (11*sym.sin(x) + 6*sym.sin(2*x) + 2*sym.sin(3*x))/10
def fprod(f, k, var=x):
return f(var) * sym.cos(k * var)
FU = sym.FU
def coeff (f, k, var=x):
return sym.integrate(FU['TR8'](fprod(f, k)), (var, -sym.pi, sym.pi)) / sym.pi
[coeff(f, k) for k in range(0, 5)]
Here is a benchmark using FU['TR8']
:
In [52]: %timeit [coeff(f, k) for k in range(0, 5)]
10 loops, best of 3: 78.8 ms per loop
Using the original code (without FU['TR8']
):
In [54]: %timeit [coeff(f, k) for k in range(0, 5)]
1 loop, best of 3: 19.8 s per loop
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With