From my SymPy output I have the matrix shown below, which I must integrate in 2D. Currently I am doing it element-wise as shown below. This method works but it gets too slow (for both sympy.mpmath.quad
and scipy.integrate.dblquad
) for my real case (in which A
and its functions are much bigger (see edit below):
from sympy import Matrix, sin, cos
import sympy
import scipy
sympy.var( 'x, t' )
A = Matrix([[(sin(2-0.1*x)*sin(t)*x+cos(2-0.1*x)*cos(t)*x)*cos(3-0.1*x)*cos(t)],
[(cos(2-0.1*x)*sin(t)*x+sin(2-0.1*x)*cos(t)*x)*sin(3-0.1*x)*cos(t)],
[(cos(2-0.1*x)*sin(t)*x+cos(2-0.1*x)*sin(t)*x)*sin(3-0.1*x)*sin(t)]])
# integration intervals
x1,x2,t1,t2 = (30, 75, 0, 2*scipy.pi)
# element-wise integration
from sympy.utilities import lambdify
from sympy.mpmath import quad
from scipy.integrate import dblquad
A_int1 = scipy.zeros( A.shape, dtype=float )
A_int2 = scipy.zeros( A.shape, dtype=float )
for (i,j), expr in scipy.ndenumerate(A):
tmp = lambdify( (x,t), expr, 'math' )
A_int1[i,j] = quad( tmp, (x1, x2), (t1, t2) )
# or (in scipy)
A_int2[i,j] = dblquad( tmp, t1, t2, lambda x:x1, lambda x:x2 )[0]
I was considering doing it in one shot like, but I'm not sure if this is the way to go:
A_eval = lambdify( (x,t), A, 'math' )
A_int1 = sympy.quad( A_eval, (x1, x2), (t1, t2)
# or (in scipy)
A_int2 = scipy.integrate.dblquad( A_eval, t1, t2, lambda x: x1, lambda x: x2 )[0]
EDIT:
The real case has been made available in this link. Just unzip and run shadmehri_2012.py
(is the author from were this example was taken from: Shadmehri et al. 2012).
I've started a bounty of 50 for the one who can do the following:
- make it reasonably faster than the proposed question
- manage to run without giving memory error even with a number of terms
m=15
andn=15
in the code), I managed up tom=7
andn=7
in 32-bit
The current timing can be summarized below(measured with m=3 and n=3). From there it can be seen that the numerical integration is the bottleneck.
build trial functions = 0%
evaluating differential equations = 2%
lambdifying k1 = 22%
integrating k1 = 74%
lambdifying and integrating k2 = 2%
extracting eigenvalues = 0%
Related questions: about lambdify
line_profiler
silas.sewell.org/blog/2009/05/28/… would have helped you. – Raynernumpy
when applicable. – Carlettacarleylambdify
call each time. So in the hope of actually being helpful unlike in the previous comment: have you actually tried to do the integration symbolically with numpy. If it is onlysin
,cos
and polynomials it should be easy. Especially if you can permit yourself to rewrite it as exponentialsexpr.rewrite(exp).expand()
(there are complex numbers popping out, but after evaluation it is real). – Raynersympy
(I guess it issympy
what you meant, isn't it?) before going further, this would really save time... – Carlettacarleysympy
. I must still be sleepy :) ... – Raynertrigsimp
(or justsimplify
) on the expression first. 2. Use the git master ofsympy
. There have been a lot of improvements to trigsimp and integration since the last official release. – Slit