From 5ac0d9b8f29def795e5c86aa8dbb32111487aacb Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 5 Oct 2024 20:49:05 -0400 Subject: [PATCH] src/sage/symbolic/integration: help libgiac handle infinite endpoints When integrating to/from plus/minus infinity, Giac can get stuck: sage: integral(1/max_symbolic(x, 1)**2, x, 0, oo, algorithm='giac') ... RuntimeError: Unable to check sign: 1>Infinity This is apparently due to the type of infinity that is used for integration. There are (at least?) two kinds: sage: from sage.libs.giac import libgiac sage: libgiac(Infinity) Infinity sage: libgiac(Infinity._giac_()) +infinity And, for integration, I guess we want the second kind, because it allows the integration to proceed with a warning. This commit calls _giac_() on the endpoints of a definite integral before passing them to libgiac.integrate(). It fixes the example above, and we update the corresponding doctest. --- src/sage/symbolic/integration/external.py | 10 ++++++++++ src/sage/symbolic/integration/integral.py | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 92574424fb0..84de69c5b30 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -256,6 +256,16 @@ def libgiac_integrator(expression, v, a=None, b=None): if a is None: result = libgiac.integrate(Pygen(expression), v) else: + # We use _giac_() in the endpoints if they are infinite because + # for some reason, passing them straight to libgiac() gives us + # a different kind of infinity back that doesn't work as well, + # at least for integration. + from sage.rings.infinity import PlusInfinity, MinusInfinity + if isinstance(a, PlusInfinity) or isinstance(a, MinusInfinity): + a = a._giac_() + if isinstance(b, PlusInfinity) or isinstance(b, MinusInfinity): + b = b._giac_() + result = libgiac.integrate(Pygen(expression), v, a, b) if 'integrate' in format(result) or 'integration' in format(result): return expression.integrate(v, a, b, hold=True) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index fdd722c1f30..a7d38b6ec55 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -206,7 +206,9 @@ def __init__(self): sage: ex = 1/max_symbolic(x, 1)**2 sage: integral(ex, x, 0, 2, algorithm='giac') 3/2 - sage: integral(1/max_symbolic(x, 1)**2, x, 0, oo, algorithm='giac') + sage: result = integral(ex, x, 0, oo, algorithm='giac') + ... + sage: result 2 """ # The automatic evaluation routine will try these integrators