Skip to content

Commit

Permalink
sagemathgh-38770: Add "needs" tags for giac and libgiac
Browse files Browse the repository at this point in the history
    
Part of sagemath#38668. If it's going to
be possible to disable giac, we need to guard all of the tests that use
it with either `# needs giac` or `# needs sage.libs.giac`.

I think I've gotten them all. A crude way to test:

1. `git rm -r src/sage/libs/giac` and rebuild to disable sage.libs.giac
2. build sage, and then delete the giac executable to disable the
pexpect interface

If you do these one at a time, it should ensure that the correct tags
are used. (Typically, if giac is missing, neither sage.libs.giac nor the
giac executable will be present, making it very easy to mix up the
tags.)

For bonus points you can undelete `src/sage/libs/giac` after building
but before testing to make sure the "needs" tags in those files are
accurate.

### Dependencies:

* sagemath#38756
* sagemath#38686 (not strictly required,
but it adds a few "needs sage.libs.giac" tags of its own)
    
URL: sagemath#38770
Reported by: Michael Orlitzky
Reviewer(s): Tobias Diez
  • Loading branch information
Release Manager committed Oct 25, 2024
2 parents 2be2d84 + 5127fd2 commit e70d9fe
Show file tree
Hide file tree
Showing 19 changed files with 130 additions and 68 deletions.
3 changes: 2 additions & 1 deletion src/doc/en/prep/Calculus.rst
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ help it look nicer in the browser?
- 1/10*(sqrt(5) - 3)*log(2*x^2 + x*(sqrt(5) - 1) + 2)/(sqrt(5) - 1)
+ 1/5*log(x + 1)

Some integrals are a little tricky, of course. Sage tries hard to integrate using Maxima, Giac and Sympy::
Some integrals are a little tricky, of course. Sage tries hard to integrate using Maxima, Sympy, and (optionally, if installed) Giac. The following can only be integrated by Giac::

