sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.79k stars 4.39k forks source link

integrate(exp(exp(I*x)), [x, 0, 2*pi]) incorrectly 0 #16046

Open ethankward opened 5 years ago

ethankward commented 5 years ago
>>> from sympy import *
>>> x = Symbol('x')
>>> integrate(exp(exp(I*x)), [x, 0, 2*pi])
0

The answer should be 2*pi.

ethankward commented 5 years ago

This returns an unevaluated integral in 1.3.

jksuom commented 5 years ago

There are many examples of the same behaviour among older issues. When the integrand is periodic, its antiderivative will usually also turn out to be periodic. It follows that if the integral over a period is not zero, the antiderivative will be discontinuous. That should be checked before applying the fundamental theorem of calculus (that only works with continuous antiderivatives).

oscarbenjamin commented 5 years ago

Is it possible to solve these by detecting periodic functions with discontinuous antiderivatives and then using a patched up antiderivative like expr_discont + delta * (x % period) where delta is the integral over the period?

Related issue #15730

jksuom commented 5 years ago

Something like that will do if the discontinuities are at n*period for integers n. But perhaps there should rather be floor(x/period) instead of x % period.

oscarbenjamin commented 5 years ago

As long as the discontinuities are periodic (which they will be if the antiderivative is periodic) then it should be possible to add a number of different terms like delta_i * floor((x-x_i)/period) where x_i is the location of the discontinuity and delta_i is the difference across the discontinuity.

jksuom commented 5 years ago

I think that would work. Only, one has to find all the x_i and delta_i. The idea has already been implemented in some cases involving atans.

oscarbenjamin commented 5 years ago

Are there already methods for detecting if an expression is periodic or continuous or for finding discontinuities?

jksuom commented 5 years ago

There is periodicity in calculus.util. Discontinuities are harder to find, especially, when branched multi-valued functions are involved.

oscarbenjamin commented 5 years ago

In this particular case the antiderivative is

In [5]: integrate(exp(exp(I*x)))                                                                                                               
Out[5]: 
     ⎛ ⅈ⋅x⎞
-ⅈ⋅Ei⎝ℯ   ⎠

Periodicity doesn't work presumably because it doesn't understand exp(I*x):

In [14]: from sympy.calculus.util import periodicity                                                                                           

In [15]: print(periodicity(exp(I*x), x))                                                                                                       
None
Teut2711 commented 5 years ago

Hey, can I work on this issue? But I 'm still not good enough to do this alone since I have only fixed a single issue that too partly.

oscarbenjamin commented 5 years ago

I don't know what can be done for solving this kind of integral. I described something above but it's not simple because other features for finding discontinuities etc. don't exist. periodicity is already being worked on in #16068

Teut2711 commented 5 years ago

well if you solve it by hand you use substitution e^ix = t but I don't know how does sympy use substitution .

mohitacecode commented 4 years ago

In the current master the following result is returned but it isn't getting simplified it is returning same expression is it the case when sympy don't have the solution for the problem it returned unsolved form?

>>> Integral(abs(sin(phi)*cos(phi)), (phi,pi,2*pi))
Integral(Abs(sin(phi)*cos(phi)), (phi, pi, 2*pi))
>>> _.doit()
Integral(Abs(sin(phi)*cos(phi)), (phi, pi, 2*pi))
>>> 
moorepants commented 4 years ago

is it the case when sympy don't have the solution for the problem it returned unsolved form?

Yes, this is the expected behavior: return the Integral if SymPy can solve it.