When computing
from sympy import sqrt, pi, integrate, Symbol
x = Symbol('x')
i1 = integrate(2 * sqrt(-x**2 + 1)*(4*sqrt(2)*x**2 - sqrt(3)), (x, -1, +1))
print(i1)
sympy reports the value to be 0. (Tested with the latest version from master.) However, it really is
(sqrt(2) - sqrt(3)) * pi
c.f. https://www.wolframalpha.com/input/?i=integrate(2+sqrt(1+-+x%5E2)+(-sqrt(3)+%2B+4+sqrt(2)+x%5E2),+-1,+%2B1).

Any idea what's going on?
Indefinite integral formed by sympy is correct :
>>> integrate(2 * sqrt(-x**2 + 1)*(4*sqrt(2)*x**2 - sqrt(3)), x)
-2*sqrt(3)*Piecewise((x*sqrt(-x**2 + 1)/2 + asin(x)/2, (x > -1) & (x < 1))) + 8*sqrt(2)*Piecewise((-x*(-2*x**2 + 1)*sqrt(-x**2 + 1)/8 + asin(x)/8, (x > -1) & (x < 1)))
However while substitution of Piecewise it is getting wrong. As you can see following:
>>> expr
-2*sqrt(3)*Piecewise((x*sqrt(-x**2 + 1)/2 + asin(x)/2, (x > -1) & (x < 1))) + 8*sqrt(2)*Piecewise((-x*(-2*x**2 + 1)*sqrt(-x**2 + 1)/8 + asin(x)/8, (x > -1) & (x < 1)))
>>> expr.subs(x,1)
-2*sqrt(3)*Piecewise() + 8*sqrt(2)*Piecewise()
>>> expr.subs(x,-1)
-2*sqrt(3)*Piecewise() + 8*sqrt(2)*Piecewise()
>>> expr.subs(x,0)
0
>>> expr.subs(x,3)
-2*sqrt(3)*Piecewise() + 8*sqrt(2)*Piecewise()
@asmeurer @jksuom How to fix this ? I have debugged up substitution process and found that at "sympy/sympy/core/compatibility.py(797)wrapper()" ( link = cache_get(key) ), it is getting RuntimeError - RuntimeError: maximum recursion depth exceeded while getting the repr of a list
here:
key = [Piecewise((-x*(-2*x**2 + 1)*sqrt(-x**2 + 1)/8 + asin(x)/8, (x > -1) & (x < 1))), x, 1, Piecewise, <class 'sympy.core.symbol.Symbol'>, <class 'sympy.core.numbers.One'>]
The issue is already in the Piecewise form of the expression for indefinite integral. The Piecewise is only defined for x strictly between -1 and 1, all other values are left undefined (and so they eventually default to 0). This means that not only this integral, but also integration from 2 to 3, and so on, will result in 0.
A thing to consider is extending the domain of Piecewise in the output of integration to closed intervals. In my experience, if an antiderivative is correct on an open interval (a, b) and we plug in the endpoints a, b in it, that'll be either undefined (then the integral diverges) or it will be the correct answer. Going from open interval (a, b) to closed [a, b] is not far enough for any branching to occur. Example:
f = integrate(2 * sqrt(-x**2 + 1)*(4*sqrt(2)*x**2 - sqrt(3)), x)
g = f.subs((x > -1) & (x < 1), (x >= -1) & (x <= 1))
print(g.subs(x, 1) - g.subs(x, -1))
Prints -sqrt(3)*pi + sqrt(2)*pi, the correct value.
This may be worth considering, but is a kind of a band-aid and doesn't do anything for intervals like [2, 3]. (On the other hand, far fewer people will want to integrate that function over [2, 3] where it's complex.)
If the terms are expanded into two integrals, they evaluate correctly.
8*sqrt(2) * integrate(x**2 * sqrt(1-x**2), (x, -1, 1)) - 2*sqrt(3) * integrate(sqrt(1-x**2), (x, -1, 1))
# returns -sqrt(3)*pi + sqrt(2)*pi
The problematic term is the one with x2. A problem, which also came up in #13792, is that integration is affected by simple constant factors like 2 or (-1). Compare
```
integrate(x2sqrt(1-x2), (x, -1, 1)) # returns pi/8, correct
integrate(2 * x2sqrt(1-x2), (x, -1, 1)) # returns unevaluated, 2Integral(x2sqrt(-(x - 1)*(x + 1)), (x, -1, 1))
````
The presence of a constant factor causes the expression to be rewritten in a way that's not actually beneficial. A thing to consider here is to try integration with the constants factored out but with other terms intact. It seems the integrator, when seeing a constant factor here, goes into "factor everything" mode and that makes things worse.
This seems to work now:
In [14]: integrate(2 * sqrt(-x**2 + 1)*(4*sqrt(2)*x**2 - sqrt(3)), (x, -1, +1))
Out[14]: -√3⋅π + √2⋅π
Most helpful comment
Open-ended conditions in Piecewise output of integration
The issue is already in the Piecewise form of the expression for indefinite integral. The Piecewise is only defined for x strictly between -1 and 1, all other values are left undefined (and so they eventually default to 0). This means that not only this integral, but also integration from 2 to 3, and so on, will result in 0.
A thing to consider is extending the domain of Piecewise in the output of integration to closed intervals. In my experience, if an antiderivative is correct on an open interval (a, b) and we plug in the endpoints a, b in it, that'll be either undefined (then the integral diverges) or it will be the correct answer. Going from open interval (a, b) to closed [a, b] is not far enough for any branching to occur. Example:
Prints
-sqrt(3)*pi + sqrt(2)*pi, the correct value.This may be worth considering, but is a kind of a band-aid and doesn't do anything for intervals like [2, 3]. (On the other hand, far fewer people will want to integrate that function over [2, 3] where it's complex.)
Fragility of integration
If the terms are expanded into two integrals, they evaluate correctly.
The problematic term is the one with x2. A problem, which also came up in #13792, is that integration is affected by simple constant factors like 2 or (-1). Compare
```
integrate(x2sqrt(1-x2), (x, -1, 1)) # returns pi/8, correct
integrate(2 * x2sqrt(1-x2), (x, -1, 1)) # returns unevaluated, 2Integral(x2sqrt(-(x - 1)*(x + 1)), (x, -1, 1))
````
The presence of a constant factor causes the expression to be rewritten in a way that's not actually beneficial. A thing to consider here is to try integration with the constants factored out but with other terms intact. It seems the integrator, when seeing a constant factor here, goes into "factor everything" mode and that makes things worse.