diff --git a/src/doc/en/prep/Calculus.rst b/src/doc/en/prep/Calculus.rst index c2f636be558..d33b3082040 100644 --- a/src/doc/en/prep/Calculus.rst +++ b/src/doc/en/prep/Calculus.rst @@ -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)) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index 65a075a2e1f..7a3c50c569e 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -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() @@ -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)) @@ -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 @@ -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') @@ -1564,7 +1565,7 @@ def laplace(ex, t, s, algorithm='maxima'): - ``'sympy'`` -- use SymPy - - ``'giac'`` -- use Giac + - ``'giac'`` -- use Giac (optional) .. NOTE:: @@ -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. @@ -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 @@ -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') @@ -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) @@ -1806,7 +1810,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'): - ``'sympy'`` -- use SymPy - - ``'giac'`` -- use Giac + - ``'giac'`` -- use Giac (optional) .. SEEALSO:: @@ -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)) @@ -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: @@ -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) @@ -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) @@ -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) """ @@ -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 """ @@ -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 diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 8747e1df790..557ce362fd3 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -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: diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py index ac88a0146a1..e074c430808 100644 --- a/src/sage/functions/exp_integral.py +++ b/src/sage/functions/exp_integral.py @@ -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, @@ -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, diff --git a/src/sage/functions/generalized.py b/src/sage/functions/generalized.py index f8f92b293a4..f43849d2043 100644 --- a/src/sage/functions/generalized.py +++ b/src/sage/functions/generalized.py @@ -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() @@ -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`:: diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index e57fbf14cd9..2f4c5c5b546 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -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, diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index d7370a5cd30..35c92f27691 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -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:: diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 00c9ff429c3..5894980b332 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -1,3 +1,4 @@ +# sage.doctest: needs giac r""" Pexpect Interface to Giac diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index c15f0342de4..b289b144dd3 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -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 @@ -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): @@ -1193,12 +1193,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 @@ -1338,7 +1338,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() diff --git a/src/sage/libs/giac/__init__.py b/src/sage/libs/giac/__init__.py index ab62e2a21db..ef2267c4378 100644 --- a/src/sage/libs/giac/__init__.py +++ b/src/sage/libs/giac/__init__.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.giac """ Wrappers for Giac functions diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 30e6fdd56ed..4094307f0fd 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.giac # distutils: libraries = giac # distutils: language = c++ # distutils: extra_compile_args = -std=c++11 diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 0940710150e..96a175825b3 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -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. = 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) + ']' diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 5f076475e8c..3dadfece8a2 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -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. = 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() diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index e6cfbcec7cb..ca25adc23f0 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -1114,7 +1114,7 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: # needs sage.libs.giac + sage: # needs giac sage: R. = GF(101)['e,i'][] sage: f = R('e*i') * x + y^2 sage: f._giac_init_() diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index f8daa8371b6..222da435df2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2311,6 +2311,7 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): You can use Giac to compute the elimination ideal:: + sage: # needs sage.libs.giac sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm='giac') == J possible output... True @@ -2331,7 +2332,7 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): Check that this method works over QQbar (:issue:`25351`):: - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.libs.giac sage: R. = QQbar[] sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3] sage: J = I.elimination_ideal([t, s]); J @@ -4366,12 +4367,12 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal reverse lexicographical ordering here, in order to test against :issue:`21884`:: + sage: # needs sage.libs.giac sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) sage: gb = J.groebner_basis('giac') # random sage: gb [c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1] - sage: J.groebner_basis.set_cache(gb) sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis() # testing issue #21884 ...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] @@ -4379,6 +4380,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Giac's gbasis over `\QQ` can benefit from a probabilistic lifting and multi threaded operations:: + sage: # needs sage.libs.giac sage: A9 = PolynomialRing(QQ, 9, 'x') sage: I9 = sage.rings.ideal.Katsura(A9) sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7) # long time (3s) @@ -4630,7 +4632,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: I.groebner_basis('libsingular:slimgb') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.libs.giac sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) sage: gb = J.groebner_basis('giac') # random diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 2449b3208ae..53bb07c2fc4 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -7177,9 +7177,9 @@ cdef class Polynomial(CommutativePolynomial): sage: f = R('e*i') * x + x^2 sage: f._giac_init_() '((1)*1)*sageVARx^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) + sage: giac(f) # needs giac sageVARx^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) + sage: giac(R.zero()) # needs giac 0 """ g = 'sageVAR' + self.variable_name() diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index ca523ee9a95..f221fd64de0 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10589,7 +10589,7 @@ cdef class Expression(Expression_abc): 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) sage: ex.simplify(algorithm='sympy') I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) - sage: ex.simplify(algorithm='giac') + sage: ex.simplify(algorithm='giac') # needs giac I*sqrt(x^2 - 1) sage: ex.simplify(algorithm='fricas') # optional - fricas (I*x^2 + I*sqrt(x^2 - 1)*x - I)/(x + sqrt(x^2 - 1)) @@ -13045,6 +13045,7 @@ cdef class Expression(Expression_abc): Use Giac to perform this summation:: + sage: # needs giac sage: (sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac')).factor() pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) @@ -13196,9 +13197,16 @@ cdef class Expression(Expression_abc): sage: integral(f, z) (x, y) |--> (x + y)*z - We check that :issue:`13097` is resolved:: + We check that :issue:`13097` is resolved (sage doesn't + crash). If giac is available, you may even get a usable + answer:: - sage: integrate(ln(1+4/5*sin(x)), x, -3.1415, 3.1415) # tol 10e-6 + sage: f = ln(1+4/5*sin(x)) + sage: integrate(f, x, -3.1415, 3.1415) # random + integrate(log(4/5*sin(x) + 1), x, -3.14150000000000, + 3.14150000000000) + sage: # needs sage.libs.giac + sage: integrate(f, x, -3.1415, 3.1415) # tol 10e-6 -1.40205228301000 """ from sage.symbolic.integration.integral import \ diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index 6bb2592a668..0877d132030 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -111,8 +111,10 @@ def _eval_(self, f, x): sage: integrate(1/(x^4 + x^3 + 1), x) integrate(1/(x^4 + x^3 + 1), x) - Check that :issue:`32002` is fixed:: + Check that :issue:`32002` is fixed. This needs giac since only + giac can integrate it in any case:: + sage: # needs sage.libs.giac sage: result = integral(2*min_symbolic(x,2*x),x) ... sage: result @@ -947,21 +949,38 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): Some integrals are now working (:issue:`27958`, using giac or sympy):: - sage: result = integrate(1/(1 + abs(x)), x) + sage: result = integrate(abs(x^2 - 1), x, -2, 2) ... sage: result - log(abs(x*sgn(x) + 1))/sgn(x) + 4 - sage: result = integrate(cos(x + abs(x)), x) + sage: result = integrate(sgn(x) - sgn(1-x), x) ... sage: result - sin(x*sgn(x) + x)/(sgn(x) + 1) + abs(x - 1) + abs(x) + + sage: result = integrate(1 / (1 + abs(x-5)), x, -5, 6) + ... + sage: result + log(11) + log(2) sage: result = integrate(abs(x^2 - 1), x, -2, 2) ... sage: result 4 + Examples that only giac can correctly integrate (for now):: + + sage: # needs sage.libs.giac + sage: g = abs(sin(x)*cos(x)) + sage: result = g.integrate(x, 0, 2*pi) + ... + sage: result + 2 + + :: + + sage: # needs sage.libs.giac sage: f = sqrt(x + 1/x^2) sage: actual = integrate(f, x) ... @@ -970,42 +989,46 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: bool(actual == expected) True - sage: g = abs(sin(x)*cos(x)) - sage: result = g.integrate(x, 0, 2*pi) - ... - sage: result - 2 + :: - sage: result = integrate(1/sqrt(abs(x)), x) + sage: # needs sage.libs.giac + sage: result = integrate(cos(x + abs(x)), x) ... sage: result - 2*sqrt(x*sgn(x))/sgn(x) + sin(x*sgn(x) + x)/(sgn(x) + 1) - sage: result = integrate(sgn(x) - sgn(1-x), x) + :: + + sage: # needs sage.libs.giac + sage: result = integrate(1/(1 + abs(x)), x) ... sage: result - abs(x - 1) + abs(x) + log(abs(x*sgn(x) + 1))/sgn(x) - sage: result = integrate(1 / (1 + abs(x-5)), x, -5, 6) + :: + + sage: # needs sage.libs.giac + sage: result = integrate(1/sqrt(abs(x)), x) ... sage: result - log(11) + log(2) + 2*sqrt(x*sgn(x))/sgn(x) + :: + + sage: # needs sage.libs.giac sage: result = integrate(1/(1 + abs(x)), x) ... sage: result log(abs(x*sgn(x) + 1))/sgn(x) + :: + + sage: # needs sage.libs.giac sage: result = integrate(cos(x + abs(x)), x) ... sage: result sin(x*sgn(x) + x)/(sgn(x) + 1) - sage: result = integrate(abs(x^2 - 1), x, -2, 2) - ... - sage: result - 4 - Some tests for :issue:`17468`:: sage: integral(log(abs(2*sin(x))), x, 0, pi/3) diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index fd0a0784e11..d0098871834 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -621,7 +621,8 @@ def solve(f, *args, **kwds): - ``algorithm`` -- string (default: ``'maxima'``); to use SymPy's solvers set this to 'sympy'. Note that SymPy is always used - for diophantine equations. Another choice is 'giac'. + for diophantine equations. Another choice, if it is installed, + is 'giac'. - ``domain`` -- string (default: ``'complex'``); setting this to 'real' changes the way SymPy solves single equations; inequalities @@ -926,13 +927,16 @@ def solve(f, *args, **kwds): A basic interface to Giac is provided:: + sage: # needs sage.libs.giac sage: solve([(2/3)^x-2], [x], algorithm='giac') ...[[-log(2)/(log(3) - log(2))]] + sage: # needs sage.libs.giac sage: f = (sin(x) - 8*cos(x)*sin(x))*(sin(x)^2 + cos(x)) - (2*cos(x)*sin(x) - sin(x))*(-2*sin(x)^2 + 2*cos(x)^2 - cos(x)) sage: solve(f, x, algorithm='giac') ...[-2*arctan(sqrt(2)), 0, 2*arctan(sqrt(2)), pi] + sage: # needs sage.libs.giac sage: x, y = SR.var('x,y') sage: solve([x+y-4,x*y-3],[x,y],algorithm='giac') [[1, 3], [3, 1]] @@ -1434,17 +1438,20 @@ def _giac_solver(f, x, solution_dict=False): EXAMPLES:: + sage: # needs sage.libs.giac sage: solve([(2/3)^x-2], [x], algorithm='giac') ...[[-log(2)/(log(3) - log(2))]] sage: solve([(2/3)^x-2], [x], algorithm='giac', solution_dict=True) ...[{x: -log(2)/(log(3) - log(2))}] + sage: # needs sage.libs.giac sage: f = (sin(x) - 8*cos(x)*sin(x))*(sin(x)^2 + cos(x)) - (2*cos(x)*sin(x) - sin(x))*(-2*sin(x)^2 + 2*cos(x)^2 - cos(x)) sage: solve(f, x, algorithm='giac') ...[-2*arctan(sqrt(2)), 0, 2*arctan(sqrt(2)), pi] sage: solve(f, x, algorithm='giac', solution_dict=True) ...[{x: -2*arctan(sqrt(2))}, {x: 0}, {x: 2*arctan(sqrt(2))}, {x: pi}] + sage: # needs sage.libs.giac sage: x, y = SR.var('x,y') sage: solve([x+y-7,x*y-10],[x,y],algorithm='giac') [[2, 5], [5, 2]]