sage: # needs sage.libs.giac
sage: integral(1/(1+x^10),x)
...1/20*(sqrt(5) + 1)*arctan((4*x + sqrt(-2*sqrt(5) + 10))/(sqrt(5) + 1))
+ 1/20*(sqrt(5) + 1)*arctan((4*x - sqrt(-2*sqrt(5) + 10))/(sqrt(5) + 1))
Expand Down
40 changes: 28 additions & 12 deletions src/sage/calculus/calculus.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@
2*pi
Ensure that :issue:`25626` is fixed. As the form of the answer is dependent of
the giac version, we simplify it (see :issue:`34037`). ::
the giac version, we simplify it (see :issue:`34037`)::
sage: t = SR.var('t')
sage: integrate(exp(t)/(t + 1)^2, t, algorithm='giac').full_simplify()
Expand Down Expand Up @@ -568,6 +568,7 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False):
An example of this summation with Giac::
sage: # needs giac
sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac').factor()
pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1))
Expand Down Expand Up @@ -843,7 +844,7 @@ def symbolic_product(expression, v, a, b, algorithm='maxima', hold=False):
- ``'maxima'`` -- use Maxima (the default)
- ``'giac'`` -- use Giac
- ``'giac'`` -- use Giac (optional)
- ``'sympy'`` -- use SymPy
Expand Down Expand Up @@ -1296,7 +1297,7 @@ def limit(ex, dir=None, taylor=False, algorithm='maxima', **argv):
With the standard package Giac::
sage: from sage.libs.giac.giac import libgiac # random
sage: # needs sage.libs.giac
sage: (exp(-x)/(2+sin(x))).limit(x=oo, algorithm='giac')
0
sage: limit(e^(-1/x), x=0, dir='right', algorithm='giac')
Expand Down Expand Up @@ -1564,7 +1565,7 @@ def laplace(ex, t, s, algorithm='maxima'):
- ``'sympy'`` -- use SymPy
- ``'giac'`` -- use Giac
- ``'giac'`` -- use Giac (optional)
.. NOTE::
Expand Down Expand Up @@ -1668,7 +1669,7 @@ def laplace(ex, t, s, algorithm='maxima'):
(0, True)
sage: F # random - sympy <1.9 includes undefined heaviside(0) in answer
1
sage: laplace(dirac_delta(t), t, s, algorithm='giac')
sage: laplace(dirac_delta(t), t, s, algorithm='giac') # needs giac
1
Heaviside step function can be handled with different interfaces.
Expand All @@ -1677,8 +1678,9 @@ def laplace(ex, t, s, algorithm='maxima'):
sage: laplace(heaviside(t-1), t, s)
e^(-s)/s
Try with giac::
Try with giac, if it is installed::
sage: # needs giac
sage: laplace(heaviside(t-1), t, s, algorithm='giac')
e^(-s)/s
Expand All @@ -1691,6 +1693,7 @@ def laplace(ex, t, s, algorithm='maxima'):
Testing Giac::
sage: # needs giac
sage: var('t, s')
(t, s)
sage: laplace(5*cos(3*t-2)*heaviside(t-2), t, s, algorithm='giac')
Expand All @@ -1699,13 +1702,14 @@ def laplace(ex, t, s, algorithm='maxima'):
Check unevaluated expression from Giac (it is locale-dependent, see
:issue:`22833`)::
sage: var('n')
n
sage: # needs giac
sage: n = SR.var('n')
sage: laplace(t^n, t, s, algorithm='giac')
laplace(t^n, t, s)
Testing SymPy::
sage: n = SR.var('n')
sage: F, a, cond = laplace(t^n, t, s, algorithm='sympy')
sage: a, cond
(0, re(n) > -1)
Expand Down Expand Up @@ -1806,7 +1810,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
- ``'sympy'`` -- use SymPy
- ``'giac'`` -- use Giac
- ``'giac'`` -- use Giac (optional)
.. SEEALSO::
Expand Down Expand Up @@ -1843,11 +1847,13 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
The same instance with Giac::
sage: # needs giac
sage: inverse_laplace(1/s^2*exp(-s), s, t, algorithm='giac')
(t - 1)*heaviside(t - 1)
Transform a rational expression::
sage: # needs giac
sage: inverse_laplace((2*s^2*exp(-2*s) - exp(-s))/(s^3+1), s, t,
....: algorithm='giac')
-1/3*(sqrt(3)*e^(1/2*t - 1/2)*sin(1/2*sqrt(3)*(t - 1))
Expand All @@ -1864,7 +1870,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
dirac_delta(t)
sage: inverse_laplace(1, s, t, algorithm='sympy')
dirac_delta(t)
sage: inverse_laplace(1, s, t, algorithm='giac')
sage: inverse_laplace(1, s, t, algorithm='giac') # needs giac
dirac_delta(t)
TESTS:
Expand All @@ -1878,6 +1884,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
Testing Giac::
sage: # needs giac
sage: inverse_laplace(exp(-s)/s, s, t, algorithm='giac')
heaviside(t - 1)
Expand All @@ -1888,12 +1895,14 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
Testing unevaluated expression from Giac::
sage: n = var('n')
sage: # needs giac
sage: n = SR.var('n')
sage: inverse_laplace(1/s^n, s, t, algorithm='giac')
ilt(1/(s^n), t, s)
Try with Maxima::
sage: n = SR.var('n')
sage: inverse_laplace(1/s^n, s, t, algorithm='maxima')
ilt(1/(s^n), s, t)
Expand All @@ -1909,6 +1918,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
Testing the same with Giac::
sage: # needs giac
sage: inverse_laplace(cos(s), s, t, algorithm='giac')
ilt(cos(s), t, s)
"""
Expand Down Expand Up @@ -2472,13 +2482,18 @@ def _find_var(name, interface=None):
EXAMPLES::
sage: y = var('y')
sage: y = SR.var('y')
sage: sage.calculus.calculus._find_var('y')
y
sage: sage.calculus.calculus._find_var('I')
I
sage: sage.calculus.calculus._find_var(repr(maxima(y)), interface='maxima')
y
::
sage: # needs giac
sage: y = SR.var('y')
sage: sage.calculus.calculus._find_var(repr(giac(y)), interface='giac')
y
"""
Expand Down Expand Up @@ -2585,6 +2600,7 @@ def symbolic_expression_from_string(s, syms=None, accept_sequence=False, *, pars
The Giac interface uses a different parser (:issue:`30133`)::
sage: # needs giac
sage: from sage.calculus.calculus import SR_parser_giac
sage: symbolic_expression_from_string(repr(giac(SR.var('e'))), parser=SR_parser_giac)
e
Expand Down
2 changes: 1 addition & 1 deletion src/sage/calculus/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def simplify(f, algorithm='maxima', **kwds):
sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1))
sage: simplify(ex)
1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1))
sage: simplify(ex, algorithm='giac')
sage: simplify(ex, algorithm='giac') # needs giac
I*sqrt(x^2 - 1)
"""
try:
Expand Down
4 changes: 2 additions & 2 deletions src/sage/functions/exp_integral.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ def __init__(self):
Si(x)
sage: sin_integral(x)._fricas_init_()
'Si(x)'
sage: sin_integral(x)._giac_() # needs sage.libs.giac
sage: sin_integral(x)._giac_() # needs giac
Si(sageVARx)
"""
BuiltinFunction.__init__(self, "sin_integral", nargs=1,
Expand Down Expand Up @@ -975,7 +975,7 @@ def __init__(self):
Ci(x)
sage: cos_integral(x)._fricas_init_()
'Ci(x)'
sage: cos_integral(x)._giac_() # needs sage.libs.giac
sage: cos_integral(x)._giac_() # needs giac
Ci(sageVARx)
"""
BuiltinFunction.__init__(self, "cos_integral", nargs=1,
Expand Down
4 changes: 2 additions & 2 deletions src/sage/functions/generalized.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def __init__(self):
H\left(x\right)
sage: heaviside(x)._sympy_() # needs sympy
Heaviside(x)
sage: heaviside(x)._giac_() # needs sage.libs.giac
sage: heaviside(x)._giac_() # needs giac
Heaviside(sageVARx)
sage: h(x) = heaviside(x)
sage: h(pi).numerical_approx()
Expand Down Expand Up @@ -413,7 +413,7 @@ class FunctionSignum(BuiltinFunction):
sign(x)
sage: sgn(x)._fricas_init_() # needs sage.symbolic
'(x+->abs(x)/x)(x)'
sage: sgn(x)._giac_() # needs sage.libs.giac sage.symbolic
sage: sgn(x)._giac_() # needs giac sage.symbolic
sign(sageVARx)
Test for :issue:`31085`::
Expand Down
2 changes: 1 addition & 1 deletion src/sage/functions/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1860,7 +1860,7 @@ def __init__(self):
sage: isinstance(r.operator(), # known bug # needs sympy
....: sage.functions.other.Function_prod)
True
sage: giac(sprod(m, m, 1, n)).sage()
sage: giac(sprod(m, m, 1, n)).sage() # needs giac
factorial(n)
"""
BuiltinFunction.__init__(self, "product", nargs=4,
Expand Down
12 changes: 7 additions & 5 deletions src/sage/functions/piecewise.py
Original file line number Diff line number Diff line change
Expand Up @@ -1470,16 +1470,18 @@ def _giac_init_(self, parameters, variable):
EXAMPLES::
sage: # needs giac
sage: ex = piecewise([((0, 1), pi), ([1, 2], x)])
sage: f = ex._giac_(); f # needs sage.libs.giac
sage: f = ex._giac_(); f
piecewise(((sageVARx>0) and (1>sageVARx)),pi,((sageVARx>=1) and (2>=sageVARx)),sageVARx)
sage: f.diff(x) # needs sage.libs.giac
sage: f.diff(x)
piecewise(((sageVARx>0) and (1>sageVARx)),0,((sageVARx>=1) and (2>=sageVARx)),1)
sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))]) # needs sage.libs.giac
sage: g = ex._giac_(); g # needs sage.libs.giac
sage: # needs giac
sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))])
sage: g = ex._giac_(); g
piecewise(((sageVARx>-100) and ((-2)>sageVARx)),1/sageVARx,sageVARx>1,cos(sageVARx))
sage: g.diff(x) # needs sage.libs.giac
sage: g.diff(x)
piecewise(((sageVARx>-100) and ((-2)>sageVARx)),-1/sageVARx^2,sageVARx>1,-sin(sageVARx))
TESTS::
Expand Down
1 change: 1 addition & 0 deletions src/sage/interfaces/giac.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# sage.doctest: needs giac
r"""
Pexpect Interface to Giac
Expand Down
12 changes: 6 additions & 6 deletions src/sage/interfaces/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def __call__(self, x, name=None):
Check conversion of Booleans (:issue:`28705`)::
sage: giac(True)
sage: giac(True) # needs giac
true
sage: maxima(True)
true
Expand Down Expand Up @@ -343,7 +343,7 @@ def _coerce_impl(self, x, use_special=True):
Check that python type ``complex`` can be converted (:issue:`31775`)::
sage: giac(complex(I))**2 # should not return `j^2`
sage: giac(complex(I))**2 # should not return `j^2` # needs giac
-1
"""
if isinstance(x, bool):
Expand Down Expand Up @@ -1196,12 +1196,12 @@ def _repr_(self):
sage: gap(2)
2
sage: x = var('x')
sage: giac(x)
sage: giac(x) # needs giac
sageVARx
sage: giac(5)
sage: giac(5) # needs giac
5
sage: M = matrix(QQ,2,range(4))
sage: giac(M)
sage: giac(M) # needs giac
[[0,1],[2,3]]
sage: x = var('x') # optional - maple
sage: maple(x) # optional - maple
Expand Down Expand Up @@ -1341,7 +1341,7 @@ def __bool__(self):
By default this returns ``True`` for elements that are considered to be
not ``False`` by the interface (:issue:`28705`)::
sage: bool(giac('"a"'))
sage: bool(giac('"a"')) # needs giac
True
"""
P = self._check_valid()
Expand Down
1 change: 1 addition & 0 deletions src/sage/libs/giac/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# sage.doctest: needs sage.libs.giac
"""
Wrappers for Giac functions
Expand Down
1 change: 1 addition & 0 deletions src/sage/libs/giac/giac.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# sage.doctest: needs sage.libs.giac
# distutils: libraries = giac
# distutils: language = c++
# distutils: extra_compile_args = -std=c++11
Expand Down
8 changes: 4 additions & 4 deletions src/sage/matrix/matrix1.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -216,21 +216,21 @@ cdef class Matrix(Matrix0):
EXAMPLES::
sage: M = matrix(ZZ, 2, range(4))
sage: giac(M) # needs sage.libs.giac
sage: giac(M) # needs giac
[[0,1],[2,3]]
sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9])
sage: giac(M) # needs sage.libs.giac
sage: giac(M) # needs giac
[[1,2,3],[4/3,5/3,3/2],[7,8,9]]
sage: P.<x> = ZZ[]
sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5])
sage: giac(M) # needs sage.libs.giac
sage: giac(M) # needs giac
[[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]]
sage: y = var('y') # needs sage.symbolic
sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic
sage: giac(M).det().sage() # needs sage.libs.giac sage.symbolic
sage: giac(M).det().sage() # needs giac sage.symbolic
(y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y
"""
s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']'
Expand Down
6 changes: 3 additions & 3 deletions src/sage/modules/free_module_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1007,20 +1007,20 @@ cdef class FreeModuleElement(Vector): # abstract base class
EXAMPLES::
sage: v = vector(ZZ, 4, range(4))
sage: giac(v) + v # needs sage.libs.giac
sage: giac(v) + v # needs giac
[0,2,4,6]
::
sage: v = vector(QQ, 3, [2/3, 0, 5/4])
sage: giac(v) # needs sage.libs.giac
sage: giac(v) # needs giac
[2/3,0,5/4]
::
sage: P.<x> = ZZ[]
sage: v = vector(P, 3, [x^2 + 2, 2*x + 1, -2*x^2 + 4*x])
sage: giac(v) # needs sage.libs.giac
sage: giac(v) # needs giac
[sageVARx^2+2,2*sageVARx+1,-2*sageVARx^2+4*sageVARx]
"""
return self.list()
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/polynomial/multi_polynomial.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ cdef class MPolynomial(CommutativePolynomial):
TESTS::
sage: # needs sage.libs.giac
sage: # needs giac
sage: R.<x,y,z> = GF(101)['e,i'][]
sage: f = R('e*i') * x + y^2
sage: f._giac_init_()
Expand Down
Loading

0 comments on commit e70d9fe

Please sign in to comment.