sympy 1.4 integral error

36 views
Skip to first unread message

Gösta Ljungdahl

unread,
Jan 13, 2020, 6:33:21 AM1/13/20
to sympy
Apparently there is some error in the integrate algorithm.

Consider the following integral:

int(x/sqrt(ax+b)) which is 2*sqrt(ax+b)*(ax-2b)/(3a**2) as is easily confirmed doing integration by parts. Many integral tables (not all) has this integral correctly listed.

sympy 1.4 gives me this:

code (ipython 7.5.0):
In [1]: from sympy import *                                                                        

In [2]: a,b,x=symbols('a b x')

In [6]: f=x/sqrt(a*x+b)                                                                            

In [7]: int=integrate(f,x)                                                                         

In [8]: factor(int)                                                                                
Out[8]: 2*sqrt(b)*(a*x*sqrt(a*x/b + 1) - 2*b*sqrt(a*x/b + 1) + 2*b)/(3*a**2)

where clearly the last term shouldn't be there.

Hope this can help improving the integrate algorithm.

Oscar Benjamin

unread,
Jan 13, 2020, 8:15:28 AM1/13/20
to sympy
The integrate function when used without limits finds an
antiderivative. In general antiderivatives are not unique and can
differ by a constant which I think is the case here. The
simplifications below won't work though unless the symbols are
declared positive:

In [44]: a, b, x = symbols('a b x', positive=True)

In [45]: f = x / sqrt(a*x + b)

In [46]: integral = integrate(f, x)

In [47]: simplify(integral.diff(x) - f)
Out[47]: 0

In [48]: expected = 2 * sqrt(a*x + b) * (a*x - 2*b) / (3*a**2)

In [49]: simplify(integral - expected)
Out[49]:
3/2
4⋅b
──────
2
3⋅a


The integral result from sympy does seem unnecessarily complicated in
this example though. You can get a more natural form by using
manualintegrate:

In [55]: integral = integrate(f, x, manual=True)

In [56]: factor(integral)
Out[56]:
_________
2⋅(a⋅x - 2⋅b)⋅╲╱ a⋅x + b
─────────────────────────
2
3⋅a

That's the result you expected and that's because it is also
(probably) calculated using integration by parts.

--
Oscar
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/b9fe9ccf-68cb-4720-a5a3-e36dfdbc620e%40googlegroups.com.

Josefsson-Ljungdahl

unread,
Jan 13, 2020, 3:52:51 PM1/13/20
to sy...@googlegroups.com
Yes, a primitive function is unique only up to a constant but it is not strictly correct to pick out a particular one since the constant is arbitrary. This may be an academic point but I would have thought that it would be possible to construct the algorithm in such a way that a constant is washed out or if included just be named constant or similar and added after to the unique part.

Cheers,
Gösta


Oscar Benjamin

unread,
Jan 13, 2020, 4:21:10 PM1/13/20
to sympy
On Mon, 13 Jan 2020 at 20:52, Josefsson-Ljungdahl <gos...@gmail.com> wrote:
>
> Yes, a primitive function is unique only up to a constant but it is not strictly correct to pick out a particular one since the constant is arbitrary. This may be an academic point but I would have thought that it would be possible to construct the algorithm in such a way that a constant is washed out or if included just be named constant or similar and added after to the unique part.

There is no "unique part" though. There is a family of possibilities
each of which may or may not be representable in a variety of forms.
Given f = 2x + 2 possible antiderivatives F are x^2 + 2*x or (x +
1)^2. These differ by a constant and you can add an arbitrary constant
to either. So how in general would you identify a unique
antiderivative?

--
Oscar

Gösta Ljungdahl

unread,
Jan 14, 2020, 4:32:52 AM1/14/20
to sympy
I do not think we have different views on how the mathematics works only perhaps how to express it.

I did not say that the antiderivative is unique only that it has a unique part. That is what I meant by
unique up to a constant but perhaps my English is wrong.

In your example the unique part is x^2+2*x, no more no less. The general antiderivative
may be expressed like so:

x^2+2*x+constant

ant I'm positive that there is no argument here.

If we are talking definite integrals we must, however, take the constant to be 0:

int_a^b(2*x+2) = b^2+2*b-(a^2+2*a)

i.e. only the unique part of the antiderivative contributes to the definite integral and
therefore it is in this case reasonable not to display any constant which is also
what is commonly done in integral tables.

I we are talking solutions to differential equations the particular value of the constant is subject
to initial conditions or more generally expressed: The constant may not be determined unless
we know the value of the antiderivative for some particular argument. In this case it would be
downright wrong to set a particular value to it without having this knowledge. I agree, of course, that
the integral sympy gave me is a possible answer but it also assumes conditions that I have not
provided so it may be misleading. For reasons outlined I think it would be better if the
algorithm did wash out the constant.

Cheers,
Gösta

Aaron Meurer

unread,
Jan 14, 2020, 3:40:16 PM1/14/20
to sympy
I agree that integrate() shouldn't return things with trivial
constants (terms that don't depend on x), but the integrand you shows
doesn't do that unless you simplify it. In the expanded form returned
by integrate() every term depends on x. Perhaps integrate() can return
a nicer looking result here. integrate() generally just returns
whatever the internal algorithm gives, without doing any additional
simplification.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/8a7a07c8-4d08-4693-9da2-240b0854291f%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages