Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sympy returns some of the integral unevaluated #15749

Open
iamrajiv opened this issue Jan 7, 2019 · 11 comments
Open

Sympy returns some of the integral unevaluated #15749

iamrajiv opened this issue Jan 7, 2019 · 11 comments

Comments

@iamrajiv
Copy link
Contributor

iamrajiv commented Jan 7, 2019

Sympy returns some of the integral unevaluated

Examples:
integrate(sqrt(sin(x)))
integrate(exp(sin(x)))
integrate(sin(x)**Rational(3,2))

for integral integrate(sqrt(sin(x))) and integrate(exp(sin(x))) it returns

>>> from sympy import *
>>> x = symbols('x')
>>> integrate(sqrt(sin(x)))
Integral(sqrt(sin(x)), x)
>>> from sympy import *
>>> x = symbols('x')
>>> integrate(exp(sin(x)))
Integral(exp(sin(x)), x)

Above code is in python 3.7.1 Shell. In Sympy Live it returns in symbolic form but does not evaluate the integral.

for integral integrate(sin(x)**Rational(3,2)) it returns

>>> from sympy import *
>>> x = symbols('x')
>>> integrate(sin(x)**Rational(3,2))
Integral(sin(x)**(3/2), x)

Above code is in python 3.7.1 Shell. In Sympy Live it gives Error: Operation timed out.

There are many more examples of integrals which either return in symbolic form without evaluated or it gives a timeout error. I have run these code in python 3.7.1 Shell, cmd and Sympy Live but none of it works. I think issues #7051 and #15730 is very much related to these issues. Do not know why this is happening but I will try to figure out this.

@iamrajiv
Copy link
Contributor Author

iamrajiv commented Jan 7, 2019

I think the problem occurs only when we are using the trigonometric function which is raised to some rational power or exponents but if I use integrate(sin(x)**Rational(4,2)) which also has rational power it returns the correct evaluation.

>>> from sympy import *
>>> x = symbols('x')
>>> integrate(sin(x)**Rational(4,2))
x/2 - sin(x)*cos(x)/2

this means that integrals do not evaluate if the power is not an integer though Rational(4,2)) is also fraction but in the simplest form, it becomes an integer i.e. the power of any trigonometric function should not be a fraction provide it should be an integer after expressing it in simplest form to get integral of that function. I think there may be a problem with the codebase of the integrals module of Sympy.

@aOrionis
Copy link

aOrionis commented Jan 8, 2019

The problem here is that there are some integrals that cannot be evaluated yet by Sympy.
For example the first equation requires an Elliptic integral to similarly some special functions are required to solve the last equation for non-integral exponents.
This is what I think is happening after some research. Would appreciate some guidance as well.

@iamrajiv
Copy link
Contributor Author

iamrajiv commented Jan 8, 2019

Wolfram Alpha also integrates the first example as the elliptic integral of the second kind with parameter k=mk^2 and evaluates answer as

image

The third example is also elliptic integral of the first kind and for second example Wolfram Alpha not able to integrate it. I think maybe e^sin(x) is not integrable form but I think there should be a feature in Sympy that if a function is not integrable it should return a message that the function is not integrable.

@iamrajiv
Copy link
Contributor Author

iamrajiv commented Jan 8, 2019

My approach for the integration of function e^sin(x) is that we should open e^x to Maclaurin series and integrate term by term but it is a long way though.

@iamrajiv
Copy link
Contributor Author

iamrajiv commented Jan 8, 2019

I used scipy and numpy to integrate sqrt(sin(x)) and it gives

>>> from scipy.integrate import quad
>>> import numpy as np
>>> def integrand(x):
	return np.sqrt(np.sin(x))

>>> ans = quad(integrand, 0, np.pi)
>>> print (ans)
(2.396280469471185, 1.91535676208332e-11)

I want to just ask that can we convert the answer that we get from above to symbolic form i.e. decimal number to rational number if we could it will be easy to evaluate these integrals.

@asmeurer
Copy link
Member

asmeurer commented Jan 8, 2019

If integrate returns an Integral it means that the algorithms don't know how to integrate the function. The algorithms for integration are heuristical in nature so there will always be functions that have integrals that SymPy cannot find (there is the Risch algorithm, but that only works for elementary integrals, and anyway is only partially implemented in SymPy).

There's no way to go from a numerical integral to a symbolic one. If you only care about a numerical answer, you may be better off just using scipy.quad from the start.

The easiest way to add support for an integral that isn't supported is to find a general integration rule that applies to it and add that rule to manualintegrate.

@normalhuman
Copy link
Contributor

normalhuman commented Jan 10, 2019

If one is lucky, nsimplify may convert a decimal expression into a symbolic one: this is occasionally useful with Integral, for example

>>> x = symbols('x')
>>> f = log(x)/(x**2 - 1)
>>> integrate(f, (x, 0, 1))
Integral(log(x)/((x - 1)*(x + 1)), (x, 0, 1))
>>> nsimplify(Integral(f, (x, 0, 1)), [pi, E])
pi**2/8

(A remark from user's point of view, not developer's.)

@asmeurer
Copy link
Member

If you do that you should always be careful to verify the answer from nsimplify somehow, e.g., by computing more digits.

By the way, Integral(expand(log(x)*apart(1/((x - 1)*(x + 1)))), (x, 0, 1)).doit() gives pi**2/8 - I*pi*log(2), which I guess is wrong.

@normalhuman
Copy link
Contributor

Yes, Meijer G does not always get the right branch of polylog in the antiderivative, but I failed to improve on its present state. #13850

@sudoer-Huatao
Copy link

I think that using the evalf() function you can actually evaluate unevaluated definite integrals by Sympy. For example:
x = symbols("x")
Integral(f, (x, lbound, rbound)).evalf()
where f is the function you are integrating lbound is the lower bound and rbound is the upper bound
This doesn't return an unevaluated object

@oscarbenjamin
Copy link
Contributor

using the evalf() function you can actually evaluate unevaluated definite integrals

This is true if there are no symbols besides the integration variable and it is a single integral (rather than a double/triple/etc integral). It should be better documented (#23025) and support for multiple integrals should be added (#21605).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants