From 5f383d6cfe22ee07eaa466d1b359eb0ed98f0d68 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 01/30] More # optional --- src/sage/misc/explain_pickle.py | 214 +++++++++++++++++--------------- 1 file changed, 112 insertions(+), 102 deletions(-) diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 30c3988850b..2fb34a2234e 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -5,9 +5,9 @@ - Carl Witty (2009-03) -The explain_pickle function takes a pickle and produces Sage code that +The :func:`explain_pickle` function takes a pickle and produces Sage code that will evaluate to the contents of the pickle. Ideally, the combination -of explain_pickle to produce Sage code and sage_eval to evaluate the code +of :func:`explain_pickle` to produce Sage code and :func:`sage_eval` to evaluate the code would be a 100% compatible implementation of cPickle's unpickler; this is almost the case now. @@ -27,9 +27,9 @@ True By default (as above) the code produced contains calls to several -utility functions (unpickle_global, etc.); this is done so that the +utility functions (:func:`unpickle_global`, etc.); this is done so that the code is truly equivalent to the pickle. If the pickle can be loaded -into a future version of Sage, then the code that explain_pickle +into a future version of Sage, then the code that :func:`explain_pickle` produces today should work in that future Sage as well. It is also possible to produce simpler code, that is tied to the current @@ -44,11 +44,11 @@ from sage.rings.rational import make_rational Polynomial_rational_flint(unpickle_PolynomialRing(RationalField(), ('x',), None, False), [make_rational('0'), make_rational('1')], False, True) -The explain_pickle function has several use cases. +The :func:`explain_pickle` function has several use cases. - Write pickling support for your classes - You can use explain_pickle to see what will happen when a pickle + You can use :func:`explain_pickle` to see what will happen when a pickle is unpickled. Consider: is this sequence of commands something that can be easily supported in all future Sage versions, or does it expose internal design decisions that are subject to change? @@ -56,55 +56,55 @@ - Debug old pickles If you have a pickle from an old version of Sage that no longer - unpickles, you can use explain_pickle to see what it is trying to + unpickles, you can use :func:`explain_pickle` to see what it is trying to do, to figure out how to fix it. - - Use explain_pickle in doctests to help maintenance + - Use :func:`explain_pickle` in doctests to help maintenance If you have a ``loads(dumps(S))`` doctest, you could also add an ``explain_pickle(dumps(S))`` doctest. Then if something changes in a way that would invalidate old pickles, the output of - ``explain_pickle`` will also change. At that point, you can add + :func:`explain_pickle` will also change. At that point, you can add the previous output of :obj:`explain_pickle` as a new set of doctests (and then update the :obj:`explain_pickle` doctest to use the new output), to ensure that old pickles will continue to work. -As mentioned above, there are several output modes for :obj:`explain_pickle`, +As mentioned above, there are several output modes for :func:`explain_pickle`, that control fidelity versus simplicity of the output. For example, the GLOBAL instruction takes a module name and a class name and produces the corresponding class. So GLOBAL of ``sage.rings.integer``, ``Integer`` is approximately equivalent to ``sage.rings.integer.Integer``. However, this class lookup process can be customized (using -sage.misc.persist.register_unpickle_override). For instance, +:func:`sage.misc.persist.register_unpickle_override`). For instance, if some future version of Sage renamed ``sage/rings/integer.pyx`` to ``sage/rings/knuth_was_here.pyx``, old pickles would no longer work unless register_unpickle_override was used; in that case, GLOBAL of -'sage.rings.integer', 'integer' would mean +``sage.rings.integer``, ``integer`` would mean ``sage.rings.knuth_was_here.integer``. -By default, ``explain_pickle`` will map this GLOBAL instruction to +By default, :func:`explain_pickle` will map this GLOBAL instruction to ``unpickle_global('sage.rings.integer', 'integer')``. Then when this code -is evaluated, unpickle_global will look up the current mapping in the -register_unpickle_override table, so the generated code will continue -to work even in hypothetical future versions of Sage where integer.pyx +is evaluated, :func:`unpickle_global` will look up the current mapping in the +:func:`register_unpickle_override` table, so the generated code will continue +to work even in hypothetical future versions of Sage where ``integer.pyx`` has been renamed. If you pass the flag ``in_current_sage=True``, then -:obj:`explain_pickle` will generate code that may only work in the +:func:`explain_pickle` will generate code that may only work in the current version of Sage, not in future versions. In this case, it would generate:: from sage.rings.integer import integer -and if you ran explain_pickle in hypothetical future sage, it would generate: +and if you ran :func:`explain_pickle` in hypothetical future sage, it would generate: from sage.rings.knuth_was_here import integer but the current code wouldn't work in the future sage. If you pass the flag ``default_assumptions=True``, then -:obj:`explain_pickle` will generate code that would work in the +:func:`explain_pickle` will generate code that would work in the absence of any special unpickling information. That is, in either current Sage or hypothetical future Sage, it would generate:: @@ -114,32 +114,32 @@ human-readable), but may not actually work; so it is only intended for human reading. -There are several functions used in the output of :obj:`explain_pickle`. +There are several functions used in the output of :func:`explain_pickle`. Here I give a brief description of what they usually do, as well as how to modify their operation (for instance, if you're trying to get old pickles to work). - ``unpickle_global(module, classname)``: - unpickle_global('sage.foo.bar', 'baz') is usually equivalent to - sage.foo.bar.baz, but this can be customized with - register_unpickle_override. + ``unpickle_global('sage.foo.bar', 'baz')`` is usually equivalent to + ``sage.foo.bar.baz``, but this can be customized with + :func:`register_unpickle_override`. - ``unpickle_newobj(klass, args)``: Usually equivalent to ``klass.__new__(klass, *args)``. If ``klass`` is a Python class, then you can define :meth:`__new__` to control the result (this result actually need not be an - instance of klass). (This doesn't work for Cython classes.) + instance of ``klass``). (This doesn't work for Cython classes.) - ``unpickle_build(obj, state)``: If ``obj`` has a :meth:`__setstate__` method, then this is equivalent to - ``obj.__setstate__(state)``. Otherwise uses state to set the attributes + ``obj.__setstate__(state)``. Otherwise uses ``state`` to set the attributes of ``obj``. Customize by defining :meth:`__setstate__`. - ``unpickle_instantiate(klass, args)``: Usually equivalent to ``klass(*args)``. Cannot be customized. - - unpickle_appends(lst, vals): - Appends the values in vals to lst. If not ``isinstance(lst, list)``, + - ``unpickle_appends(lst, vals)``: + Appends the values in ``vals`` to ``lst``. If not ``isinstance(lst, list)``, can be customized by defining a :meth:`append` method. """ @@ -165,7 +165,6 @@ from pickletools import genops -import sage.all from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.misc.sage_eval import sage_eval from sage.misc.persist import (unpickle_override, unpickle_global, dumps, @@ -181,30 +180,30 @@ def explain_pickle(pickle=None, file=None, compress=True, **kwargs): r""" Explain a pickle. That is, produce source code such that evaluating the code is equivalent to loading the pickle. Feeding the result - of ``explain_pickle`` to ``sage_eval`` should be totally equivalent to loading + of :func:`explain_pickle` to :func:`sage_eval` should be totally equivalent to loading the ``pickle`` with ``cPickle``. INPUT: - - ``pickle`` -- the pickle to explain, as a string (default: None) - - ``file`` -- a filename of a pickle (default: None) - - ``compress`` -- if False, don't attempt to decompress the pickle - (default: True) - - ``in_current_sage`` -- if True, produce potentially simpler code that is - tied to the current version of Sage. (default: False) - - ``default_assumptions`` -- if True, produce potentially simpler code that - assumes that generic unpickling code will be - used. This code may not actually work. - (default: False) - - ``eval`` -- if True, then evaluate the resulting code and return the - evaluated result. (default: False) - - ``preparse`` -- if True, then produce code to be evaluated with - Sage's preparser; if False, then produce standard - Python code; if None, then produce code that will work - either with or without the preparser. (default: True) - - ``pedantic`` -- if True, then carefully ensures that the result has - at least as much sharing as the result of cPickle - (it may have more, for immutable objects). (default: False) + - ``pickle`` -- the pickle to explain, as a string (default: ``None``) + - ``file`` -- a filename of a pickle (default: ``None``) + - ``compress`` -- if ``False``, don't attempt to decompress the pickle + (default: ``True``) + - ``in_current_sage`` -- if ``True``, produce potentially simpler code that is + tied to the current version of Sage. (default: ``False``) + - ``default_assumptions`` -- if ``True``, produce potentially simpler code that + assumes that generic unpickling code will be + used. This code may not actually work. + (default: ``False``) + - ``eval`` -- if ``True``, then evaluate the resulting code and return the + evaluated result. (default: ``False``) + - ``preparse`` -- if ``True``, then produce code to be evaluated with + Sage's preparser; if ``False``, then produce standard + Python code; if ``None``, then produce code that will work + either with or without the preparser. (default: ``True``) + - ``pedantic`` -- if ``True``, then carefully ensures that the result has + at least as much sharing as the result of cPickle + (it may have more, for immutable objects). (default: ``False``) Exactly one of ``pickle`` (a string containing a pickle) or ``file`` (the filename of a pickle) must be provided. @@ -263,16 +262,16 @@ def explain_pickle_string(pickle, in_current_sage=False, default_assumptions=False, eval=False, preparse=True, pedantic=False): r""" - This is a helper function for explain_pickle. It takes a decompressed + This is a helper function for :func:`explain_pickle`. It takes a decompressed pickle string as input; other than that, its options are all the same - as explain_pickle. + as :func:`explain_pickle`. EXAMPLES:: sage: sage.misc.explain_pickle.explain_pickle_string(dumps("Hello, world", compress=False)) 'Hello, world' - (See the documentation for ``explain_pickle`` for many more examples.) + (See the documentation for :func:`explain_pickle` for many more examples.) """ sib = SageInputBuilder(preparse=preparse) @@ -321,17 +320,19 @@ def name_is_valid(name): class PickleObject(): r""" - Pickles have a stack-based virtual machine. The explain_pickle - pickle interpreter mostly uses SageInputExpressions, from sage_input, + Pickles have a stack-based virtual machine. The :func:`explain_pickle` + pickle interpreter mostly uses :class:`sage.misc.sage_input.SageInputExpression` objects as the stack values. However, sometimes we want some more information about the value on the stack, so that we can generate better (prettier, less confusing) code. In such cases, we push - a PickleObject instead of a SageInputExpression. A PickleObject + a :class:`PickleObject` instead of a :class:`~sage.misc.sage_input.SageInputExpression`. + A :class:`PickleObject` contains a value (which may be a standard Python value, or a - PickleDict or PickleInstance), an expression (a SageInputExpression), + :class:`PickleDict` or :class:`PickleInstance`), an expression + (a :class:`~sage.misc.sage_input.SageInputExpression`), and an "immutable" flag (which checks whether this object - has been converted to a SageInputExpression; if it has, then we - must not mutate the object, since the SageInputExpression would not + has been converted to a :class:`SageInputExpression`; if it has, then we + must not mutate the object, since the :class:`SageInputExpression` would not reflect the changes). """ @@ -375,9 +376,9 @@ def _sage_input_(self, sib, coerced): class PickleDict(): r""" - An object which can be used as the value of a PickleObject. The items + An object which can be used as the value of a :class:`PickleObject`. The items is a list of key-value pairs, where the keys and values are - SageInputExpressions. We use this to help construct dictionary literals, + :class:`SageInputExpression` objects. We use this to help construct dictionary literals, instead of always starting with an empty dictionary and assigning to it. """ @@ -395,8 +396,8 @@ def __init__(self, items): class PickleInstance(): r""" - An object which can be used as the value of a PickleObject. Unlike - other possible values of a PickleObject, a PickleInstance doesn't represent + An object which can be used as the value of a :class:`PickleObject`. Unlike + other possible values of a :class:`PickleObject`, a :class:`PickleInstance` doesn't represent an exact value; instead, it gives the class (type) of the object. """ def __init__(self, klass): @@ -414,7 +415,7 @@ def __init__(self, klass): class PickleExplainer(): r""" An interpreter for the pickle virtual machine, that executes - symbolically and constructs SageInputExpressions instead of + symbolically and constructs :class:`SageInputExpression` objects instead of directly constructing values. """ def __init__(self, sib, in_current_sage=False, default_assumptions=False, @@ -448,7 +449,7 @@ def run_pickle(self, p): r""" Given an (uncompressed) pickle as a string, run the pickle in this virtual machine. Once a STOP has been executed, return - the result (a SageInputExpression representing code which, when + the result (a :class:`SageInputExpression` representing code which, when evaluated, will give the value of the pickle). EXAMPLES:: @@ -477,8 +478,8 @@ def run_pickle(self, p): def check_value(self, v): r""" - Check that the given value is either a SageInputExpression or a - PickleObject. Used for internal sanity checking. + Check that the given value is either a :class:`SageInputExpression` or a + :class:`PickleObject`. Used for internal sanity checking. EXAMPLES:: @@ -514,7 +515,7 @@ def push(self, v): def push_and_share(self, v): r""" Push a value onto the virtual machine's stack; also mark it as shared - for sage_input if we are in pedantic mode. + for :func:`sage_input` if we are in pedantic mode. EXAMPLES:: @@ -595,14 +596,15 @@ def pop_to_mark(self): def share(self, v): r""" - Mark a sage_input value as shared, if we are in pedantic mode. + Mark a :func:`sage_input` value as shared, if we are in pedantic mode. EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = sib(7) sage: v._sie_share False @@ -617,15 +619,16 @@ def share(self, v): def is_mutable_pickle_object(self, v): r""" - Test whether a PickleObject is mutable (has never been converted - to a SageInputExpression). + Test whether a :class:`PickleObject` is mutable (has never been converted + to a :class:`SageInputExpression`). EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = PickleObject(1, sib(1)) sage: pe.is_mutable_pickle_object(v) True @@ -1394,7 +1397,12 @@ def GLOBAL(self, name): # OK, we know what module and function name will actually # be used, as well as the actual function. # Is this already available at the command line? - cmdline_f = getattr(sage.all, func, None) + try: + import sage.all + except ImportError: + cmdline_f = None + else: + cmdline_f = getattr(sage.all, func, None) if cmdline_f is f: self.push(PickleObject(f, self.sib.name(func))) return @@ -2368,7 +2376,7 @@ def UNICODE(self, s): def unpickle_newobj(klass, args): r""" Create a new object; this corresponds to the C code - klass->tp_new(klass, args, NULL). Used by ``explain_pickle``. + ``klass->tp_new(klass, args, NULL)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2413,7 +2421,7 @@ def pers_load(id): def unpickle_build(obj, state): r""" - Set the state of an object. Used by ``explain_pickle``. + Set the state of an object. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2447,8 +2455,8 @@ def unpickle_build(obj, state): def unpickle_instantiate(fn, args): r""" - Instantiate a new object of class fn with arguments args. Almost always - equivalent to ``fn(*args)``. Used by ``explain_pickle``. + Instantiate a new object of class ``fn`` with arguments ``args``. Almost always + equivalent to ``fn(*args)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2469,7 +2477,7 @@ def unpickle_persistent(s): r""" Takes an integer index and returns the persistent object with that index; works by calling whatever callable is stored in - unpickle_persistent_loader. Used by ``explain_pickle``. + ``unpickle_persistent_loader``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2484,7 +2492,7 @@ def unpickle_persistent(s): def unpickle_extension(code): r""" Takes an integer index and returns the extension object with that - index. Used by ``explain_pickle``. + index. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2512,7 +2520,7 @@ def unpickle_appends(lst, vals): r""" Given a list (or list-like object) and a sequence of values, appends the values to the end of the list. This is careful to do so using the - exact same technique that cPickle would use. Used by ``explain_pickle``. + exact same technique that cPickle would use. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2532,7 +2540,9 @@ def unpickle_appends(lst, vals): def test_pickle(p, verbose_eval=False, pedantic=False, args=()): r""" - Tests explain_pickle on a given pickle p. p can be: + Test :func:`explain_pickle` on a given pickle ``p``. + + ``p`` can be: - a string containing an uncompressed pickle (which will always end with a '.') @@ -2542,14 +2552,14 @@ def test_pickle(p, verbose_eval=False, pedantic=False, args=()): the stack (using persistent IDs), run the pickle fragment, and then STOP (if the string 'mark' occurs in args, then a mark will be pushed) - - an arbitrary object; test_pickle will pickle the object + - an arbitrary object; :func:`test_pickle` will pickle the object - Once it has a pickle, test_pickle will print the pickle's - disassembly, run explain_pickle with in_current_sage=True and - False, print the results, evaluate the results, unpickle the + Once it has a pickle, :func:`test_pickle` will print the pickle's + disassembly, run :func:`explain_pickle` with ``in_current_sage=True`` and + ``False``, print the results, evaluate the results, unpickle the object with cPickle, and compare all three results. - If verbose_eval is True, then test_pickle will print messages + If ``verbose_eval`` is ``True``, then :func:`test_pickle` will print messages before evaluating the pickles; this is to allow for tests where the unpickling prints messages (to verify that the same operations occur in all cases). @@ -2636,7 +2646,7 @@ def pers_load(s): class EmptyOldstyleClass: r""" A featureless old-style class (does not inherit from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2674,7 +2684,7 @@ def __hash__(self): class EmptyNewstyleClass(): r""" A featureless new-style class (inherits from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2696,8 +2706,8 @@ def __repr__(self): class TestReduceGetinitargs: r""" - An old-style class with a __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with a :func:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2748,8 +2758,8 @@ def __repr__(self): class TestReduceNoGetinitargs: r""" - An old-style class with no __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with no :meth:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2786,8 +2796,8 @@ def __repr__(self): class TestAppendList(list): r""" - A subclass of list, with deliberately-broken append and extend methods. - Used for testing explain_pickle. + A subclass of :class:`list`, with deliberately-broken append and extend methods. + Used for testing :func:`explain_pickle`. """ def append(self): r""" @@ -2835,7 +2845,7 @@ def extend(self): class TestAppendNonlist(): r""" A list-like class, carefully designed to test exact unpickling - behavior. Used for testing explain_pickle. + behavior. Used for testing :func:`explain_pickle`. """ def __init__(self): r""" @@ -2918,8 +2928,8 @@ def __repr__(self): class TestBuild(): r""" - A simple class with a __getstate__ but no __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` but no :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __getstate__(self): r""" @@ -2955,8 +2965,8 @@ def __repr__(self): class TestBuildSetstate(TestBuild): r""" - A simple class with a __getstate__ and a __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` and a :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __setstate__(self, state): r""" @@ -2978,8 +2988,8 @@ def __setstate__(self, state): class TestGlobalOldName(): r""" A featureless new-style class. When you try to unpickle an instance - of this class, it is redirected to create a TestGlobalNewName instead. - Used for testing explain_pickle. + of this class, it is redirected to create a :class:`TestGlobalNewName` instead. + Used for testing :func:`explain_pickle`. EXAMPLES:: @@ -2993,8 +3003,8 @@ class TestGlobalOldName(): class TestGlobalNewName(): r""" A featureless new-style class. When you try to unpickle an instance - of TestGlobalOldName, it is redirected to create an instance of this - class instead. Used for testing explain_pickle. + of :class:`TestGlobalOldName`, it is redirected to create an instance of this + class instead. Used for testing :func:`explain_pickle`. EXAMPLES:: From 66db7aa276741cf67673b43ded108f8a3220d2ac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 21:38:40 -0800 Subject: [PATCH 02/30] Add # optional - numpy etc. --- src/sage/interfaces/sympy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interfaces/sympy.py b/src/sage/interfaces/sympy.py index a334c241127..c380731f8b7 100644 --- a/src/sage/interfaces/sympy.py +++ b/src/sage/interfaces/sympy.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy """ SymPy --> Sage conversion From 753ac98a9b0ffab5993f86a1fe86e8ae29d4f110 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 13 May 2023 15:58:37 -0700 Subject: [PATCH 03/30] src/sage/interfaces/tides.py: pycodestyle fix --- src/sage/interfaces/tides.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index f70a2357cd3..1b00f52df54 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -37,8 +37,10 @@ - [TIDES]_ """ + from sage.rings.real_mpfr import RealField -from sage.calculus.all import symbolic_expression +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.all", "symbolic_expression") from sage.misc.flatten import flatten from sage.ext.fast_callable import fast_callable from sage.rings.semirings.non_negative_integer_semiring import NN From 0eb6d0a834b992985ea035a27861cbf333bb54f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 13:20:30 -0700 Subject: [PATCH 04/30] Massive modularization fixes --- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/gp.py | 28 ++++++++++++++-------------- src/sage/interfaces/interface.py | 1 + src/sage/interfaces/jmoldata.py | 6 +++--- src/sage/interfaces/quit.py | 14 +++++++------- src/sage/interfaces/tests.py | 2 +- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 17ad63cfbac..9c38a8c1cba 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic """ Common Interface Functionality through Pexpect diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index e5c77833cca..c777bc6bd40 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -787,26 +787,26 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def + sage: pi_def = gp(pi); pi_def # optional - sage.symbolic 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() + sage: pi_def.precision() # optional - sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) - sage: new_prec = pi_150.precision(); new_prec + sage: pi_150 = gp.new_with_bits_prec(pi, 150) # optional - sage.symbolic + sage: new_prec = pi_150.precision(); new_prec # optional - sage.symbolic 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec + sage: old_prec = gp.set_precision(new_prec); old_prec # optional - sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 + sage: pi_150 # optional - sage.symbolic 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) + sage: gp.set_precision(old_prec) # optional - sage.symbolic 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() + sage: gp.get_precision() # optional - sage.symbolic 28 # 32-bit 38 # 64-bit """ @@ -877,9 +877,9 @@ def _sage_(self): EXAMPLES:: - sage: gp(SR(I)).sage() + sage: gp(SR(I)).sage() # optional - sage.symbolic i - sage: gp(SR(I)).sage().parent() + sage: gp(SR(I)).sage().parent() # optional - sage.symbolic Number Field in i with defining polynomial x^2 + 1 with i = 1*I :: @@ -955,11 +955,11 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z + sage: z = gp(SR(1+15*I)); z # optional - sage.symbolic 1 + 15*I - sage: z._complex_mpfr_field_(CC) + sage: z._complex_mpfr_field_(CC) # optional - sage.symbolic 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) + sage: CC(z) # CC(gp(1+15*I)) # optional - sage.symbolic 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I @@ -977,7 +977,7 @@ def _complex_double_(self, CDF): EXAMPLES:: - sage: CDF(gp(pi+I*e)) + sage: CDF(gp(pi+I*e)) # optional - sage.symbolic 3.141592653589793 + 2.718281828459045*I """ # Retrieving values from another computer algebra system is diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 78f94269ff4..4c0f1205092 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic r""" Common Interface Functionality diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index a68e53e2d85..2890a8a7a76 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -134,10 +134,10 @@ def export_image(self, sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() - sage: D = dodecahedron() + sage: D = dodecahedron() # optional - sage.plot sage: from tempfile import NamedTemporaryFile sage: archive = NamedTemporaryFile(suffix=".zip") - sage: D.export_jmol(archive.name) + sage: D.export_jmol(archive.name) # optional - sage.plot sage: archive_native = archive.name sage: import sys sage: if sys.platform == 'cygwin': @@ -145,7 +145,7 @@ def export_image(self, ....: archive_native = cygwin.cygpath(archive_native, 'w') sage: script = f'set defaultdirectory "f{archive_native}"\n' sage: script += 'script SCRIPT\n' - sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java + sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java sage.plot ....: JData.export_image(targetfile=testfile.name, ....: datafile=script, ....: image_type="PNG") diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 575646f2365..afc87aed1a7 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -140,19 +140,19 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) - sage: a, b + sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic + sage: a, b # optional - sage.libs.pari sage.symbolic (2, 3) - sage: sage.interfaces.quit.invalidate_all() - sage: a + sage: sage.interfaces.quit.invalidate_all() # optional - sage.libs.pari sage.symbolic + sage: a # optional - sage.libs.pari sage.symbolic (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b + sage: b # optional - sage.libs.pari sage.symbolic (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: - sage: a = maxima(2); b = gp(3) - sage: a, b + sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic + sage: a, b # optional - sage.libs.pari sage.symbolic (2, 3) """ for I in expect_objects: diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 8c760c2a2c0..6c0942e04f4 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -13,7 +13,7 @@ 4 sage: parent(a) Gap - sage: a = 2 * maxima('2'); a + sage: a = 2 * maxima('2'); a # optional - sage.symbolic 4 sage: parent(a) Maxima From 8ee15dc876d97ec50ae701ee234afb08a9a7646e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 May 2023 15:38:10 -0700 Subject: [PATCH 05/30] More # optional --- src/sage/interfaces/axiom.py | 20 ++++++++++---------- src/sage/interfaces/tests.py | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 5df8d2e184a..b00e9fc68a0 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -796,12 +796,12 @@ def _sage_(self): 2.12340000000000 sage: _.parent() #optional - axiom Real Field with 53 bits of precision - sage: a = RealField(100)(pi) - sage: axiom(a)._sage_() #optional - axiom + sage: a = RealField(100)(pi) # optional - sage.symbolic + sage: axiom(a)._sage_() #optional - axiom # optional - sage.symbolic 3.1415926535897932384626433833 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Real Field with 100 bits of precision - sage: axiom(a)._sage_() == a #optional - axiom + sage: axiom(a)._sage_() == a #optional - axiom # optional - sage.symbolic True sage: axiom(2.0)._sage_() #optional - axiom 2.00000000000000 @@ -810,16 +810,16 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) #optional - axiom - sage: a.type() #optional - axiom + sage: a = axiom(x^2 + 1) #optional - axiom # optional - sage.symbolic + sage: a.type() #optional - axiom # optional - sage.symbolic Polynomial Integer - sage: a.sage() #optional - axiom + sage: a.sage() #optional - axiom # optional - sage.symbolic x^2 + 1 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom + sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom # optional - sage.symbolic y^2 + x^2 + 1/2 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Multivariate Polynomial Ring in y, x over Rational Field diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 6c0942e04f4..a77a66e7876 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -15,7 +15,7 @@ Gap sage: a = 2 * maxima('2'); a # optional - sage.symbolic 4 - sage: parent(a) + sage: parent(a) # optional - sage.symbolic Maxima sage: a = 2 * singular('2'); a 4 From caa86847954d72b88b6bfc69e39b5c0809fde134 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 31 May 2023 23:15:29 -0700 Subject: [PATCH 06/30] sage.interfaces: Modularization fixes --- src/sage/interfaces/gp.py | 1 + src/sage/interfaces/interface.py | 20 +++++++------- src/sage/interfaces/maxima_abstract.py | 37 +++++++++++++++----------- src/sage/interfaces/sympy_wrapper.py | 1 + 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index c777bc6bd40..974ef82a406 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari r""" Interface to the GP calculator of PARI/GP diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 4c0f1205092..3774d033e0f 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -349,14 +349,14 @@ def _coerce_impl(self, x, use_special=True): if isinstance(x, bool): return self(self._true_symbol() if x else self._false_symbol()) elif isinstance(x, int): - import sage.rings.all - return self(sage.rings.all.Integer(x)) + from sage.rings.integer import Integer + return self(Integer(x)) elif isinstance(x, float): - import sage.rings.all - return self(sage.rings.all.RDF(x)) + from sage.rings.real_double import RDF + return self(RDF(x)) elif isinstance(x, complex): - import sage.rings.all - return self(sage.rings.all.CDF(x)) + from sage.rings.complex_double import CDF + return self(CDF(x)) if use_special: try: return self._coerce_from_special_method(x) @@ -1374,8 +1374,8 @@ def _integer_(self, ZZ=None): sage: QQ(m) 1 """ - import sage.rings.all - return sage.rings.all.Integer(repr(self)) + from sage.rings.integer import Integer + return Integer(repr(self)) def _rational_(self): """ @@ -1389,8 +1389,8 @@ def _rational_(self): sage: QQ(m) 1/2 """ - import sage.rings.all - return sage.rings.all.Rational(repr(self)) + from sage.rings.rational import Rational + return Rational(repr(self)) def name(self, new_name=None): """ diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 9fe624a7f02..bdb4494edf9 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1020,11 +1020,13 @@ def plot_list(self, ptsx, ptsy, options=None): EXAMPLES:: - sage: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range(70,150)] - sage: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range(70,150)] - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested + sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(70,150)] + sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(70,150)] + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # optional - sage.libs.pari sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]' - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # optional - sage.libs.pari """ cmd = 'plot2d([discrete,%s, %s]' % (ptsx, ptsy) if options is None: @@ -1056,18 +1058,23 @@ def plot_multilist(self, pts_list, options=None): EXAMPLES:: - sage: xx = [ i/10.0 for i in range(-10,10)] - sage: yy = [ i/10.0 for i in range(-10,10)] - sage: x0 = [ 0 for i in range(-10,10)] - sage: y0 = [ 0 for i in range(-10,10)] - sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range(10)] - sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range(10)] - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested - sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range(10,150)] - sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range(10,150)] - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested + sage: xx = [i/10.0 for i in range(-10,10)] + sage: yy = [i/10.0 for i in range(-10,10)] + sage: x0 = [0 for i in range(-10,10)] + sage: y0 = [0 for i in range(-10,10)] + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(10)] + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(10)] + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(10,150)] + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(10,150)] + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested sage: opts='[gnuplot_preamble, "set nokey"]' - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]],opts) # not tested + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]], # not tested + ....: opts) """ n = len(pts_list) cmd = '[' diff --git a/src/sage/interfaces/sympy_wrapper.py b/src/sage/interfaces/sympy_wrapper.py index 7f49cb76923..792d1eaee99 100644 --- a/src/sage/interfaces/sympy_wrapper.py +++ b/src/sage/interfaces/sympy_wrapper.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy """ Wrapper Class for Sage Sets as SymPy Sets """ From 2b0112d5ee64548920eaff8a201de1dfd2751121 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 07/30] More # optional --- src/sage/interfaces/quit.py | 18 +++++++++--------- src/sage/interfaces/sagespawn.pyx | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index afc87aed1a7..720ea3f080a 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -63,14 +63,14 @@ def expect_quitall(verbose=False): EXAMPLES:: sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' - sage: gp('a') + sage: gp('a') # optional - sage.libs.pari 10 sage: sage.interfaces.quit.expect_quitall() - sage: gp('a') + sage: gp('a') # optional - sage.libs.pari a - sage: sage.interfaces.quit.expect_quitall(verbose=True) + sage: sage.interfaces.quit.expect_quitall(verbose=True) # optional - sage.libs.pari Exiting PARI/GP interpreter with PID ... running .../gp --fast --emacs --quiet --stacksize 10000000 """ for P in expect_objects: @@ -87,18 +87,18 @@ def kill_spawned_jobs(verbose=False): """ INPUT: - - ``verbose`` -- bool (default: False); if True, display a - message each time a process is sent a kill signal + - ``verbose`` -- bool (default: ``False``); if ``True``, display a + message each time a process is sent a kill signal EXAMPLES:: - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' sage: sage.interfaces.quit.kill_spawned_jobs(verbose=False) sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' - sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) + sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # optional - sage.libs.pari Killing spawned job ... After doing the above, we do the following to avoid confusion in other doctests:: diff --git a/src/sage/interfaces/sagespawn.pyx b/src/sage/interfaces/sagespawn.pyx index 6bb9b90e580..497efc74bba 100644 --- a/src/sage/interfaces/sagespawn.pyx +++ b/src/sage/interfaces/sagespawn.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - ptyprocess """ Sage wrapper around pexpect's ``spawn`` class and the ptyprocess's ``PtyProcess`` class. From fa011659f1686a0870c9c5bc33549a2c18dba303 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Jun 2023 00:11:47 -0700 Subject: [PATCH 08/30] More # optional --- src/sage/interfaces/sage0.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 9eddb7019f7..a8bb27975c3 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F == sage0(F)._sage_() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules + sage: F,s = sr.polynomial_system() # optional - sage.modules + sage: F == sage0(F)._sage_() # optional - sage.modules True """ P = self.parent() From 19a524be5c2dd22be4fd894232766f8ccf0a81cb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Jun 2023 23:43:13 -0700 Subject: [PATCH 09/30] More # optional --- src/sage/interfaces/sage0.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index a8bb27975c3..0d43f2bd6b9 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules - sage: F,s = sr.polynomial_system() # optional - sage.modules - sage: F == sage0(F)._sage_() # optional - sage.modules + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # optional - sage.modules sage.rings.finite_rings + sage: F == sage0(F)._sage_() # optional - sage.modules sage.rings.finite_rings True """ P = self.parent() From e953197fc52ea3504442cb0561a1f9cf31dfa7a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Jul 2023 17:25:38 -0700 Subject: [PATCH 10/30] ./sage -fixdoctests --no-test src/sage/interfaces --- src/sage/interfaces/axiom.py | 20 +++++++++--------- src/sage/interfaces/gfan.py | 4 ++-- src/sage/interfaces/gp.py | 28 +++++++++++++------------- src/sage/interfaces/jmoldata.py | 6 +++--- src/sage/interfaces/maxima_abstract.py | 16 +++++++-------- src/sage/interfaces/quit.py | 28 +++++++++++++------------- src/sage/interfaces/sage0.py | 6 +++--- src/sage/interfaces/tests.py | 4 ++-- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index b00e9fc68a0..f61fcc638f9 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -796,12 +796,12 @@ def _sage_(self): 2.12340000000000 sage: _.parent() #optional - axiom Real Field with 53 bits of precision - sage: a = RealField(100)(pi) # optional - sage.symbolic - sage: axiom(a)._sage_() #optional - axiom # optional - sage.symbolic + sage: a = RealField(100)(pi) # needs sage.symbolic + sage: axiom(a)._sage_() # optional - axiom # needs sage.symbolic 3.1415926535897932384626433833 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Real Field with 100 bits of precision - sage: axiom(a)._sage_() == a #optional - axiom # optional - sage.symbolic + sage: axiom(a)._sage_() == a # optional - axiom # needs sage.symbolic True sage: axiom(2.0)._sage_() #optional - axiom 2.00000000000000 @@ -810,16 +810,16 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) #optional - axiom # optional - sage.symbolic - sage: a.type() #optional - axiom # optional - sage.symbolic + sage: a = axiom(x^2 + 1) # optional - axiom # needs sage.symbolic + sage: a.type() # optional - axiom # needs sage.symbolic Polynomial Integer - sage: a.sage() #optional - axiom # optional - sage.symbolic + sage: a.sage() # optional - axiom # needs sage.symbolic x^2 + 1 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom # optional - sage.symbolic + sage: axiom('x^2 + y^2 + 1/2').sage() # optional - axiom # needs sage.symbolic y^2 + x^2 + 1/2 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Multivariate Polynomial Ring in y, x over Rational Field diff --git a/src/sage/interfaces/gfan.py b/src/sage/interfaces/gfan.py index ffb75c39b35..01429c5cde6 100644 --- a/src/sage/interfaces/gfan.py +++ b/src/sage/interfaces/gfan.py @@ -63,7 +63,7 @@ def __call__(self, input, cmd='', verbose=False, format=None): EXAMPLES:: - sage: print(gfan('Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases')) # optional - gfan + sage: print(gfan('Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases')) # needs gfan Q[x,y] {{ y^4+4/9-7/3*y^2-y^3, @@ -85,7 +85,7 @@ def __call__(self, input, cmd='', verbose=False, format=None): TESTS:: - sage: _ = gfan(I='Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases') # optional - gfan + sage: _ = gfan(I='Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases') # needs gfan doctest:...: DeprecationWarning: use the option 'input' instead of 'I' See https://github.com/sagemath/sage/issues/33468 for details. diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 974ef82a406..d1085562828 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -788,26 +788,26 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def # optional - sage.symbolic + sage: pi_def = gp(pi); pi_def # needs sage.symbolic 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() # optional - sage.symbolic + sage: pi_def.precision() # needs sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) # optional - sage.symbolic - sage: new_prec = pi_150.precision(); new_prec # optional - sage.symbolic + sage: pi_150 = gp.new_with_bits_prec(pi, 150) # needs sage.symbolic + sage: new_prec = pi_150.precision(); new_prec # needs sage.symbolic 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec # optional - sage.symbolic + sage: old_prec = gp.set_precision(new_prec); old_prec # needs sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 # optional - sage.symbolic + sage: pi_150 # needs sage.symbolic 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) # optional - sage.symbolic + sage: gp.set_precision(old_prec) # needs sage.symbolic 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() # optional - sage.symbolic + sage: gp.get_precision() # needs sage.symbolic 28 # 32-bit 38 # 64-bit """ @@ -878,9 +878,9 @@ def _sage_(self): EXAMPLES:: - sage: gp(SR(I)).sage() # optional - sage.symbolic + sage: gp(SR(I)).sage() # needs sage.symbolic i - sage: gp(SR(I)).sage().parent() # optional - sage.symbolic + sage: gp(SR(I)).sage().parent() # needs sage.symbolic Number Field in i with defining polynomial x^2 + 1 with i = 1*I :: @@ -956,11 +956,11 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z # optional - sage.symbolic + sage: z = gp(SR(1+15*I)); z # needs sage.symbolic 1 + 15*I - sage: z._complex_mpfr_field_(CC) # optional - sage.symbolic + sage: z._complex_mpfr_field_(CC) # needs sage.symbolic 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) # optional - sage.symbolic + sage: CC(z) # CC(gp(1+15*I)) # needs sage.symbolic 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I @@ -978,7 +978,7 @@ def _complex_double_(self, CDF): EXAMPLES:: - sage: CDF(gp(pi+I*e)) # optional - sage.symbolic + sage: CDF(gp(pi+I*e)) # needs sage.symbolic 3.141592653589793 + 2.718281828459045*I """ # Retrieving values from another computer algebra system is diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index 2890a8a7a76..3e83043d747 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -134,10 +134,10 @@ def export_image(self, sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() - sage: D = dodecahedron() # optional - sage.plot + sage: D = dodecahedron() # needs sage.plot sage: from tempfile import NamedTemporaryFile sage: archive = NamedTemporaryFile(suffix=".zip") - sage: D.export_jmol(archive.name) # optional - sage.plot + sage: D.export_jmol(archive.name) # needs sage.plot sage: archive_native = archive.name sage: import sys sage: if sys.platform == 'cygwin': @@ -145,7 +145,7 @@ def export_image(self, ....: archive_native = cygwin.cygpath(archive_native, 'w') sage: script = f'set defaultdirectory "f{archive_native}"\n' sage: script += 'script SCRIPT\n' - sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java sage.plot + sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional - java, needs sage.plot ....: JData.export_image(targetfile=testfile.name, ....: datafile=script, ....: image_type="PNG") diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index bdb4494edf9..abc43baf127 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1020,13 +1020,13 @@ def plot_list(self, ptsx, ptsy, options=None): EXAMPLES:: - sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(70,150)] - sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(70,150)] - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # optional - sage.libs.pari + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # needs sage.libs.pari sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]' - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # optional - sage.libs.pari + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # needs sage.libs.pari """ cmd = 'plot2d([discrete,%s, %s]' % (ptsx, ptsy) if options is None: @@ -1062,14 +1062,14 @@ def plot_multilist(self, pts_list, options=None): sage: yy = [i/10.0 for i in range(-10,10)] sage: x0 = [0 for i in range(-10,10)] sage: y0 = [0 for i in range(-10,10)] - sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(10)] - sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(10)] sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested - sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(10,150)] - sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(10,150)] sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested sage: opts='[gnuplot_preamble, "set nokey"]' diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 720ea3f080a..99e5aa018f3 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -63,14 +63,14 @@ def expect_quitall(verbose=False): EXAMPLES:: sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' - sage: gp('a') # optional - sage.libs.pari + sage: gp('a') # needs sage.libs.pari 10 sage: sage.interfaces.quit.expect_quitall() - sage: gp('a') # optional - sage.libs.pari + sage: gp('a') # needs sage.libs.pari a - sage: sage.interfaces.quit.expect_quitall(verbose=True) # optional - sage.libs.pari + sage: sage.interfaces.quit.expect_quitall(verbose=True) # needs sage.libs.pari Exiting PARI/GP interpreter with PID ... running .../gp --fast --emacs --quiet --stacksize 10000000 """ for P in expect_objects: @@ -92,13 +92,13 @@ def kill_spawned_jobs(verbose=False): EXAMPLES:: - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' sage: sage.interfaces.quit.kill_spawned_jobs(verbose=False) sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' - sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # optional - sage.libs.pari + sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # needs sage.libs.pari Killing spawned job ... After doing the above, we do the following to avoid confusion in other doctests:: @@ -140,19 +140,19 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic - sage: a, b # optional - sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic + sage: a, b # needs sage.libs.pari sage.symbolic (2, 3) - sage: sage.interfaces.quit.invalidate_all() # optional - sage.libs.pari sage.symbolic - sage: a # optional - sage.libs.pari sage.symbolic + sage: sage.interfaces.quit.invalidate_all() # needs sage.libs.pari sage.symbolic + sage: a # needs sage.libs.pari sage.symbolic (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b # optional - sage.libs.pari sage.symbolic + sage: b # needs sage.libs.pari sage.symbolic (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: - sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic - sage: a, b # optional - sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic + sage: a, b # needs sage.libs.pari sage.symbolic (2, 3) """ for I in expect_objects: diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 0d43f2bd6b9..1505d1f2f69 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules sage.rings.finite_rings - sage: F,s = sr.polynomial_system() # optional - sage.modules sage.rings.finite_rings - sage: F == sage0(F)._sage_() # optional - sage.modules sage.rings.finite_rings + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # needs sage.modules sage.rings.finite_rings + sage: F == sage0(F)._sage_() # needs sage.modules sage.rings.finite_rings True """ P = self.parent() diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index a77a66e7876..13f755b4d11 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -13,9 +13,9 @@ 4 sage: parent(a) Gap - sage: a = 2 * maxima('2'); a # optional - sage.symbolic + sage: a = 2 * maxima('2'); a # needs sage.symbolic 4 - sage: parent(a) # optional - sage.symbolic + sage: parent(a) # needs sage.symbolic Maxima sage: a = 2 * singular('2'); a 4 From 85baf286d318f4d453c2a586e4993118111523fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 22:30:42 -0700 Subject: [PATCH 11/30] sage.interfaces: Update # needs --- src/sage/interfaces/interface.py | 18 ++++++++++-------- src/sage/interfaces/quit.py | 11 ++++++----- src/sage/interfaces/sage0.py | 1 + 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 3774d033e0f..94b8307cea4 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -882,11 +882,12 @@ def _reduce(self): by the doctests because the original identifier was reused. This test makes sure that does not happen again:: - sage: a = r("'abc'") # optional - rpy2 - sage: b = dumps(a) # optional - rpy2 - sage: r.set(a.name(), 0) # make sure that identifier reuse # optional - rpy2 + sage: # optional - rpy2 + sage: a = r("'abc'") + sage: b = dumps(a) + sage: r.set(a.name(), 0) # make sure that identifier reuse ....: # does not accidentally lead to success - sage: loads(b) # optional - rpy2 + sage: loads(b) [1] "abc" """ @@ -1402,13 +1403,14 @@ def name(self, new_name=None): EXAMPLES:: - sage: x = r([1,2,3]); x # optional - rpy2 + sage: # optional - rpy2 + sage: x = r([1,2,3]); x [1] 1 2 3 - sage: x.name() # optional - rpy2 + sage: x.name() 'sage...' - sage: x = r([1,2,3]).name('x'); x # optional - rpy2 + sage: x = r([1,2,3]).name('x'); x [1] 1 2 3 - sage: x.name() # optional - rpy2 + sage: x.name() 'x' :: diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 99e5aa018f3..c10b1414dde 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -140,13 +140,14 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic - sage: a, b # needs sage.libs.pari sage.symbolic + sage: # needs sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) + sage: a, b (2, 3) - sage: sage.interfaces.quit.invalidate_all() # needs sage.libs.pari sage.symbolic - sage: a # needs sage.libs.pari sage.symbolic + sage: sage.interfaces.quit.invalidate_all() + sage: a (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b # needs sage.libs.pari sage.symbolic + sage: b (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 1505d1f2f69..11ece30ac56 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.all r""" Interface to Sage From 1393952b559324cbcb772c1a36b5a31f74e2eda3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:08 -0700 Subject: [PATCH 12/30] src/sage/interfaces: Update file-level doctest tag --- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/gp.py | 3 ++- src/sage/interfaces/interface.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 9c38a8c1cba..a5ba8f09f4e 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic +# sage.doctest: needs sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic """ Common Interface Functionality through Pexpect diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index d1085562828..6e12504e829 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -1,4 +1,5 @@ -# sage.doctest: optional - sage.libs.pari +# sage_setup: distribution = sagemath-pari +# sage.doctest: needs sage.libs.pari r""" Interface to the GP calculator of PARI/GP diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 94b8307cea4..8e89aa65c1e 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic +# sage.doctest: needs sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic r""" Common Interface Functionality From 12e2a4628a52695e28835e8269966b4f05aa024b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:16 -0700 Subject: [PATCH 13/30] src/sage/interfaces: sage -fixdoctests --only-tags --- src/sage/interfaces/axiom.py | 97 +++---- src/sage/interfaces/fricas.py | 137 +++++----- src/sage/interfaces/frobby.py | 85 ++++--- src/sage/interfaces/kash.py | 139 +++++----- src/sage/interfaces/kenzo.py | 396 +++++++++++++++-------------- src/sage/interfaces/lie.py | 80 +++--- src/sage/interfaces/macaulay2.py | 10 +- src/sage/interfaces/magma.py | 298 ++++++++++++---------- src/sage/interfaces/maple.py | 16 ++ src/sage/interfaces/mathematica.py | 88 ++++--- src/sage/interfaces/mathics.py | 160 ++++++------ src/sage/interfaces/matlab.py | 77 +++--- src/sage/interfaces/mupad.py | 80 +++--- src/sage/interfaces/octave.py | 126 ++++----- src/sage/interfaces/polymake.py | 164 ++++++------ src/sage/interfaces/qepcad.py | 70 ++--- src/sage/interfaces/rubik.py | 57 +++-- src/sage/interfaces/scilab.py | 134 +++++----- 18 files changed, 1209 insertions(+), 1005 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index f61fcc638f9..5933e633d38 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -304,12 +304,13 @@ def _commands(self): EXAMPLES:: - sage: cmds = axiom._commands() #optional - axiom - sage: len(cmds) > 100 #optional - axiom + sage: # optional - axiom + sage: cmds = axiom._commands() + sage: len(cmds) > 100 True - sage: '<' in cmds #optional - axiom + sage: '<' in cmds True - sage: 'factor' in cmds #optional - axiom + sage: 'factor' in cmds True """ s = self.eval(")what things") @@ -327,18 +328,19 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: c = axiom._tab_completion(use_disk_cache=False, verbose=False) #optional - axiom - sage: len(c) > 100 #optional - axiom + sage: # optional - axiom + sage: c = axiom._tab_completion(use_disk_cache=False, verbose=False) + sage: len(c) > 100 True - sage: 'factor' in c #optional - axiom + sage: 'factor' in c True - sage: '**' in c #optional - axiom + sage: '**' in c False - sage: 'upperCase?' in c #optional - axiom + sage: 'upperCase?' in c False - sage: 'upperCase_q' in c #optional - axiom + sage: 'upperCase_q' in c True - sage: 'upperCase_e' in c #optional - axiom + sage: 'upperCase_e' in c True """ try: @@ -396,11 +398,12 @@ def get(self, var): EXAMPLES:: - sage: axiom.set('xx', '2') #optional - axiom - sage: axiom.get('xx') #optional - axiom + sage: # optional - axiom + sage: axiom.set('xx', '2') + sage: axiom.get('xx') '2' - sage: a = axiom('(1 + sqrt(2))^5') #optional - axiom - sage: axiom.get(a.name()) #optional - axiom + sage: a = axiom('(1 + sqrt(2))^5') + sage: axiom.get(a.name()) ' +-+\r\r\n 29\\|2 + 41' """ s = self._eval_line(str(var)) @@ -571,26 +574,28 @@ def _richcmp_(self, other, op): """ EXAMPLES:: - sage: two = axiom(2) #optional - axiom - sage: two == 2 #optional - axiom + sage: # optional - axiom + sage: two = axiom(2) + sage: two == 2 True - sage: two == 3 #optional - axiom + sage: two == 3 False - sage: two < 3 #optional - axiom + sage: two < 3 True - sage: two > 1 #optional - axiom + sage: two > 1 True - sage: a = axiom(1); b = axiom(2) #optional - axiom - sage: a == b #optional - axiom + sage: # optional - axiom + sage: a = axiom(1); b = axiom(2) + sage: a == b False - sage: a < b #optional - axiom + sage: a < b True - sage: a > b #optional - axiom + sage: a > b False - sage: b < a #optional - axiom + sage: b < a False - sage: b > a #optional - axiom + sage: b > a True We can also compare more complicated object such as functions:: @@ -649,15 +654,16 @@ def __getitem__(self, n): EXAMPLES:: - sage: v = axiom('[i*x^i for i in 0..5]'); v # optional - axiom + sage: # optional - axiom + sage: v = axiom('[i*x^i for i in 0..5]'); v 2 3 4 5 [0,x,2x ,3x ,4x ,5x ] - sage: v[4] # optional - axiom + sage: v[4] 3 3x - sage: v[1] # optional - axiom + sage: v[1] 0 - sage: v[10] # optional - axiom + sage: v[10] Traceback (most recent call last): ... IndexError: index out of range @@ -677,12 +683,13 @@ def comma(self, *args): EXAMPLES:: - sage: two = axiom(2) #optional - axiom - sage: two.comma(3) #optional - axiom + sage: # optional - axiom + sage: two = axiom(2) + sage: two.comma(3) [2,3] - sage: two.comma(3,4) #optional - axiom + sage: two.comma(3,4) [2,3,4] - sage: _.type() #optional - axiom + sage: _.type() Tuple PositiveInteger """ P = self._check_valid() @@ -810,16 +817,17 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) # optional - axiom # needs sage.symbolic - sage: a.type() # optional - axiom # needs sage.symbolic + sage: # optional - axiom, needs sage.symbolic + sage: a = axiom(x^2 + 1) + sage: a.type() Polynomial Integer - sage: a.sage() # optional - axiom # needs sage.symbolic + sage: a.sage() x^2 + 1 - sage: _.parent() # optional - axiom # needs sage.symbolic + sage: _.parent() Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() # optional - axiom # needs sage.symbolic + sage: axiom('x^2 + y^2 + 1/2').sage() y^2 + x^2 + 1/2 - sage: _.parent() # optional - axiom # needs sage.symbolic + sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field @@ -902,12 +910,13 @@ def __init__(self, object, name): """ TESTS:: - sage: a = axiom('"Hello"') #optional - axiom - sage: a.upperCase_q #optional - axiom + sage: # optional - axiom + sage: a = axiom('"Hello"') + sage: a.upperCase_q upperCase? - sage: a.upperCase_e #optional - axiom + sage: a.upperCase_e upperCase! - sage: a.upperCase_e() #optional - axiom + sage: a.upperCase_e() "HELLO" """ if name.endswith("_q"): diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index c771aea716c..c19feb3a7e5 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -313,13 +313,14 @@ def _start(self): EXAMPLES:: - sage: a = FriCAS() # optional - fricas - sage: a.is_running() # optional - fricas + sage: # optional - fricas + sage: a = FriCAS() + sage: a.is_running() False - sage: a._start() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a._start() + sage: a.is_running() True - sage: a.quit() # optional - fricas + sage: a.quit() """ # setting the prompt properly is necessary for restarting FriCAS self._prompt = FRICAS_FIRST_PROMPT @@ -356,16 +357,17 @@ def _quit_string(self): EXAMPLES:: - sage: fricas._quit_string() # optional - fricas + sage: # optional - fricas + sage: fricas._quit_string() ')quit' - sage: a = FriCAS() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a = FriCAS() + sage: a.is_running() False - sage: a._start() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a._start() + sage: a.is_running() True - sage: a.quit() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a.quit() + sage: a.is_running() False TESTS: @@ -387,12 +389,13 @@ def _commands(self): EXAMPLES:: - sage: cmds = fricas._commands() # optional - fricas - sage: len(cmds) > 100 # optional - fricas + sage: # optional - fricas + sage: cmds = fricas._commands() + sage: len(cmds) > 100 True - sage: '<' in cmds # optional - fricas + sage: '<' in cmds True - sage: 'factor' in cmds # optional - fricas + sage: 'factor' in cmds True """ output = self.eval(")what operations", reformat=False) @@ -408,18 +411,19 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) # optional - fricas - sage: len(c) > 100 # optional - fricas + sage: # optional - fricas + sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) + sage: len(c) > 100 True - sage: 'factor' in c # optional - fricas + sage: 'factor' in c True - sage: '**' in c # optional - fricas + sage: '**' in c False - sage: 'upperCase?' in c # optional - fricas + sage: 'upperCase?' in c False - sage: 'upperCase_q' in c # optional - fricas + sage: 'upperCase_q' in c True - sage: 'upperCase_e' in c # optional - fricas + sage: 'upperCase_e' in c True """ try: @@ -676,15 +680,16 @@ def get(self, var): EXAMPLES:: - sage: fricas.set('xx', '2') # optional - fricas - sage: fricas.get('xx') # optional - fricas + sage: # optional - fricas + sage: fricas.set('xx', '2') + sage: fricas.get('xx') '2' - sage: a = fricas('(1 + sqrt(2))^5') # optional - fricas - sage: fricas.get(a.name()) # optional - fricas + sage: a = fricas('(1 + sqrt(2))^5') + sage: fricas.get(a.name()) ' +-+\n29 \\|2 + 41' - sage: fricas.get('(1 + sqrt(2))^5') # optional - fricas + sage: fricas.get('(1 + sqrt(2))^5') ' +-+\n29 \\|2 + 41' - sage: fricas.new('(1 + sqrt(2))^5') # optional - fricas + sage: fricas.new('(1 + sqrt(2))^5') +-+ 29 \|2 + 41 """ @@ -728,19 +733,20 @@ def get_string(self, var): Check that :trac:`25628` is fixed:: - sage: var("a b"); f = 1/(1+a*cos(x)) # optional - fricas + sage: # optional - fricas + sage: var("a b"); f = 1/(1+a*cos(x)) (a, b) - sage: lF = integrate(f, x, algorithm="fricas") # optional - fricas - sage: (diff(lF[0], x) - f).simplify_trig() # optional - fricas + sage: lF = integrate(f, x, algorithm="fricas") + sage: (diff(lF[0], x) - f).simplify_trig() 0 - sage: (diff(lF[1], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[1], x) - f).simplify_trig() 0 - sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm="fricas"); lF # optional - fricas + sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm="fricas"); lF [1/2*log((2*a*b*x + (b*x^2 - a)*sqrt(-a*b))/(b*x^2 + a))/sqrt(-a*b), arctan(sqrt(a*b)*x/a)/sqrt(a*b)] - sage: (diff(lF[0], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[0], x) - f).simplify_trig() 0 - sage: (diff(lF[1], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[1], x) - f).simplify_trig() 0 """ @@ -1613,13 +1619,14 @@ def _sage_expression(fricas_InputForm): Check conversions of sums and products:: - sage: var("k, m, n") # optional - fricas + sage: # optional - fricas + sage: var("k, m, n") (k, m, n) - sage: fricas("sum(1/factorial(k), k=1..n)").sage() # optional - fricas + sage: fricas("sum(1/factorial(k), k=1..n)").sage() sum(1/factorial(_...), _..., 1, n) - sage: fricas("eval(sum(x/k, k=1..n), x=k)").sage() # optional - fricas + sage: fricas("eval(sum(x/k, k=1..n), x=k)").sage() k*harmonic_number(n) - sage: fricas("product(1/factorial(k), k=1..n)").sage() # optional - fricas + sage: fricas("product(1/factorial(k), k=1..n)").sage() 1/product(factorial(_...), _..., 1, n) sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f # optional - fricas @@ -1772,20 +1779,21 @@ def _sage_(self): Floats:: - sage: fricas(2.1234).sage() # optional - fricas + sage: # optional - fricas + sage: fricas(2.1234).sage() 2.12340000000000 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 53 bits of precision - sage: a = RealField(100)(pi) # optional - fricas - sage: fricas(a).sage() # optional - fricas + sage: a = RealField(100)(pi) + sage: fricas(a).sage() 3.1415926535897932384626433833 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 100 bits of precision - sage: fricas(a).sage() == a # optional - fricas + sage: fricas(a).sage() == a True - sage: fricas(2.0).sage() # optional - fricas + sage: fricas(2.0).sage() 2.00000000000000 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 53 bits of precision Algebraic numbers:: @@ -1810,15 +1818,16 @@ def _sage_(self): We can also convert FriCAS's polynomials to Sage polynomials:: - sage: a = fricas("x^2 + 1"); a.typeOf() # optional - fricas + sage: # optional - fricas + sage: a = fricas("x^2 + 1"); a.typeOf() Polynomial(Integer) - sage: a.sage() # optional - fricas + sage: a.sage() x^2 + 1 - sage: _.parent() # optional - fricas + sage: _.parent() Univariate Polynomial Ring in x over Integer Ring - sage: fricas('x^2 + y^2 + 1/2').sage() # optional - fricas + sage: fricas('x^2 + y^2 + 1/2').sage() y^2 + x^2 + 1/2 - sage: _.parent() # optional - fricas + sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field sage: fricas("1$Polynomial Integer").sage() # optional - fricas @@ -2067,12 +2076,13 @@ def __init__(self, object, name): TESTS:: - sage: a = fricas('"Hello"') # optional - fricas - sage: a.upperCase_q # optional - fricas + sage: # optional - fricas + sage: a = fricas('"Hello"') + sage: a.upperCase_q upperCase? - sage: a.upperCase_e # optional - fricas + sage: a.upperCase_e upperCase! - sage: a.upperCase_e() # optional - fricas + sage: a.upperCase_e() "HELLO" """ @@ -2167,13 +2177,14 @@ def __doctest_cleanup(): """ EXAMPLES:: - sage: from sage.interfaces.fricas import __doctest_cleanup # optional - fricas - sage: a = FriCAS() # optional - fricas - sage: two = a(2) # optional - fricas - sage: a.is_running() # optional - fricas + sage: # optional - fricas + sage: from sage.interfaces.fricas import __doctest_cleanup + sage: a = FriCAS() + sage: two = a(2) + sage: a.is_running() True - sage: __doctest_cleanup() # optional - fricas - sage: a.is_running() # optional - fricas + sage: __doctest_cleanup() + sage: a.is_running() False """ import sage.interfaces.quit diff --git a/src/sage/interfaces/frobby.py b/src/sage/interfaces/frobby.py index aab3bd9b58f..7eb5e53becd 100644 --- a/src/sage/interfaces/frobby.py +++ b/src/sage/interfaces/frobby.py @@ -115,20 +115,22 @@ def alexander_dual(self, monomial_ideal): This is a simple example of computing irreducible decomposition. :: - sage: (a, b, c, d) = QQ['a,b,c,d'].gens() # optional - frobby - sage: id = ideal(a * b, b * c, c * d, d * a) # optional - frobby - sage: alexander_dual = frobby.alexander_dual(id) # optional - frobby - sage: true_alexander_dual = ideal(b * d, a * c) # optional - frobby - sage: alexander_dual == true_alexander_dual # use sets to ignore order # optional - frobby + sage: # optional - frobby + sage: (a, b, c, d) = QQ['a,b,c,d'].gens() + sage: id = ideal(a * b, b * c, c * d, d * a) + sage: alexander_dual = frobby.alexander_dual(id) + sage: true_alexander_dual = ideal(b * d, a * c) + sage: alexander_dual == true_alexander_dual # use sets to ignore order True We see how it is much faster to compute this with frobby than the built-in procedure for simplicial complexes:: - sage: t=simplicial_complexes.PoincareHomologyThreeSphere() # optional - frobby - sage: R=PolynomialRing(QQ,16,'x') # optional - frobby - sage: I=R.ideal([prod([R.gen(i-1) for i in a]) for a in t.facets()]) # optional - frobby - sage: len(frobby.alexander_dual(I).gens()) # optional - frobby + sage: # optional - frobby + sage: t=simplicial_complexes.PoincareHomologyThreeSphere() + sage: R=PolynomialRing(QQ,16,'x') + sage: I=R.ideal([prod([R.gen(i-1) for i in a]) for a in t.facets()]) + sage: len(frobby.alexander_dual(I).gens()) 643 @@ -261,11 +263,12 @@ def irreducible_decomposition(self, monomial_ideal): This is a simple example of computing irreducible decomposition. :: - sage: (x, y, z) = QQ['x,y,z'].gens() # optional - frobby - sage: id = ideal(x ** 2, y ** 2, x * z, y * z) # optional - frobby - sage: decom = frobby.irreducible_decomposition(id) # optional - frobby - sage: true_decom = [ideal(x, y), ideal(x ** 2, y ** 2, z)] # optional - frobby - sage: set(decom) == set(true_decom) # use sets to ignore order # optional - frobby + sage: # optional - frobby + sage: (x, y, z) = QQ['x,y,z'].gens() + sage: id = ideal(x ** 2, y ** 2, x * z, y * z) + sage: decom = frobby.irreducible_decomposition(id) + sage: true_decom = [ideal(x, y), ideal(x ** 2, y ** 2, z)] + sage: set(decom) == set(true_decom) # use sets to ignore order True We now try the special case of the zero ideal in different rings. @@ -273,25 +276,27 @@ def irreducible_decomposition(self, monomial_ideal): We should also try PolynomialRing(QQ, names=[]), but it has a bug which makes that impossible (see :trac:`3028`). :: - sage: rings = [ZZ['x'], CC['x,y']] # optional - frobby - sage: allOK = True # optional - frobby - sage: for ring in rings: # optional - frobby + sage: # optional - frobby + sage: rings = [ZZ['x'], CC['x,y']] + sage: allOK = True + sage: for ring in rings: ....: id0 = ring.ideal(0) ....: decom0 = frobby.irreducible_decomposition(id0) ....: allOK = allOK and decom0 == [id0] - sage: allOK # optional - frobby + sage: allOK True Finally, we try the ideal that is all of the ring in different rings. :: - sage: rings = [ZZ['x'], CC['x,y']] # optional - frobby - sage: allOK = True # optional - frobby - sage: for ring in rings: # optional - frobby + sage: # optional - frobby + sage: rings = [ZZ['x'], CC['x,y']] + sage: allOK = True + sage: for ring in rings: ....: id1 = ring.ideal(1) ....: decom1 = frobby.irreducible_decomposition(id1) ....: allOK = allOK and decom1 == [id1] - sage: allOK # optional - frobby + sage: allOK True """ frobby_input = self._ideal_to_string(monomial_ideal) @@ -316,10 +321,11 @@ def _parse_ideals(self, string, ring): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: string = '2 3\n1 2 3\n0 5 0\n2 3\n1 2 3\n4 5 6' # optional - frobby - sage: frobby._parse_ideals(string, ring) # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: string = '2 3\n1 2 3\n0 5 0\n2 3\n1 2 3\n4 5 6' + sage: frobby._parse_ideals(string, ring) [Ideal (x*y^2*z^3, y^5) of Multivariate Polynomial Ring in x, y, z over Rational Field, Ideal (x*y^2*z^3, x^4*y^5*z^6) of Multivariate Polynomial Ring in x, y, z over Rational Field] @@ -365,10 +371,11 @@ def _parse_4ti2_matrix(self, string): The format is straight-forward, as this example shows. :: - sage: string = '2 3\n1 2 3\n 0 5 0' # optional - frobby - sage: parsed_matrix = frobby._parse_4ti2_matrix(string) # optional - frobby - sage: reference_matrix = [[1, 2, 3], [0, 5, 0]] # optional - frobby - sage: parsed_matrix == reference_matrix # optional - frobby + sage: # optional - frobby + sage: string = '2 3\n1 2 3\n 0 5 0' + sage: parsed_matrix = frobby._parse_4ti2_matrix(string) + sage: reference_matrix = [[1, 2, 3], [0, 5, 0]] + sage: parsed_matrix == reference_matrix True A number of syntax errors lead to exceptions. :: @@ -414,10 +421,11 @@ def _ideal_to_string(self, monomial_ideal): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: id = ring.ideal(x ** 2, x * y * z) # optional - frobby - sage: frobby._ideal_to_string(id) == "2 3\n2 0 0\n1 1 1\n" # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: id = ring.ideal(x ** 2, x * y * z) + sage: frobby._ideal_to_string(id) == "2 3\n2 0 0\n1 1 1\n" True """ # There is no exponent vector that represents zero as a generator, so @@ -447,10 +455,11 @@ def _monomial_to_string(self, monomial): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: monomial = x * x * z # optional - frobby - sage: frobby._monomial_to_string(monomial) == '2 0 1\n' # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: monomial = x * x * z + sage: frobby._monomial_to_string(monomial) == '2 0 1\n' True """ exponents = monomial.exponents() diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index ebfd9178c70..aecddae452b 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -89,11 +89,12 @@ :: - sage: a = kash(12345) # optional -- kash - sage: b = kash(25) # optional -- kash - sage: a/b # optional -- kash + sage: # optional - kash + sage: a = kash(12345) + sage: b = kash(25) + sage: a/b 2469/5 - sage: a**b # optional -- kash + sage: a**b 1937659030411463935651167391656422626577614411586152317674869233464019922771432158872187137603759765625 Variable assignment @@ -130,12 +131,13 @@ :: - sage: F = kash.Factorization(4352) # optional -- kash - sage: F[1] # optional -- kash + sage: # optional - kash + sage: F = kash.Factorization(4352) + sage: F[1] <2, 8> - sage: F[2] # optional -- kash + sage: F[2] <17, 1> - sage: F # optional -- kash + sage: F [ <2, 8>, <17, 1> ], extended by: ext1 := 1, ext2 := Unassign @@ -147,17 +149,18 @@ :: - sage: kash.GCD(15,25) # optional -- kash + sage: # optional - kash + sage: kash.GCD(15,25) 5 - sage: kash.LCM(15,25) # optional -- kash + sage: kash.LCM(15,25) 75 - sage: kash.Div(25,15) # optional -- kash + sage: kash.Div(25,15) 1 - sage: kash(17) % kash(5) # optional -- kash + sage: kash(17) % kash(5) 2 - sage: kash.IsPrime(10007) # optional -- kash + sage: kash.IsPrime(10007) TRUE - sage: kash.IsPrime(2005) # optional -- kash + sage: kash.IsPrime(2005) FALSE sage: kash.NextPrime(10007) # optional -- kash @@ -168,18 +171,19 @@ :: - sage: kash.Precision() # optional -- kash + sage: # optional - kash + sage: kash.Precision() 30 - sage: kash('R') # optional -- kash + sage: kash('R') Real field of precision 30 - sage: kash.Precision(40) # optional -- kash + sage: kash.Precision(40) 40 - sage: kash('R') # optional -- kash + sage: kash('R') Real field of precision 40 - sage: z = kash('1 + 2*I') # optional -- kash - sage: z # optional -- kash + sage: z = kash('1 + 2*I') + sage: z 1.000000000000000000000000000000000000000 + 2.000000000000000000000000000000000000000*I - sage: z*z # optional -- kash + sage: z*z -3.000000000000000000000000000000000000000 + 4.000000000000000000000000000000000000000*I sage: kash.Cos('1.24') # optional -- kash @@ -222,40 +226,42 @@ :: - sage: v = kash([1,2,3]); v # optional -- kash + sage: # optional - kash + sage: v = kash([1,2,3]); v [ 1, 2, 3 ] - sage: v[1] # optional -- kash + sage: v[1] 1 - sage: v[3] # optional -- kash + sage: v[3] 3 - sage: v.Append([5]) # optional -- kash + sage: v.Append([5]) [ 1, 2, 3, 5 ] - sage: v # optional -- kash + sage: v [ 1, 2, 3 ] - sage: v.Append_([5, 6]) # optional -- kash + sage: v.Append_([5, 6]) SUCCESS - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6 ] - sage: v.Add(5) # optional -- kash + sage: v.Add(5) [ 1, 2, 3, 5, 6, 5 ] - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6 ] - sage: v.Add_(5) # optional -- kash + sage: v.Add_(5) SUCCESS - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6, 5 ] The ``Apply`` command applies a function to each element of a list:: - sage: L = kash([1,2,3,4]) # optional -- kash - sage: L.Apply('i -> 3*i') # optional -- kash + sage: # optional - kash + sage: L = kash([1,2,3,4]) + sage: L.Apply('i -> 3*i') [ 3, 6, 9, 12 ] - sage: L # optional -- kash + sage: L [ 1, 2, 3, 4 ] - sage: L.Apply('IsEven') # optional -- kash + sage: L.Apply('IsEven') [ FALSE, TRUE, FALSE, TRUE ] - sage: L # optional -- kash + sage: L [ 1, 2, 3, 4 ] Ranges @@ -265,11 +271,12 @@ :: - sage: L = kash('[1..10]') # optional -- kash - sage: L # optional -- kash + sage: # optional - kash + sage: L = kash('[1..10]') + sage: L [ 1 .. 10 ] - sage: L = kash('[2,4..100]') # optional -- kash - sage: L # optional -- kash + sage: L = kash('[2,4..100]') + sage: L [ 2, 4 .. 100 ] Sequences @@ -283,15 +290,16 @@ :: - sage: f = kash('X^3 + X + 1') # optional -- kash - sage: f + f # optional -- kash + sage: # optional - kash + sage: f = kash('X^3 + X + 1') + sage: f + f 2*X^3 + 2*X + 2 - sage: f * f # optional -- kash + sage: f * f X^6 + 2*X^4 + 2*X^3 + X^2 + 2*X + 1 - sage: f.Evaluate(10) # optional -- kash + sage: f.Evaluate(10) 1011 - sage: Qx = kash.PolynomialAlgebra('Q') # optional -- kash - sage: Qx.gen(1)**5 + kash('7/3') # sage1 below somewhat random; optional -- kash + sage: Qx = kash.PolynomialAlgebra('Q') + sage: Qx.gen(1)**5 + kash('7/3') sage1.1^5 + 7/3 Number Fields @@ -308,12 +316,13 @@ :: - sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash - sage: O = f.EquationOrder() # optional -- kash - sage: a = O.gen(2) # optional -- kash - sage: a # optional -- kash + sage: # optional - kash + sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') + sage: O = f.EquationOrder() + sage: a = O.gen(2) + sage: a [0, 1, 0, 0, 0] - sage: O.Basis() # output somewhat random; optional -- kash + sage: O.Basis() [ _NG.1, _NG.2, @@ -321,9 +330,9 @@ _NG.4, _NG.5 ] - sage: O.Discriminant() # optional -- kash + sage: O.Discriminant() 1364202618880 - sage: O.MaximalOrder() # name sage2 below somewhat random; optional -- kash + sage: O.MaximalOrder() Maximal Order of sage2 sage: O = kash.MaximalOrder('X^3 - 77') # optional -- kash @@ -353,10 +362,11 @@ Computation of class groups and unit groups:: - sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash - sage: O = kash.EquationOrder(f) # optional -- kash - sage: OK = O.MaximalOrder() # optional -- kash - sage: OK.ClassGroup() # name sage32 below random; optional -- kash + sage: # optional - kash + sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') + sage: O = kash.EquationOrder(f) + sage: OK = O.MaximalOrder() + sage: OK.ClassGroup() Abelian Group isomorphic to Z/6 Defined on 1 generator Relations: @@ -381,12 +391,13 @@ :: - sage: k = kash.FiniteField(25) # optional -- kash - sage: kT = k.RationalFunctionField() # optional -- kash - sage: kTy = kT.PolynomialAlgebra() # optional -- kash - sage: T = kT.gen(1) # optional -- kash - sage: y = kTy.gen(1) # optional -- kash - sage: f = y**3 + T**4 + 1 # optional -- kash + sage: # optional - kash + sage: k = kash.FiniteField(25) + sage: kT = k.RationalFunctionField() + sage: kTy = kT.PolynomialAlgebra() + sage: T = kT.gen(1) + sage: y = kTy.gen(1) + sage: f = y**3 + T**4 + 1 Long Input ---------- diff --git a/src/sage/interfaces/kenzo.py b/src/sage/interfaces/kenzo.py index 3607dd7879e..e403b04dab7 100644 --- a/src/sage/interfaces/kenzo.py +++ b/src/sage/interfaces/kenzo.py @@ -193,12 +193,13 @@ def EilenbergMacLaneSpace(G, n): EXAMPLES:: - sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace # optional - kenzo - sage: e3 = EilenbergMacLaneSpace(ZZ, 3) # optional - kenzo - sage: [e3.homology(i) for i in range(8)] # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace + sage: e3 = EilenbergMacLaneSpace(ZZ, 3) + sage: [e3.homology(i) for i in range(8)] [Z, 0, 0, Z, 0, C2, 0, C3] - sage: f3 = EilenbergMacLaneSpace(AdditiveAbelianGroup([2]), 3) # optional - kenzo - sage: [f3.homology(i) for i in range(8)] # optional - kenzo + sage: f3 = EilenbergMacLaneSpace(AdditiveAbelianGroup([2]), 3) + sage: [f3.homology(i) for i in range(8)] [Z, 0, 0, C2, 0, C2, C2, C2] """ if G == ZZ: @@ -230,15 +231,16 @@ def __init__(self, kenzo_object): TESTS:: - sage: from sage.interfaces.kenzo import KenzoObject # optional -kenzo - sage: from sage.interfaces.kenzo import __sphere__ # optional -kenzo - sage: ks = __sphere__(2) # optional -kenzo - sage: ks # optional -kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import KenzoObject + sage: from sage.interfaces.kenzo import __sphere__ + sage: ks = __sphere__(2) + sage: ks - sage: s2 = KenzoObject(ks) # optional -kenzo - sage: s2 # optional -kenzo + sage: s2 = KenzoObject(ks) + sage: s2 [K1 Simplicial-Set] - sage: TestSuite(s2).run(skip='_test_pickling') # optional -kenzo + sage: TestSuite(s2).run(skip='_test_pickling') """ self._kenzo = kenzo_object @@ -280,12 +282,13 @@ def group(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S2 = Sphere(2) # optional - kenzo - sage: EMS = S2.em_spectral_sequence() # optional - kenzo - sage: EMS.group(0, -1, 2) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S2 = Sphere(2) + sage: EMS = S2.em_spectral_sequence() + sage: EMS.group(0, -1, 2) Additive abelian group isomorphic to Z - sage: EMS.group(0, -1, 3) # optional - kenzo + sage: EMS.group(0, -1, 3) Trivial group """ invs = __spectral_sequence_group__(self._kenzo, p, i, j).python() @@ -308,16 +311,17 @@ def matrix(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: L = S3.loop_space() # optional - kenzo - sage: EMS = L.em_spectral_sequence() # optional - kenzo - sage: EMS.table(1, -5, -2, 5, 8) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: L = S3.loop_space() + sage: EMS = L.em_spectral_sequence() + sage: EMS.table(1, -5, -2, 5, 8) 0 Z Z + Z + Z Z + Z + Z 0 0 0 0 0 0 Z Z + Z 0 0 0 0 - sage: EMS.matrix(1, -2 ,8) # optional - kenzo + sage: EMS.matrix(1, -2 ,8) [ 3 -2 0] [ 3 0 -3] [ 0 2 -3] @@ -344,18 +348,19 @@ def differential(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: L = S3.loop_space() # optional - kenzo - sage: EMS = L.em_spectral_sequence() # optional - kenzo - sage: EMS.table(1,-5,-2,5,8) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: L = S3.loop_space() + sage: EMS = L.em_spectral_sequence() + sage: EMS.table(1,-5,-2,5,8) 0 Z Z + Z + Z Z + Z + Z 0 0 0 0 0 0 Z Z + Z 0 0 0 0 - sage: EMS.matrix(1, -3, 8) # optional - kenzo + sage: EMS.matrix(1, -3, 8) [ 2 -2 2] - sage: EMS.differential(1, -3, 8) # optional - kenzo + sage: EMS.differential(1, -3, 8) Morphism from module over Integer Ring with invariants (0, 0, 0) to module with invariants (0,) that sends the generators to [(2), (-2), (2)] """ domain = self.group(p, i, j) @@ -458,13 +463,14 @@ def tensor_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: p = s2.tensor_product(s3) # optional - kenzo - sage: type(p) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: p = s2.tensor_product(s3) + sage: type(p) - sage: [p.homology(i) for i in range(8)] # optional - kenzo + sage: [p.homology(i) for i in range(8)] [Z, 0, Z, Z, 0, Z, 0, 0] """ return KenzoChainComplex(__tnsr_prdc__(self._kenzo, other._kenzo)) @@ -514,11 +520,12 @@ def identity_morphism(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: tp = s2.tensor_product(s2) # optional - kenzo - sage: idnt = tp.identity_morphism() # optional - kenzo - sage: type(idnt) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: tp = s2.tensor_product(s2) + sage: idnt = tp.identity_morphism() + sage: type(idnt) """ return KenzoChainComplexMorphism(__idnt_mrph__(self._kenzo)) @@ -542,20 +549,21 @@ def null_morphism(self, target=None, degree=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp22 = s2.tensor_product(s2) # optional - kenzo - sage: tp22 # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp22 = s2.tensor_product(s2) + sage: tp22 [K... Chain-Complex] - sage: tp23 = s2.tensor_product(s3) # optional - kenzo - sage: tp23 # optional - kenzo + sage: tp23 = s2.tensor_product(s3) + sage: tp23 [K... Chain-Complex] - sage: null1 = tp22.null_morphism() # optional - kenzo - sage: null1 # optional - kenzo + sage: null1 = tp22.null_morphism() + sage: null1 [K... Morphism (degree 0): K... -> K...] - sage: null2 = tp22.null_morphism(target = tp23, degree = -3) # optional - kenzo - sage: null2 # optional - kenzo + sage: null2 = tp22.null_morphism(target = tp23, degree = -3) + sage: null2 [K... Morphism (degree -3): K... -> K...] """ if target is None: @@ -634,13 +642,14 @@ def orgn(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: l2 = s2.loop_space() # optional - kenzo - sage: l2.orgn() # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: l2 = s2.loop_space() + sage: l2.orgn() '(LOOP-SPACE [K... Simplicial-Set])' - sage: A = l2.cartesian_product(s2) # optional - kenzo - sage: A.orgn() # optional - kenzo + sage: A = l2.cartesian_product(s2) + sage: A.orgn() '(CRTS-PRDC [K... Simplicial-Group] [K... Simplicial-Set])' """ return str(__orgn_aux1__(self._kenzo)) @@ -669,13 +678,14 @@ def loop_space(self, n=1): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: l2 = s2.loop_space() # optional - kenzo - sage: type(l2) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: l2 = s2.loop_space() + sage: type(l2) - sage: l2 = s2.loop_space() # optional - kenzo - sage: [l2.homology(i) for i in range(8)] # optional - kenzo + sage: l2 = s2.loop_space() + sage: [l2.homology(i) for i in range(8)] [Z, Z, Z, Z, Z, Z, Z, Z] """ return KenzoSimplicialGroup(__loop_space__(self._kenzo, n)) @@ -694,13 +704,14 @@ def cartesian_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: p = s2.cartesian_product(s3) # optional - kenzo - sage: type(p) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: p = s2.cartesian_product(s3) + sage: type(p) - sage: [p.homology(i) for i in range(6)] # optional - kenzo + sage: [p.homology(i) for i in range(6)] [Z, 0, Z, Z, 0, Z] """ prod_kenzo = __crts_prdc__(self._kenzo, other._kenzo) @@ -716,12 +727,13 @@ def suspension(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace # optional - kenzo - sage: e3 = EilenbergMacLaneSpace(ZZ, 3) # optional - kenzo - sage: s = e3.suspension() # optional - kenzo - sage: type(s) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace + sage: e3 = EilenbergMacLaneSpace(ZZ, 3) + sage: s = e3.suspension() + sage: type(s) - sage: [s.homology(i) for i in range(6)] # optional - kenzo + sage: [s.homology(i) for i in range(6)] [Z, 0, 0, 0, Z, 0] """ return KenzoSimplicialSet(__suspension__(self._kenzo)) @@ -799,11 +811,12 @@ def sw_spectral_sequence(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: E = S3.sw_spectral_sequence() # optional - kenzo - sage: T = E.table(0, 0, 4, 0, 4) # optional - kenzo - sage: T # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: E = S3.sw_spectral_sequence() + sage: T = E.table(0, 0, 4, 0, 4) + sage: T Z 0 0 Z 0 0 0 0 0 0 Z 0 0 Z 0 @@ -827,12 +840,13 @@ def serre_spectral_sequence(self): EXAMPLES:: + sage: # optional - kenzo sage: from sage.interfaces.kenzo import Sphere - sage: S2 = Sphere(2) # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: P = S2.cartesian_product(S3) # optional - kenzo - sage: E = P.serre_spectral_sequence() # optional - kenzo - sage: E.table(0, 0, 2, 0, 3) # optional - kenzo + sage: S2 = Sphere(2) + sage: S3 = Sphere(3) + sage: P = S2.cartesian_product(S3) + sage: E = P.serre_spectral_sequence() + sage: E.table(0, 0, 2, 0, 3) Z 0 Z 0 0 0 0 0 0 @@ -862,13 +876,14 @@ def wedge(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: w = s2.wedge(s3) # optional - kenzo - sage: type(w) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: w = s2.wedge(s3) + sage: type(w) - sage: [w.homology(i) for i in range(6)] # optional - kenzo + sage: [w.homology(i) for i in range(6)] [Z, 0, Z, Z, 0, 0] """ wedge_kenzo = __wedge__(self._kenzo, other._kenzo) @@ -888,13 +903,14 @@ def join(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: j = s2.join(s3) # optional - kenzo - sage: type(j) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: j = s2.join(s3) + sage: type(j) - sage: [j.homology(i) for i in range(6)] # optional - kenzo + sage: [j.homology(i) for i in range(6)] [Z, 0, 0, 0, 0, 0] """ join_kenzo = __join__(self._kenzo, other._kenzo) @@ -914,13 +930,14 @@ def smash_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: s = s2.smash_product(s3) # optional - kenzo - sage: type(s) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: s = s2.smash_product(s3) + sage: type(s) - sage: [s.homology(i) for i in range(6)] # optional - kenzo + sage: [s.homology(i) for i in range(6)] [Z, 0, 0, 0, 0, Z] """ smash_kenzo = __smash_product__(self._kenzo, other._kenzo) @@ -942,13 +959,14 @@ def classifying_space(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import MooreSpace # optional - kenzo - sage: m2 = MooreSpace(2,4) # optional - kenzo - sage: l2 = m2.loop_space() # optional - kenzo - sage: c = l2.classifying_space() # optional - kenzo - sage: type(c) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import MooreSpace + sage: m2 = MooreSpace(2,4) + sage: l2 = m2.loop_space() + sage: c = l2.classifying_space() + sage: type(c) - sage: [c.homology(i) for i in range(8)] # optional - kenzo + sage: [c.homology(i) for i in range(8)] [Z, 0, 0, 0, C2, 0, 0, 0] """ return KenzoSimplicialGroup(__classifying_space__(self._kenzo)) @@ -1118,14 +1136,15 @@ def SChainComplex(kchaincomplex, start=0, end=15): :: - sage: from sage.interfaces.kenzo import SChainComplex, Sphere # optional - kenzo - sage: S4 = Sphere(4) # optional - kenzo - sage: C = SChainComplex(S4) # optional - kenzo - sage: C # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import SChainComplex, Sphere + sage: S4 = Sphere(4) + sage: C = SChainComplex(S4) + sage: C Chain complex with at most 3 nonzero terms over Integer Ring - sage: C._ascii_art_() # optional - kenzo + sage: C._ascii_art_() 0 <-- C_4 <-- 0 ... 0 <-- C_0 <-- 0 - sage: [C.homology(i) for i in range(6)] # optional - kenzo + sage: [C.homology(i) for i in range(6)] [Z, 0, 0, 0, Z, 0] """ matrices = {} @@ -1156,17 +1175,18 @@ def SAbstractSimplex(simplex, dim): EXAMPLES:: + sage: # optional - kenzo sage: from sage.libs.ecl import EclObject, ecl_eval - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: KenzoObject, SAbstractSimplex) - sage: KAbSm = KenzoObject(ecl_eval("(ABSM 15 'K)")) # optional - kenzo - sage: SAbSm1 = SAbstractSimplex(KAbSm, 2) # optional - kenzo - sage: SAbSm2 = SAbstractSimplex(KAbSm, 7) # optional - kenzo - sage: SAbSm1.degeneracies() # optional - kenzo + sage: KAbSm = KenzoObject(ecl_eval("(ABSM 15 'K)")) + sage: SAbSm1 = SAbstractSimplex(KAbSm, 2) + sage: SAbSm2 = SAbstractSimplex(KAbSm, 7) + sage: SAbSm1.degeneracies() [3, 2, 1, 0] - sage: SAbSm1.dimension() # optional - kenzo + sage: SAbSm1.dimension() 6 - sage: SAbSm2.dimension() # optional - kenzo + sage: SAbSm2.dimension() 11 """ degeneracies = __dgop_int_ext__(__dgop__(simplex._kenzo)).python() @@ -1192,15 +1212,16 @@ def KAbstractSimplex(simplex): EXAMPLES:: + sage: # optional - kenzo sage: from sage.topology.simplicial_set import AbstractSimplex - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: KAbstractSimplex, SAbstractSimplex) - sage: SAbSm = AbstractSimplex(1, (2,0,3,2,1), name = 'SAbSm') # optional - kenzo - sage: KAbSm = KAbstractSimplex(SAbSm) # optional - kenzo - sage: SAbSm2 = SAbstractSimplex(KAbSm, 1) # optional - kenzo - sage: SAbSm.degeneracies() == SAbSm2.degeneracies() # optional - kenzo + sage: SAbSm = AbstractSimplex(1, (2,0,3,2,1), name = 'SAbSm') + sage: KAbSm = KAbstractSimplex(SAbSm) + sage: SAbSm2 = SAbstractSimplex(KAbSm, 1) + sage: SAbSm.degeneracies() == SAbSm2.degeneracies() True - sage: SAbSm.dimension() == SAbSm2.dimension() # optional - kenzo + sage: SAbSm.dimension() == SAbSm2.dimension() True """ return KenzoObject(__kabstractsimplex_aux1__(simplex.degeneracies(), @@ -1289,30 +1310,31 @@ def SFiniteSimplicialSet(ksimpset, limit): EXAMPLES:: + sage: # optional - kenzo sage: from sage.topology.simplicial_set import SimplicialSet - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: AbstractSimplex, KFiniteSimplicialSet, ....: SFiniteSimplicialSet, Sphere) - sage: s0 = AbstractSimplex(0, name='s0') # optional - kenzo - sage: s1 = AbstractSimplex(0, name='s1') # optional - kenzo - sage: s2 = AbstractSimplex(0, name='s2') # optional - kenzo - sage: s01 = AbstractSimplex(1, name='s01') # optional - kenzo - sage: s02 = AbstractSimplex(1, name='s02') # optional - kenzo - sage: s12 = AbstractSimplex(1, name='s12') # optional - kenzo - sage: s012 = AbstractSimplex(2, name='s012') # optional - kenzo - sage: Triangle = SimplicialSet({s01: (s1, s0), # optional - kenzo + sage: s0 = AbstractSimplex(0, name='s0') + sage: s1 = AbstractSimplex(0, name='s1') + sage: s2 = AbstractSimplex(0, name='s2') + sage: s01 = AbstractSimplex(1, name='s01') + sage: s02 = AbstractSimplex(1, name='s02') + sage: s12 = AbstractSimplex(1, name='s12') + sage: s012 = AbstractSimplex(2, name='s012') + sage: Triangle = SimplicialSet({s01: (s1, s0), ....: s02: (s2, s0), ....: s12: (s2, s1)}, ....: base_point = s0) - sage: KTriangle = KFiniteSimplicialSet(Triangle) # optional - kenzo - sage: STriangle = SFiniteSimplicialSet(KTriangle, 1) # optional - kenzo - sage: STriangle.homology() # optional - kenzo + sage: KTriangle = KFiniteSimplicialSet(Triangle) + sage: STriangle = SFiniteSimplicialSet(KTriangle, 1) + sage: STriangle.homology() {0: 0, 1: Z} - sage: S1 = simplicial_sets.Sphere(1) # optional - kenzo - sage: S3 = simplicial_sets.Sphere(3) # optional - kenzo - sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3)) # optional - kenzo - sage: SS1vS3 = SFiniteSimplicialSet(KS1vS3, 3) # optional - kenzo - sage: SS1vS3.homology() # optional - kenzo + sage: S1 = simplicial_sets.Sphere(1) + sage: S3 = simplicial_sets.Sphere(3) + sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3)) + sage: SS1vS3 = SFiniteSimplicialSet(KS1vS3, 3) + sage: SS1vS3.homology() {0: 0, 1: Z, 2: 0, 3: Z} """ list_orgn = __orgn_aux1__(ksimpset._kenzo).python() @@ -1587,18 +1609,19 @@ def composite(self, object=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp22 = s2.tensor_product(s2) # optional - kenzo - sage: tp23 = s2.tensor_product(s3) # optional - kenzo - sage: idnt = tp22.identity_morphism() # optional - kenzo - sage: idnt # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp22 = s2.tensor_product(s2) + sage: tp23 = s2.tensor_product(s3) + sage: idnt = tp22.identity_morphism() + sage: idnt [K... Morphism (degree 0): K... -> K...] - sage: null = tp23.null_morphism(target = tp22, degree = 4) # optional - kenzo - sage: null # optional - kenzo + sage: null = tp23.null_morphism(target = tp22, degree = 4) + sage: null [K... Morphism (degree 4): K... -> K...] - sage: idnt.composite((tp22, null)) # optional - kenzo + sage: idnt.composite((tp22, null)) [K... Morphism (degree 3): K... -> K...] """ if object is None: @@ -1765,25 +1788,26 @@ def change_source_target_complex(self, source=None, target=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: ZCC # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: ZCC [K... Chain-Complex] - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp = s2.tensor_product(s3) # optional - kenzo - sage: tp # optional - kenzo + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp = s2.tensor_product(s3) + sage: tp [K... Filtered-Chain-Complex] - sage: null = ZCC.null_morphism(tp) # optional - kenzo - sage: null # optional - kenzo + sage: null = ZCC.null_morphism(tp) + sage: null [K... Morphism (degree 0): K... -> K...] - sage: null.source_complex() # optional - kenzo + sage: null.source_complex() [K... Chain-Complex] - sage: null2 = null.change_source_target_complex(source = tp) # optional - kenzo - sage: null2 # optional - kenzo + sage: null2 = null.change_source_target_complex(source = tp) + sage: null2 [K... Morphism (degree 0): K... -> K...] - sage: null2.source_complex() # optional - kenzo + sage: null2.source_complex() [K... Filtered-Chain-Complex] """ source = source or self.source_complex() @@ -1810,24 +1834,25 @@ def destructive_change_source_target_complex(self, source=None, target=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: ZCC # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: ZCC [K... Chain-Complex] - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp = s2.tensor_product(s3) # optional - kenzo - sage: tp # optional - kenzo + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp = s2.tensor_product(s3) + sage: tp [K... Filtered-Chain-Complex] - sage: null = ZCC.null_morphism(tp) # optional - kenzo - sage: null # optional - kenzo + sage: null = ZCC.null_morphism(tp) + sage: null [K... Morphism (degree 0): K... -> K...] - sage: null.target_complex() # optional - kenzo + sage: null.target_complex() [K... Filtered-Chain-Complex] - sage: null.destructive_change_source_target_complex(target = ZCC) # optional - kenzo + sage: null.destructive_change_source_target_complex(target = ZCC) [K... Cohomology-Class on K... of degree 0] - sage: null.target_complex() # optional - kenzo + sage: null.target_complex() [K... Chain-Complex] """ source = source or self.source_complex() @@ -1864,19 +1889,20 @@ def build_morphism(source_complex, target_complex, degree, algorithm, strategy, EXAMPLES:: + sage: # optional - kenzo sage: from sage.interfaces.kenzo import (KenzoChainComplex, ....: build_morphism) sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: A = build_morphism( # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: A = build_morphism( ....: ZCC, ZCC, -1, ....: ecl_eval("#'(lambda (comb) (cmbn (1- (degr comb))))"), ....: "cmbn", ["zero morphism on ZCC"]) - sage: A.target_complex() # optional - kenzo + sage: A.target_complex() [K... Chain-Complex] - sage: A.degree() # optional - kenzo + sage: A.degree() -1 - sage: type(A) # optional - kenzo + sage: type(A) """ return KenzoChainComplexMorphism( diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index 84aee7d7259..2866dfbb828 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -53,36 +53,38 @@ You can perform basic arithmetic operations in LiE. :: - sage: lie.eval('19+68') # optional - lie + sage: # optional - lie + sage: lie.eval('19+68') '87' - sage: a = lie('1111111111*1111111111') # optional - lie - sage: a # optional - lie + sage: a = lie('1111111111*1111111111') + sage: a 1234567900987654321 - sage: a/1111111111 # optional - lie + sage: a/1111111111 1111111111 - sage: a = lie('345') # optional - lie - sage: a^2+3*a-5 # optional - lie + sage: a = lie('345') + sage: a^2+3*a-5 120055 - sage: _ / 7*a # optional - lie + sage: _ / 7*a 5916750 Vectors in LiE are created using square brackets. Notice that the indexing in LiE is 1-based, unlike Python/Sage which is 0-based. :: - sage: v = lie('[3,2,6873,-38]') # optional - lie - sage: v # optional - lie + sage: # optional - lie + sage: v = lie('[3,2,6873,-38]') + sage: v [3,2,6873,-38] - sage: v[3] # optional - lie + sage: v[3] 6873 - sage: v+v # optional - lie + sage: v+v [6,4,13746,-76] - sage: v*v # optional - lie + sage: v*v 47239586 - sage: v+234786 # optional - lie + sage: v+234786 [3,2,6873,-38,234786] - sage: v-3 # optional - lie + sage: v-3 [3,2,-38] - sage: v^v # optional - lie + sage: v^v [3,2,6873,-38,3,2,6873,-38] You can also work with matrices in LiE. :: @@ -101,19 +103,20 @@ ,[3, 7, 0, 9] ] - sage: m^3 # optional - lie + sage: # optional - lie + sage: m^3 [[ 220, 87, 81, 375] ,[-168,-1089, 13,1013] ,[1550, 357,-55,1593] ,[-854, -652, 98,-170] ] - sage: v*m # optional - lie + sage: v*m [-6960,62055,55061,-319] - sage: m*v # optional - lie + sage: m*v [20508,-27714,54999,-14089] - sage: v*m*v # optional - lie + sage: v*m*v 378549605 - sage: m+v # optional - lie + sage: m+v [[ 1, 0, 3, 3] ,[12, 4, -4, 7] ,[-1, 9, 8, 0] @@ -130,17 +133,18 @@ LiE handles multivariate (Laurent) polynomials. :: - sage: lie('X[1,2]') # optional - lie + sage: # optional - lie + sage: lie('X[1,2]') 1X[1,2] - sage: -3*_ # optional - lie + sage: -3*_ -3X[1,2] - sage: _ + lie('4X[-1,4]') # optional - lie + sage: _ + lie('4X[-1,4]') 4X[-1,4] - 3X[ 1,2] - sage: _^2 # optional - lie + sage: _^2 16X[-2,8] - 24X[ 0,6] + 9X[ 2,4] - sage: lie('(4X[-1,4]-3X[1,2])*(X[2,0]-X[0,-4])') # optional - lie + sage: lie('(4X[-1,4]-3X[1,2])*(X[2,0]-X[0,-4])') -4X[-1, 0] + 3X[ 1,-2] + 4X[ 1, 4] - 3X[ 3, 2] - sage: _ - _ # optional - lie + sage: _ - _ 0X[0,0] @@ -172,15 +176,16 @@ a function (say f), you can call it using lie.f ; however, user-defined functions do not show up when using tab-completion. :: - sage: lie.eval('f(int x) = 2*x') # optional - lie + sage: # optional - lie + sage: lie.eval('f(int x) = 2*x') '' - sage: lie.f(984) # optional - lie + sage: lie.f(984) 1968 - sage: lie.eval('f(int n) = a=3*n-7; if a < 0 then a = -a fi; 7^a+a^3-4*a-57') # optional - lie + sage: lie.eval('f(int n) = a=3*n-7; if a < 0 then a = -a fi; 7^a+a^3-4*a-57') '' - sage: lie.f(2) # optional - lie + sage: lie.f(2) -53 - sage: lie.f(5) # optional - lie + sage: lie.f(5) 5765224 @@ -250,7 +255,8 @@ which evaluates a polynomial at a point. Below is a (roughly) direct translation of that program into Python / Sage. :: - sage: def eval_pol(p, pt): # optional - lie + sage: # optional - lie + sage: def eval_pol(p, pt): ....: s = 0 ....: for i in range(1,p.length().sage()+1): ....: m = 1 @@ -258,12 +264,12 @@ ....: m *= pt[j]^p.expon(i)[j] ....: s += p.coef(i)*m ....: return s - sage: a = lie('X[1,2]') # optional - lie - sage: b1 = lie('[1,2]') # optional - lie - sage: b2 = lie('[2,3]') # optional - lie - sage: eval_pol(a, b1) # optional - lie + sage: a = lie('X[1,2]') + sage: b1 = lie('[1,2]') + sage: b2 = lie('[2,3]') + sage: eval_pol(a, b1) 4 - sage: eval_pol(a, b2) # optional - lie + sage: eval_pol(a, b2) 18 diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 4ed5ab46542..e8a4d94d2dc 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -496,7 +496,11 @@ def _contains(self, v1, v2): sage: 0 in a, 2 in a, 3 in a (True, True, False) sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') +<<<<<<< HEAD sage: 'x' in b, '"x"' in b # indirect doctest +======= + sage: 'x' in b, '"x"' in b +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) (False, True) """ return self.eval("%s#?%s" % (v2, v1)) == self._true_symbol() @@ -645,7 +649,11 @@ def cputime(self, t=None): sage: R = macaulay2("QQ[x,y]") sage: x,y = R.gens() sage: a = (x+y+1)^20 +<<<<<<< HEAD sage: macaulay2.cputime() # random +======= + sage: macaulay2.cputime() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.48393700000000001 """ _t = float(self.cpuTime()._sage_()) @@ -958,7 +966,7 @@ def _repr_(self): Sequence sage: str(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) - sage: macaulay2.options.after_print = False # optional - macaulay2 + sage: macaulay2.options.after_print = False """ from sage.typeset.ascii_art import empty_ascii_art P = self.parent() diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 529bfbc349b..7d66375f25f 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -47,23 +47,25 @@ how many you get using the ``nvals`` named parameter to a function call:: - sage: n = magma(100) # optional - magma - sage: n.IsSquare(nvals = 1) # optional - magma + sage: # optional - magma + sage: n = magma(100) + sage: n.IsSquare(nvals = 1) true - sage: n.IsSquare(nvals = 2) # optional - magma + sage: n.IsSquare(nvals = 2) (true, 10) - sage: n = magma(-2006) # optional - magma - sage: n.Factorization() # optional - magma + sage: n = magma(-2006) + sage: n.Factorization() [ <2, 1>, <17, 1>, <59, 1> ] - sage: n.Factorization(nvals=2) # optional - magma + sage: n.Factorization(nvals=2) ([ <2, 1>, <17, 1>, <59, 1> ], -1) We verify that an obviously principal ideal is principal:: - sage: _ = magma.eval('R := PolynomialRing(RationalField())') # optional - magma - sage: O = magma.NumberField('x^2+23').MaximalOrder() # optional - magma - sage: I = magma('ideal<%s|%s.1>'%(O.name(),O.name())) # optional - magma - sage: I.IsPrincipal(nvals=2) # optional - magma + sage: # optional - magma + sage: _ = magma.eval('R := PolynomialRing(RationalField())') + sage: O = magma.NumberField('x^2+23').MaximalOrder() + sage: I = magma('ideal<%s|%s.1>'%(O.name(),O.name())) + sage: I.IsPrincipal(nvals=2) (true, [1, 0]) Long Input @@ -142,14 +144,15 @@ structure S is denoted by S(x). This also works for the Magma interface:: - sage: G = magma.DirichletGroup(20) # optional - magma - sage: G.AssignNames(['a', 'b']) # optional - magma - sage: (G.1).Modulus() # optional - magma + sage: # optional - magma + sage: G = magma.DirichletGroup(20) + sage: G.AssignNames(['a', 'b']) + sage: (G.1).Modulus() 20 - sage: e = magma.DirichletGroup(40)(G.1) # optional - magma - sage: print(e) # optional - magma + sage: e = magma.DirichletGroup(40)(G.1) + sage: print(e) Kronecker character -4 in modulus 40 - sage: print(e.Modulus()) # optional - magma + sage: print(e.Modulus()) 40 We coerce some polynomial rings into Magma:: @@ -713,13 +716,14 @@ def __call__(self, x, gens=None): EXAMPLES:: - sage: magma(EllipticCurve('37a')) # optional - magma + sage: # optional - magma + sage: magma(EllipticCurve('37a')) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - sage: magma('EllipticCurve([GF(5)|1,2,3,4,1])') # optional - magma + sage: magma('EllipticCurve([GF(5)|1,2,3,4,1])') Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 1 over GF(5) - sage: magma('PowerSeriesRing(Rationals())', 't') # optional - magma + sage: magma('PowerSeriesRing(Rationals())', 't') Power series ring in t over Rational Field - sage: magma('PolynomialRing(RationalField(), 3)', 'x,y,z') # optional - magma + sage: magma('PolynomialRing(RationalField(), 3)', 'x,y,z') Polynomial ring of rank 3 over Rational Field Order: Lexicographical Variables: x, y, z @@ -736,25 +740,27 @@ def __call__(self, x, gens=None): We test caching:: - sage: R. = ZZ[] # optional - magma - sage: magma(R) is magma(R) # optional - magma + sage: # optional - magma + sage: R. = ZZ[] + sage: magma(R) is magma(R) True - sage: m = Magma() # optional - magma - sage: m(R) # optional - magma + sage: m = Magma() + sage: m(R) Univariate Polynomial Ring in x over Integer Ring - sage: m(R) is magma(R) # optional - magma + sage: m(R) is magma(R) False - sage: R._magma_cache # optional - magma + sage: R._magma_cache {Magma: Univariate Polynomial Ring in x over Integer Ring, Magma: Univariate Polynomial Ring in x over Integer Ring} - sage: P. = PolynomialRing(GF(127)) # optional - magma - sage: m = Magma() # optional - magma - sage: m(P) # optional - magma + sage: # optional - magma + sage: P. = PolynomialRing(GF(127)) + sage: m = Magma() + sage: m(P) Polynomial ring of rank 2 over GF(127) Order: Graded Reverse Lexicographical Variables: x, y - sage: P._magma_cache # optional - magma + sage: P._magma_cache {Magma: Polynomial ring of rank 2 over GF(127) Order: Graded Reverse Lexicographical Variables: x, y} @@ -891,16 +897,17 @@ def clear(self, var): :: - sage: magma = Magma() # optional - magma - sage: a = magma('100') # optional - magma - sage: a.name() # optional - magma + sage: # optional - magma + sage: magma = Magma() + sage: a = magma('100') + sage: a.name() '_sage_[1]' - sage: del a # optional - magma - sage: b = magma('257') # optional - magma - sage: b.name() # optional - magma + sage: del a + sage: b = magma('257') + sage: b.name() '_sage_[1]' - sage: del b # optional - magma - sage: magma('_sage_[1]') # optional - magma + sage: del b + sage: magma('_sage_[1]') 0 """ self.__available_var.insert(0, var) # adds var to front of list @@ -931,12 +938,13 @@ def cputime(self, t=None): EXAMPLES:: - sage: type(magma.cputime()) # optional - magma + sage: # optional - magma + sage: type(magma.cputime()) <... 'float'> - sage: magma.cputime() # random, optional - magma + sage: magma.cputime() 1.9399999999999999 - sage: t = magma.cputime() # optional - magma - sage: magma.cputime(t) # random, optional - magma + sage: t = magma.cputime() + sage: magma.cputime(t) 0.02 """ if t: @@ -1251,15 +1259,16 @@ def bar_call(self, left, name, gens, nvals=1): methods of Magma elements. Here we illustrate directly using bar_call to create quotients:: - sage: V = magma.RModule(ZZ,3) # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma.RModule(ZZ,3) + sage: V RModule(IntegerRing(), 3) - sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=1) # optional - magma + sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=1) RModule(IntegerRing(), 2) - sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=2) # optional - magma + sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=2) (RModule(IntegerRing(), 2), Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 2)) - sage: magma.bar_call(V, 'quo', V, nvals=2) # optional - magma + sage: magma.bar_call(V, 'quo', V, nvals=2) (RModule(IntegerRing(), 0), Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 0)) """ @@ -1644,11 +1653,12 @@ def __call__(self, *args, **kwds): EXAMPLES: We create a MagmaFunctionElement:: - sage: n = magma(-15) # optional - magma - sage: f = n.Factorisation # optional - magma - sage: type(f) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: f = n.Factorisation + sage: type(f) - sage: f() # optional - magma + sage: f() [ <3, 1>, <5, 1> ] We verify that the nvals argument works. @@ -1686,12 +1696,13 @@ def _instancedoc_(self): EXAMPLES:: - sage: n = magma(-15) # optional - magma - sage: f = n.Factorisation # optional - magma - sage: print(f.__doc__) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: f = n.Factorisation + sage: print(f.__doc__) (n::RngIntElt) -> RngIntEltFact, RngIntElt, SeqEnum ... - sage: print(n.Factorisation.__doc__) # optional - magma + sage: print(n.Factorisation.__doc__) (n::RngIntElt) -> RngIntEltFact, RngIntElt, SeqEnum ... """ @@ -1728,13 +1739,14 @@ def _repr_(self): :: - sage: V = magma('VectorSpace(RationalField(),2)') # optional - magma - sage: V.set_magma_attribute('M', 290398) # optional - magma - sage: V.M # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(RationalField(),2)') + sage: V.set_magma_attribute('M', 290398) + sage: V.M 290398 - sage: type(V.M) # optional - magma + sage: type(V.M) - sage: type(V.M.__repr__()) # optional - magma + sage: type(V.M.__repr__()) <... 'str'> Displaying a non-attribute function works as above. @@ -1898,13 +1910,14 @@ def __getattr__(self, attrname): EXAMPLES:: - sage: n = magma(-15) # optional - magma - sage: type(n) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: type(n) - sage: f = n.__getattr__('Factorization') # optional - magma - sage: type(f) # optional - magma + sage: f = n.__getattr__('Factorization') + sage: type(f) - sage: f # optional - magma + sage: f Partially evaluated Magma function or intrinsic 'Factorization' ... """ @@ -1921,24 +1934,25 @@ def _sage_(self): EXAMPLES: Enumerated Sets:: - sage: a = magma('{1,2/3,-5/9}') # optional - magma - sage: a.sage() # optional - magma + sage: # optional - magma + sage: a = magma('{1,2/3,-5/9}') + sage: a.sage() {1, -5/9, 2/3} - sage: a._sage_() # optional - magma + sage: a._sage_() {1, -5/9, 2/3} - sage: type(a.sage()) # optional - magma + sage: type(a.sage()) - sage: a = magma('{1,2/3,-5/9}'); a # optional - magma + sage: a = magma('{1,2/3,-5/9}'); a { -5/9, 2/3, 1 } - sage: a.Type() # optional - magma + sage: a.Type() SetEnum - sage: b = a.sage(); b # optional - magma + sage: b = a.sage(); b {1, -5/9, 2/3} - sage: type(b) # optional - magma + sage: type(b) - sage: c = magma(b); c # optional - magma + sage: c = magma(b); c { -5/9, 2/3, 1 } - sage: c.Type() # optional - magma + sage: c.Type() SetEnum Multisets are converted to lists:: @@ -1986,20 +2000,22 @@ def _sage_(self): Multivariate polynomials:: - sage: R. = QQ[] # optional - magma - sage: f = x^2+3*y # optional - magma - sage: g = magma(f).sage(); g # optional - magma + sage: # optional - magma + sage: R. = QQ[] + sage: f = x^2+3*y + sage: g = magma(f).sage(); g x^2 + 3*y - sage: parent(f) == parent(g) # optional - magma + sage: parent(f) == parent(g) True Real and complex numbers:: - sage: m = magma(RealField(200)(1/3)) # optional - magma - sage: m.sage() # indirect doctest, optional - magma + sage: # optional - magma + sage: m = magma(RealField(200)(1/3)) + sage: m.sage() 0.33333333333333333333333333333333333333333333333333333333333 - sage: m = magma(RealField(1000)(1/3)) # optional - magma - sage: m.sage() # indirect doctest, optional - magma + sage: m = magma(RealField(1000)(1/3)) + sage: m.sage() 0.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 sage: m = magma(ComplexField(200)).1; m # optional - magma @@ -2041,14 +2057,15 @@ def _sage_(self): to relative number fields. Conversion of their elements has not yet been implemented.:: - sage: magma.eval('P := PolynomialRing(Rationals());') # optional - magma + sage: # optional - magma + sage: magma.eval('P := PolynomialRing(Rationals());') '' - sage: K = magma('NumberField([x^2-2,x^2-3]:Abs);') # optional - magma - sage: L = K.sage(); L # optional - magma + sage: K = magma('NumberField([x^2-2,x^2-3]:Abs);') + sage: L = K.sage(); L Number Field in K1 with defining polynomial x^2 - 2 over its base field - sage: L.base_field() # optional - magma + sage: L.base_field() Number Field in K2 with defining polynomial x^2 - 3 - sage: K.GeneratorsSequence()[1].sage() # optional - magma + sage: K.GeneratorsSequence()[1].sage() Traceback (most recent call last): ... NameError: name 'K' is not defined @@ -2083,11 +2100,12 @@ def AssignNames(self, names): """ EXAMPLES:: - sage: S = magma.PolynomialRing(magma.Integers(), 2) # optional - magma - sage: S.AssignNames(['a', 'b']) # optional - magma - sage: S.1 # optional - magma + sage: # optional - magma + sage: S = magma.PolynomialRing(magma.Integers(), 2) + sage: S.AssignNames(['a', 'b']) + sage: S.1 a - sage: S.1^2 + S.2 # optional - magma + sage: S.1^2 + S.2 a^2 + b """ P = self._check_valid() @@ -2214,13 +2232,14 @@ def evaluate(self, *args): EXAMPLES:: - sage: f = magma('Factorization') # optional - magma - sage: f.evaluate(15) # optional - magma + sage: # optional - magma + sage: f = magma('Factorization') + sage: f.evaluate(15) [ <3, 1>, <5, 1> ] - sage: f(15) # optional - magma + sage: f(15) [ <3, 1>, <5, 1> ] - sage: f = magma('GCD') # optional - magma - sage: f.evaluate(15,20) # optional - magma + sage: f = magma('GCD') + sage: f.evaluate(15,20) 5 sage: m = matrix(QQ, 2, 2, [2,3,5,7]) # optional - magma @@ -2242,13 +2261,14 @@ def __call__(self, *args): EXAMPLES:: - sage: M = magma.RMatrixSpace(magma.IntegerRing(), 2, 2) # optional - magma - sage: A = M([1,2,3,4]); A # optional - magma + sage: # optional - magma + sage: M = magma.RMatrixSpace(magma.IntegerRing(), 2, 2) + sage: A = M([1,2,3,4]); A [1 2] [3 4] - sage: type(A) # optional - magma + sage: type(A) - sage: A.Type() # optional - magma + sage: A.Type() ModMatRngElt """ if len(args) > 1: @@ -2274,16 +2294,17 @@ def __iter__(self): EXAMPLES:: - sage: V = magma('VectorSpace(GF(3),2)') # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(GF(3),2)') + sage: V Full Vector space of degree 2 over GF(3) - sage: w = V.__iter__(); w # optional - magma + sage: w = V.__iter__(); w - sage: next(w) # optional - magma + sage: next(w) (0 0) - sage: next(w) # optional - magma + sage: next(w) (1 0) - sage: list(w) # optional - magma + sage: list(w) [(2 0), (0 1), (1 1), (2 1), (0 2), (1 2), (2 2)] """ P = self._check_valid() @@ -2299,12 +2320,13 @@ def __len__(self): EXAMPLES:: - sage: V = magma('VectorSpace(GF(3),2)') # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(GF(3),2)') + sage: V Full Vector space of degree 2 over GF(3) - sage: len(V) # optional - magma + sage: len(V) 9 - sage: V.__len__() # optional - magma + sage: V.__len__() 9 """ P = self._check_valid() @@ -2431,11 +2453,12 @@ def _latex_(self): Power Series:: - sage: _=magma.eval('R := PowerSeriesRing(RationalField())') # optional - magma - sage: latex(magma('(1/(1+x))')) # optional - magma + sage: # optional - magma + sage: _=magma.eval('R := PowerSeriesRing(RationalField())') + sage: latex(magma('(1/(1+x))')) 1-x+x^{2}-x^{3}+x^{4}-x^{5}+x^{6}-x^{7}+x^{8}-x^{9}+x^{10}-x^{11}+x^{12}-x^{13}+x^{14}-x^{15}+x^{16}-x^{17}+x^{18}-x^{19}+O(x^{20}) - sage: _=magma.eval('R := PowerSeriesRing(RationalField())') # optional - magma - sage: latex(magma('(-1/(2+x + O(x^3)))')) # optional - magma + sage: _=magma.eval('R := PowerSeriesRing(RationalField())') + sage: latex(magma('(-1/(2+x + O(x^3)))')) \frac{-1}{2}+\frac{1}{4}x-\frac{1}{8}x^{2}+O(x^{3}) p-adic Numbers:: @@ -2457,11 +2480,12 @@ def set_magma_attribute(self, attrname, value): EXAMPLES:: - sage: V = magma("VectorSpace(RationalField(),2)") # optional - magma - sage: V.set_magma_attribute('M',10) # optional - magma - sage: V.get_magma_attribute('M') # optional - magma + sage: # optional - magma + sage: V = magma("VectorSpace(RationalField(),2)") + sage: V.set_magma_attribute('M',10) + sage: V.get_magma_attribute('M') 10 - sage: V.M # optional - magma + sage: V.M 10 """ P = self.parent() # instance of Magma that contains this element. @@ -2478,11 +2502,12 @@ def get_magma_attribute(self, attrname): EXAMPLES:: - sage: V = magma("VectorSpace(RationalField(),10)") # optional - magma - sage: V.set_magma_attribute('M','"hello"') # optional - magma - sage: V.get_magma_attribute('M') # optional - magma + sage: # optional - magma + sage: V = magma("VectorSpace(RationalField(),10)") + sage: V.set_magma_attribute('M','"hello"') + sage: V.get_magma_attribute('M') hello - sage: V.M # optional - magma + sage: V.M hello """ P = self.parent() @@ -2620,13 +2645,14 @@ def __bool__(self): Test use in bool conversions of bools:: - sage: bool(magma(False)) # optional - magma + sage: # optional - magma + sage: bool(magma(False)) False - sage: bool(magma(True)) # optional - magma + sage: bool(magma(True)) True - sage: bool(magma(1)) # optional - magma + sage: bool(magma(1)) True - sage: bool(magma(0)) # optional - magma + sage: bool(magma(0)) False TESTS: @@ -2713,12 +2739,13 @@ def quo(self, gens, **args): :: - sage: V = magma.RModule(ZZ,3); V # optional - magma + sage: # optional - magma + sage: V = magma.RModule(ZZ,3); V RModule(IntegerRing(), 3) - sage: W, phi = V.quo([[1,2,3]]) # optional - magma - sage: W # optional - magma + sage: W, phi = V.quo([[1,2,3]]) + sage: W RModule(IntegerRing(), 2) - sage: phi # optional - magma + sage: phi Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 2) """ return self.parent().bar_call(self, 'quo', gens, nvals=2) @@ -2741,10 +2768,11 @@ def ideal(self, gens): EXAMPLES:: - sage: R = magma('PolynomialRing(RationalField())') # optional - magma - sage: R.assign_names(['x']) # optional - magma - sage: x = R.1 # optional - magma - sage: R.ideal([x^2 - 1, x^3 - 1]) # optional - magma + sage: # optional - magma + sage: R = magma('PolynomialRing(RationalField())') + sage: R.assign_names(['x']) + sage: x = R.1 + sage: R.ideal([x^2 - 1, x^3 - 1]) Ideal of Univariate Polynomial Ring in x over Rational Field generated by x - 1 """ return self.parent().bar_call(self, 'ideal', gens, nvals=1) diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 7ba21a66cf6..1f4f209f127 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -605,12 +605,20 @@ def cputime(self, t=None): sage: # optional - maple sage: t = maple.cputime() +<<<<<<< HEAD sage: t # random +======= + sage: t +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.02 sage: x = maple('x') sage: maple.diff(x^2, x) 2*x +<<<<<<< HEAD sage: maple.cputime(t) # random +======= + sage: maple.cputime(t) +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.0 """ if t is None: @@ -810,7 +818,11 @@ def with_package(self, package): :: sage: # optional - maple +<<<<<<< HEAD sage: maple.quit() # reset maple +======= + sage: maple.quit() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) sage: maple('partition(10)') partition(10) sage: maple('bell(10)') @@ -947,7 +959,11 @@ def __hash__(self): sage: # optional - maple sage: m = maple('x^2+y^2') +<<<<<<< HEAD sage: m.__hash__() # random +======= + sage: m.__hash__() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 188724254834261060184983038723355865733 sage: hash(m) # random 5035731711831192733 diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 9c6e3ca86e9..9c64e9f4286 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -31,14 +31,15 @@ call the Mathematica wrapper object's ``sage()`` method. This method returns a native Sage object:: - sage: mobj = mathematica(x^2-1) # optional - mathematica - sage: mobj2 = mobj.Factor(); mobj2 # optional - mathematica + sage: # optional - mathematica + sage: mobj = mathematica(x^2-1) + sage: mobj2 = mobj.Factor(); mobj2 (-1 + x)*(1 + x) - sage: mobj2.parent() # optional - mathematica + sage: mobj2.parent() Mathematica - sage: sobj = mobj2.sage(); sobj # optional - mathematica + sage: sobj = mobj2.sage(); sobj (x + 1)*(x - 1) - sage: sobj.parent() # optional - mathematica + sage: sobj.parent() Symbolic Ring @@ -122,16 +123,17 @@ We solve an equation and a system of two equations:: - sage: eqn = mathematica('3x + 5 == 14') # optional - mathematica - sage: eqn # optional - mathematica + sage: # optional - mathematica + sage: eqn = mathematica('3x + 5 == 14') + sage: eqn 5 + 3*x == 14 - sage: eqn.Solve('x') # optional - mathematica + sage: eqn.Solve('x') {{x -> 3}} - sage: sys = mathematica('{x^2 - 3y == 3, 2x - y == 1}') # optional - mathematica - sage: print(sys) # optional - mathematica + sage: sys = mathematica('{x^2 - 3y == 3, 2x - y == 1}') + sage: print(sys) 2 {x - 3 y == 3, 2 x - y == 1} - sage: sys.Solve('{x, y}') # optional - mathematica + sage: sys.Solve('{x, y}') {{x -> 0, y -> -1}, {x -> 6, y -> 11}} Assignments and definitions @@ -227,15 +229,16 @@ We factor an integer:: - sage: n = mathematica(2434500) # optional - mathematica - sage: n.FactorInteger() # optional - mathematica + sage: # optional - mathematica + sage: n = mathematica(2434500) + sage: n.FactorInteger() {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: n = mathematica(2434500) # optional - mathematica - sage: F = n.FactorInteger(); F # optional - mathematica + sage: n = mathematica(2434500) + sage: F = n.FactorInteger(); F {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: F[1] # optional - mathematica + sage: F[1] {2, 2} - sage: F[4] # optional - mathematica + sage: F[4] {541, 1} Mathematica's ECM package is no longer available. @@ -261,17 +264,18 @@ :: - sage: x = mathematica(pi/2) # optional - mathematica - sage: print(x) # optional - mathematica + sage: # optional - mathematica + sage: x = mathematica(pi/2) + sage: print(x) Pi -- 2 - sage: loads(dumps(x)) == x # optional - mathematica + sage: loads(dumps(x)) == x True - sage: n = x.N(50) # optional - mathematica - sage: print(n) # optional - mathematica + sage: n = x.N(50) + sage: print(n) 1.5707963267948966192313216916397514420985846996876 - sage: loads(dumps(n)) == n # optional - mathematica + sage: loads(dumps(n)) == n True Complicated translations @@ -351,13 +355,14 @@ Check that numerical approximations via Mathematica's `N[]` function work correctly (:trac:`18888`, :trac:`28907`):: - sage: mathematica('Pi/2').N(10) # optional -- mathematica + sage: # optional - mathematica + sage: mathematica('Pi/2').N(10) 1.5707963268 - sage: mathematica('Pi').N(10) # optional -- mathematica + sage: mathematica('Pi').N(10) 3.1415926536 - sage: mathematica('Pi').N(50) # optional -- mathematica + sage: mathematica('Pi').N(50) 3.14159265358979323846264338327950288419716939937511 - sage: str(mathematica('Pi*x^2-1/2').N()) # optional -- mathematica + sage: str(mathematica('Pi*x^2-1/2').N()) 2 -0.5 + 3.14159 x @@ -373,13 +378,14 @@ Check that all trig/hyperbolic functions and their reciprocals are correctly translated to Mathematica (:trac:`34087`):: - sage: x=var('x') # optional - mathematica - sage: FL=[sin, cos, tan, csc, sec, cot, # optional - mathematica + sage: # optional - mathematica + sage: x=var('x') + sage: FL=[sin, cos, tan, csc, sec, cot, ....: sinh, cosh, tanh, csch, sech, coth] - sage: IFL=[arcsin, arccos, arctan, arccsc, # optional - mathematica + sage: IFL=[arcsin, arccos, arctan, arccsc, ....: arcsec, arccot, arcsinh, arccosh, ....: arctanh, arccsch, arcsech, arccoth] - sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + sage: [mathematica.TrigToExp(u(x)).sage() ....: for u in FL] [-1/2*I*e^(I*x) + 1/2*I*e^(-I*x), 1/2*e^(I*x) + 1/2*e^(-I*x), @@ -393,7 +399,7 @@ -2/(e^(-x) - e^x), 2/(e^(-x) + e^x), -(e^(-x) + e^x)/(e^(-x) - e^x)] - sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + sage: [mathematica.TrigToExp(u(x)).sage() ....: for u in IFL] [-I*log(I*x + sqrt(-x^2 + 1)), 1/2*pi + I*log(I*x + sqrt(-x^2 + 1)), @@ -789,12 +795,13 @@ def _sage_(self, locals={}): Mathematica lists of numbers/constants become Sage lists of numbers/constants:: - sage: m = mathematica('{{1., 4}, Pi, 3.2e100, I}') # optional - mathematica - sage: s = m.sage(); s # optional - mathematica + sage: # optional - mathematica + sage: m = mathematica('{{1., 4}, Pi, 3.2e100, I}') + sage: s = m.sage(); s [[1.00000000000000, 4], pi, 3.20000000000000*e100, I] - sage: s[1].n() # optional - mathematica + sage: s[1].n() 3.14159265358979 - sage: s[3]^2 # optional - mathematica + sage: s[3]^2 -1 :: @@ -825,11 +832,12 @@ def _sage_(self, locals={}): :: - sage: m = mathematica('bla^2') # optional - mathematica - sage: mb = m.sage() # optional - mathematica - sage: var('bla') # optional - mathematica + sage: # optional - mathematica + sage: m = mathematica('bla^2') + sage: mb = m.sage() + sage: var('bla') bla - sage: bla^2 - mb # optional - mathematica + sage: bla^2 - mb 0 diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 0bf0bc78829..aec033d3173 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -47,14 +47,15 @@ call the Mathics wrapper object's ``sage()`` method. This method returns a native Sage object:: - sage: mobj = mathics(x^2-1) # optional - mathics - sage: mobj2 = mobj.Factor(); mobj2 # optional - mathics + sage: # optional - mathics + sage: mobj = mathics(x^2-1) + sage: mobj2 = mobj.Factor(); mobj2 (-1 + x) (1 + x) - sage: mobj2.parent() # optional - mathics + sage: mobj2.parent() Mathics - sage: sobj = mobj2.sage(); sobj # optional - mathics + sage: sobj = mobj2.sage(); sobj (x + 1)*(x - 1) - sage: sobj.parent() # optional - mathics + sage: sobj.parent() Symbolic Ring @@ -132,15 +133,16 @@ We solve an equation and a system of two equations:: - sage: eqn = mathics('3x + 5 == 14') # optional - mathics - sage: eqn # optional - mathics + sage: # optional - mathics + sage: eqn = mathics('3x + 5 == 14') + sage: eqn 5 + 3 x == 14 - sage: eqn.Solve('x') # optional - mathics + sage: eqn.Solve('x') {{x -> 3}} - sage: sys = mathics('{x^2 - 3y == 3, 2x - y == 1}') # optional - mathics - sage: print(sys) # optional - mathics + sage: sys = mathics('{x^2 - 3y == 3, 2x - y == 1}') + sage: print(sys) {x ^ 2 - 3 y == 3, 2 x - y == 1} - sage: sys.Solve('{x, y}') # optional - mathics + sage: sys.Solve('{x, y}') {{x -> 0, y -> -1}, {x -> 6, y -> 11}} Assignments and definitions @@ -233,15 +235,16 @@ We factor an integer:: - sage: n = mathics(2434500) # optional - mathics - sage: n.FactorInteger() # optional - mathics + sage: # optional - mathics + sage: n = mathics(2434500) + sage: n.FactorInteger() {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: n = mathics(2434500) # optional - mathics - sage: F = n.FactorInteger(); F # optional - mathics + sage: n = mathics(2434500) + sage: F = n.FactorInteger(); F {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: F[1] # optional - mathics + sage: F[1] {2, 2} - sage: F[4] # optional - mathics + sage: F[4] {541, 1} @@ -266,15 +269,16 @@ :: - sage: x = mathics(pi/2) # optional - mathics - sage: print(x) # optional - mathics + sage: # optional - mathics + sage: x = mathics(pi/2) + sage: print(x) Pi / 2 - sage: loads(dumps(x)) == x # optional - mathics + sage: loads(dumps(x)) == x True - sage: n = x.N(50) # optional - mathics - sage: print(n) # optional - mathics + sage: n = x.N(50) + sage: print(n) 1.5707963267948966192313216916397514420985846996876 - sage: loads(dumps(n)) == n # optional - mathics + sage: loads(dumps(n)) == n True Complicated translations @@ -356,13 +360,14 @@ Check that numerical approximations via Mathics's `N[]` function work correctly (:trac:`18888`, :trac:`28907`):: - sage: mathics('Pi/2').N(10) # optional -- mathics + sage: # optional - mathics + sage: mathics('Pi/2').N(10) 1.570796327 - sage: mathics('Pi').N(10) # optional -- mathics + sage: mathics('Pi').N(10) 3.141592654 - sage: mathics('Pi').N(50) # optional -- mathics + sage: mathics('Pi').N(50) 3.1415926535897932384626433832795028841971693993751 - sage: str(mathics('Pi*x^2-1/2').N()) # optional -- mathics + sage: str(mathics('Pi*x^2-1/2').N()) '-0.5 + 3.14159 x ^ 2.' Check that Mathics's `E` exponential symbol is correctly backtranslated @@ -405,15 +410,16 @@ def _mathics_sympysage_symbol(self): EXAMPLES:: + sage: # optional - mathics sage: from sage.interfaces.mathics import _mathics_sympysage_symbol - sage: mt = mathics('t') # optional - mathics - sage: st = mt.to_sympy(); st # optional - mathics + sage: mt = mathics('t') + sage: st = mt.to_sympy(); st _Mathics_User_Global`t - sage: _mathics_sympysage_symbol(st) # optional - mathics + sage: _mathics_sympysage_symbol(st) t - sage: bool(_ == st._sage_()) # optional - mathics + sage: bool(_ == st._sage_()) True - sage: type(st._sage_()) # optional - mathics + sage: type(st._sage_()) """ from sage.symbolic.ring import SR @@ -442,20 +448,21 @@ class Mathics(Interface): EXAMPLES:: - sage: t = mathics('Tan[I + 0.5]') # optional - mathics - sage: t.parent() # optional - mathics + sage: # optional - mathics + sage: t = mathics('Tan[I + 0.5]') + sage: t.parent() Mathics - sage: ts = t.sage() # optional - mathics - sage: ts.parent() # optional - mathics + sage: ts = t.sage() + sage: ts.parent() Complex Field with 53 bits of precision - sage: t == mathics(ts) # optional - mathics + sage: t == mathics(ts) True - sage: mtan = mathics.Tan # optional - mathics - sage: mt = mtan(I+1/2) # optional - mathics - sage: mt == t # optional - mathics + sage: mtan = mathics.Tan + sage: mt = mtan(I+1/2) + sage: mt == t True - sage: u = mathics(I+1/2) # optional - mathics - sage: u.Tan() == mt # optional - mathics + sage: u = mathics(I+1/2) + sage: u.Tan() == mt True @@ -829,34 +836,37 @@ class MathicsElement(ExtraTabCompletion, InterfaceElement): EXAMPLES:: - sage: me=mathics(e); me # optional - mathics + sage: # optional - mathics + sage: me=mathics(e); me E - sage: type(me) # optional - mathics + sage: type(me) - sage: P = me.parent(); P # optional - mathics + sage: P = me.parent(); P Mathics - sage: type(P) # optional - mathics + sage: type(P) Access to the Mathics expression objects:: - sage: res = me._mathics_result # optional - mathics - sage: type(res) # optional - mathics + sage: # optional - mathics + sage: res = me._mathics_result + sage: type(res) - sage: expr = res.last_eval; expr # optional - mathics + sage: expr = res.last_eval; expr - sage: type(expr) # optional - mathics + sage: type(expr) Applying Mathics methods:: - sage: me.to_sympy() # optional - mathics + sage: # optional - mathics + sage: me.to_sympy() E - sage: me.get_name() # optional - mathics + sage: me.get_name() 'System`E' - sage: me.is_inexact() # optional - mathics + sage: me.is_inexact() False - sage: me.is_symbol() # optional - mathics + sage: me.is_symbol() True Conversion to Sage:: @@ -900,12 +910,13 @@ def __getattr__(self, attrname): r""" EXAMPLES:: - sage: a = mathics(5*x) # optional - mathics - sage: res = a._mathics_result # optional - mathics - sage: str(a) == res.result # optional - mathics + sage: # optional - mathics + sage: a = mathics(5*x) + sage: res = a._mathics_result + sage: str(a) == res.result True - sage: t = mathics._eval('5*x') # optional - mathics - sage: t.last_eval == res.last_eval # optional - mathics + sage: t = mathics._eval('5*x') + sage: t.last_eval == res.last_eval True """ P = self._check_valid() @@ -1004,12 +1015,13 @@ def _sage_(self, locals={}): Mathics lists of numbers/constants become Sage lists of numbers/constants:: - sage: m = mathics('{{1., 4}, Pi, 3.2e100, I}') # optional - mathics - sage: s = m.sage(); s # optional - mathics + sage: # optional - mathics + sage: m = mathics('{{1., 4}, Pi, 3.2e100, I}') + sage: s = m.sage(); s [[1.00000000000000, 4], pi, 3.20000000000000*e100, 1.00000000000000*I] - sage: s[1].n() # optional - mathics + sage: s[1].n() 3.14159265358979 - sage: s[3]^2 # optional - mathics + sage: s[3]^2 -1.00000000000000 :: @@ -1040,11 +1052,12 @@ def _sage_(self, locals={}): :: - sage: m = mathics('bla^2') # optional - mathics - sage: mb = m.sage() # optional - mathics - sage: var('bla') # optional - mathics + sage: # optional - mathics + sage: m = mathics('bla^2') + sage: mb = m.sage() + sage: var('bla') bla - sage: bla^2 - mb # optional - mathics + sage: bla^2 - mb 0 """ @@ -1203,14 +1216,15 @@ def _richcmp_(self, other, op): r""" EXAMPLES:: - sage: mobj1 = mathics([x^2-1, 2]) # optional - mathics - sage: mobj2 = mathics('{x^2-1, 2}') # optional - mathics - sage: mobj3 = mathics('5*x + y') # optional - mathics - sage: mobj1 == mobj2 # optional - mathics + sage: # optional - mathics + sage: mobj1 = mathics([x^2-1, 2]) + sage: mobj2 = mathics('{x^2-1, 2}') + sage: mobj3 = mathics('5*x + y') + sage: mobj1 == mobj2 True - sage: mobj1 < mobj2 # optional - mathics + sage: mobj1 < mobj2 False - sage: mobj1 == mobj3 # optional - mathics + sage: mobj1 == mobj3 False """ P = self.parent() diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index 24c40a3647c..74354b77412 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -30,53 +30,57 @@ EXAMPLES:: - sage: matlab('4+10') # optional - matlab + sage: # optional - matlab + sage: matlab('4+10') 14 - sage: matlab('date') # optional - matlab; random output + sage: matlab('date') 18-Oct-2006 - sage: matlab('5*10 + 6') # optional - matlab + sage: matlab('5*10 + 6') 56 - sage: matlab('(6+6)/3') # optional - matlab + sage: matlab('(6+6)/3') 4 - sage: matlab('9')^2 # optional - matlab + sage: matlab('9')^2 81 - sage: a = matlab(10); b = matlab(20); c = matlab(30) # optional - matlab - sage: avg = (a+b+c)/3 ; avg # optional - matlab + sage: a = matlab(10); b = matlab(20); c = matlab(30) + sage: avg = (a+b+c)/3 ; avg 20 - sage: parent(avg) # optional - matlab + sage: parent(avg) Matlab :: - sage: my_scalar = matlab('3.1415') # optional - matlab - sage: my_scalar # optional - matlab + sage: # optional - matlab + sage: my_scalar = matlab('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = matlab('[1,5,7]') # optional - matlab - sage: my_vector1 # optional - matlab + sage: my_vector1 = matlab('[1,5,7]') + sage: my_vector1 1 5 7 - sage: my_vector2 = matlab('[1;5;7]') # optional - matlab - sage: my_vector2 # optional - matlab + sage: my_vector2 = matlab('[1;5;7]') + sage: my_vector2 1 5 7 - sage: my_vector1 * my_vector2 # optional - matlab + sage: my_vector1 * my_vector2 75 :: - sage: row_vector1 = matlab('[1 2 3]') # optional - matlab - sage: row_vector2 = matlab('[3 2 1]') # optional - matlab - sage: matrix_from_row_vec = matlab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) # optional - matlab - sage: matrix_from_row_vec # optional - matlab + sage: # optional - matlab + sage: row_vector1 = matlab('[1 2 3]') + sage: row_vector2 = matlab('[3 2 1]') + sage: matrix_from_row_vec = matlab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) + sage: matrix_from_row_vec 1 2 3 3 2 1 :: - sage: column_vector1 = matlab('[1;3]') # optional - matlab - sage: column_vector2 = matlab('[2;8]') # optional - matlab - sage: matrix_from_col_vec = matlab('[%s %s]'%(column_vector1.name(), column_vector2.name())) # optional - matlab - sage: matrix_from_col_vec # optional - matlab + sage: # optional - matlab + sage: column_vector1 = matlab('[1;3]') + sage: column_vector2 = matlab('[2;8]') + sage: matrix_from_col_vec = matlab('[%s %s]'%(column_vector1.name(), column_vector2.name())) + sage: matrix_from_col_vec 1 2 3 8 @@ -106,12 +110,13 @@ :: - sage: my_vector1 = matlab('[1,5,7]') # optional - matlab - sage: my_vector1(1) # optional - matlab + sage: # optional - matlab + sage: my_vector1 = matlab('[1,5,7]') + sage: my_vector1(1) 1 - sage: my_vector1(2) # optional - matlab + sage: my_vector1(2) 5 - sage: my_vector1(3) # optional - matlab + sage: my_vector1(3) 7 Matrix indexing works as follows:: @@ -159,10 +164,11 @@ class Matlab(Expect): EXAMPLES:: - sage: a = matlab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') # optional - matlab - sage: b = matlab('[ 1; 3; 13]') # optional - matlab - sage: c = a * b # optional - matlab - sage: print(c) # optional - matlab + sage: # optional - matlab + sage: a = matlab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') + sage: b = matlab('[ 1; 3; 13]') + sage: c = a * b + sage: print(c) 30 122 505 @@ -328,12 +334,13 @@ def _matrix_(self, R): EXAMPLES:: - sage: A = matlab('[1,2;3,4]') # optional - matlab - sage: matrix(ZZ, A) # optional - matlab + sage: # optional - matlab + sage: A = matlab('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = matlab('[1,2;3,4.5]') # optional - matlab - sage: matrix(RR, A) # optional - matlab + sage: A = matlab('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index 956de696806..82920a9edaa 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -13,23 +13,25 @@ TESTS:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad - sage: combinat = mupad.combinat # optional - mupad - sage: examples = mupad.examples # optional - mupad - sage: S = examples.SymmetricFunctions() # optional - mupad - sage: S.s[2,1]^2 # optional - mupad + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: examples = mupad.examples + sage: S = examples.SymmetricFunctions() + sage: S.s[2,1]^2 s[3, 3] + s[4, 2] + s[2, 2, 1, 1] + s[2, 2, 2] + 2 s[3, 2, 1] + s[4, 1, 1] + s[3, 1, 1, 1] - sage: S.omega( S.s[3] ) # optional - mupad + sage: S.omega( S.s[3] ) s[1, 1, 1] - sage: s = S.s # optional - mupad - sage: p = S.p # optional - mupad - sage: s(s[2,1] + p[2,1]) # optional - mupad + sage: s = S.s + sage: p = S.p + sage: s(s[2,1] + p[2,1]) s[2, 1] + s[3] - s[1, 1, 1] - sage: s(_) # optional - mupad + sage: s(_) s[2, 1] + s[3] - s[1, 1, 1] - sage: combinat.tableaux.list(3) # optional - mupad # note: the order of the result seems to depend on the version of MuPAD / MuPAD-Combinat + sage: # optional - mupad + sage: combinat.tableaux.list(3) -- +---+ -- | | 3 | | | +---+ +---+ +---+ | @@ -37,8 +39,8 @@ | +---+---+---+ +---+---+ +---+---+ +---+ | | | 1 | 2 | 3 |, | 1 | 2 |, | 1 | 3 |, | 1 | | -- +---+---+---+ +---+---+ +---+---+ +---+ -- - sage: three = mupad(3) # optional - mupad - sage: three.combinat.tableaux.list() # optional - mupad + sage: three = mupad(3) + sage: three.combinat.tableaux.list() -- +---+ -- | | 3 | | | +---+ +---+ +---+ | @@ -46,12 +48,12 @@ | +---+---+---+ +---+---+ +---+---+ +---+ | | | 1 | 2 | 3 |, | 1 | 2 |, | 1 | 3 |, | 1 | | -- +---+---+---+ +---+---+ +---+---+ +---+ -- - sage: t = _[1] # optional - mupad - sage: t # optional - mupad + sage: t = _[1] + sage: t +---+---+---+ | 1 | 2 | 3 | +---+---+---+ - sage: combinat.tableaux.conjugate(t) # optional - mupad + sage: combinat.tableaux.conjugate(t) +---+ | 3 | +---+ @@ -60,21 +62,22 @@ | 1 | +---+ - sage: combinat.ribbonsTableaux.list([2,2],[1,1],2) # optional - mupad + sage: # optional - mupad + sage: combinat.ribbonsTableaux.list([2,2],[1,1],2) -- +---+---+ +---+---+ -- | | | 2 | | 2 | | | + + +, +---+---+ | | | 1 | | | 1 | | -- +---+---+ +---+---+ -- - sage: combinat.tableaux.kAtom([2,1],3) # optional - mupad + sage: combinat.tableaux.kAtom([2,1],3) -- +---+ -- | | 2 | | | +---+---+ | | | 1 | 1 | | -- +---+---+ -- - sage: M = S.Macdonald() # optional - mupad - sage: a = M.P[1]^2 # optional - mupad - sage: mupad.mapcoeffs(a, 'normal') # optional - mupad + sage: M = S.Macdonald() + sage: a = M.P[1]^2 + sage: mupad.mapcoeffs(a, 'normal') q - t + q t - 1 P[2] + --------------- P[1, 1] q t - 1 @@ -491,13 +494,14 @@ def __getattr__(self, attrname): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: combinat = mupad.combinat # optional - mupad-Combinat - sage: three = mupad(3) # optional - mupad-Combinat - sage: type(three.combinat) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: three = mupad(3) + sage: type(three.combinat) - sage: tableaux = three.combinat.tableaux # optional - mupad-Combinat - sage: type(tableaux) # optional - mupad-Combinat + sage: tableaux = three.combinat.tableaux + sage: type(tableaux) """ P = self._obj.parent() @@ -528,13 +532,14 @@ def __call__(self, *args): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: combinat = mupad.combinat # optional - mupad-Combinat - sage: examples = mupad.examples # optional - mupad-Combinat - sage: S = examples.SymmetricFunctions() # optional - mupad-Combinat - sage: type(S.omega) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: examples = mupad.examples + sage: S = examples.SymmetricFunctions() + sage: type(S.omega) - sage: S.omega(S.s[3]) # optional - mupad-Combinat + sage: S.omega(S.s[3]) s[1, 1, 1] """ P = self._obj.parent() @@ -551,11 +556,12 @@ def __getattr__(self, attrname): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: S = mupad.examples.SymmetricFunctions() # optional - mupad-Combinat - sage: type(S) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: S = mupad.examples.SymmetricFunctions() + sage: type(S) - sage: S.s # optional - mupad-Combinat + sage: S.s (examples::SymmetricFunctions(Dom::ExpressionField()))::s sage: x = mupad('x') # optional - mupad-Combinat diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index d0f5694c8bc..10e8457aa0f 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -60,31 +60,32 @@ :: - sage: octave("airy(3,2)") # optional - octave + sage: # optional - octave + sage: octave("airy(3,2)") 4.10068 - sage: octave("beta(2,2)") # optional - octave + sage: octave("beta(2,2)") 0.166667 - sage: octave("betainc(0.2,2,2)") # optional - octave + sage: octave("betainc(0.2,2,2)") 0.104 - sage: octave("besselh(0,2)") # optional - octave + sage: octave("besselh(0,2)") (0.223891,0.510376) - sage: octave("besselh(0,1)") # optional - octave + sage: octave("besselh(0,1)") (0.765198,0.088257) - sage: octave("besseli(1,2)") # optional - octave + sage: octave("besseli(1,2)") 1.59064 - sage: octave("besselj(1,2)") # optional - octave + sage: octave("besselj(1,2)") 0.576725 - sage: octave("besselk(1,2)") # optional - octave + sage: octave("besselk(1,2)") 0.139866 - sage: octave("erf(0)") # optional - octave + sage: octave("erf(0)") 0 - sage: octave("erf(1)") # optional - octave + sage: octave("erf(1)") 0.842701 - sage: octave("erfinv(0.842)") # optional - octave + sage: octave("erfinv(0.842)") 0.998315 - sage: octave("gamma(1.5)") # optional - octave + sage: octave("gamma(1.5)") 0.886227 - sage: octave("gammainc(1.5,1)") # optional - octave + sage: octave("gammainc(1.5,1)") 0.77687 Tutorial @@ -92,37 +93,39 @@ EXAMPLES:: - sage: octave('4+10') # optional - octave + sage: # optional - octave + sage: octave('4+10') 14 - sage: octave('date') # optional - octave; random output + sage: octave('date') 18-Oct-2007 - sage: octave('5*10 + 6') # optional - octave + sage: octave('5*10 + 6') 56 - sage: octave('(6+6)/3') # optional - octave + sage: octave('(6+6)/3') 4 - sage: octave('9')^2 # optional - octave + sage: octave('9')^2 81 - sage: a = octave(10); b = octave(20); c = octave(30) # optional - octave - sage: avg = (a+b+c)/3 # optional - octave - sage: avg # optional - octave + sage: a = octave(10); b = octave(20); c = octave(30) + sage: avg = (a+b+c)/3 + sage: avg 20 - sage: parent(avg) # optional - octave + sage: parent(avg) Octave :: - sage: my_scalar = octave('3.1415') # optional - octave - sage: my_scalar # optional - octave + sage: # optional - octave + sage: my_scalar = octave('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = octave('[1,5,7]') # optional - octave - sage: my_vector1 # optional - octave + sage: my_vector1 = octave('[1,5,7]') + sage: my_vector1 1 5 7 - sage: my_vector2 = octave('[1;5;7]') # optional - octave - sage: my_vector2 # optional - octave + sage: my_vector2 = octave('[1;5;7]') + sage: my_vector2 1 5 7 - sage: my_vector1 * my_vector2 # optional - octave + sage: my_vector1 * my_vector2 75 """ @@ -356,11 +359,12 @@ def _start(self): EXAMPLES:: - sage: o = Octave() # optional - octave - sage: o.is_running() # optional - octave + sage: # optional - octave + sage: o = Octave() + sage: o.is_running() False - sage: o._start() # optional - octave - sage: o.is_running() # optional - octave + sage: o._start() + sage: o.is_running() True """ Expect._start(self) @@ -647,13 +651,14 @@ def __bool__(self): EXAMPLES:: - sage: bool(octave('0')) # optional - octave + sage: # optional - octave + sage: bool(octave('0')) False - sage: bool(octave('[]')) # optional - octave + sage: bool(octave('[]')) False - sage: bool(octave('[0,0]')) # optional - octave + sage: bool(octave('[0,0]')) False - sage: bool(octave('[0,0,0;0,0,0]')) # optional - octave + sage: bool(octave('[0,0,0;0,0,0]')) False sage: bool(octave('0.1')) # optional - octave @@ -685,12 +690,13 @@ def _matrix_(self, R=None): sage: _.base_ring() # optional - octave Complex Double Field - sage: A = octave('[1,2;3,4]') # optional - octave - sage: matrix(ZZ, A) # optional - octave + sage: # optional - octave + sage: A = octave('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = octave('[1,2;3,4.5]') # optional - octave - sage: matrix(RR, A) # optional - octave + sage: A = octave('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] """ @@ -716,14 +722,15 @@ def _vector_(self, R=None): EXAMPLES:: - sage: A = octave('[1,2,3,4]') # optional - octave - sage: vector(ZZ, A) # optional - octave + sage: # optional - octave + sage: A = octave('[1,2,3,4]') + sage: vector(ZZ, A) (1, 2, 3, 4) - sage: A = octave('[1,2.3,4.5]') # optional - octave - sage: vector(A) # optional - octave + sage: A = octave('[1,2.3,4.5]') + sage: vector(A) (1.0, 2.3, 4.5) - sage: A = octave('[1,I]') # optional - octave - sage: vector(A) # optional - octave + sage: A = octave('[1,I]') + sage: vector(A) (1.0, 1.0*I) """ from sage.modules.free_module import FreeModule @@ -780,23 +787,24 @@ def _sage_(self): EXAMPLES:: - sage: A = octave('2833') # optional - octave - sage: A.sage() # optional - octave + sage: # optional - octave + sage: A = octave('2833') + sage: A.sage() 2833.0 - sage: B = sqrt(A) # optional - octave - sage: B.sage() # optional - octave + sage: B = sqrt(A) + sage: B.sage() 53.2259 - sage: C = sqrt(-A) # optional - octave - sage: C.sage() # optional - octave + sage: C = sqrt(-A) + sage: C.sage() 53.2259*I - sage: A = octave('[1,2,3,4]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2,3,4]') + sage: A.sage() (1.0, 2.0, 3.0, 4.0) - sage: A = octave('[1,2.3,4.5]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2.3,4.5]') + sage: A.sage() (1.0, 2.3, 4.5) - sage: A = octave('[1,2.3+I,4.5]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2.3+I,4.5]') + sage: A.sage() (1.0, 2.3 + 1.0*I, 4.5) """ if self.isscalar(): diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index 9161ebd5377..3875ff7962e 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -243,15 +243,16 @@ def _function_call_string(self, function, args, kwds): EXAMPLES:: - sage: polymake._function_call_string('cube', ['2','7','3'], ['group=>1']) # optional - jupymake + sage: # optional - jupymake + sage: polymake._function_call_string('cube', ['2','7','3'], ['group=>1']) 'cube(2,7,3, group=>1);' - sage: c = polymake('cube(2,7,3, group=>1)') # optional - jupymake - sage: c.VERTICES # optional - jupymake + sage: c = polymake('cube(2,7,3, group=>1)') + sage: c.VERTICES 1 3 3 1 7 3 1 3 7 1 7 7 - sage: c.GROUP # optional - jupymake + sage: c.GROUP full combinatorial group """ @@ -461,13 +462,14 @@ def clear(self, var): TESTS:: - sage: c = polymake.cube(15) # optional - jupymake - sage: polymake._available_vars = [] # optional - jupymake - sage: old = c._name # optional - jupymake - sage: del c # optional - jupymake # indirect doctest - sage: len(polymake._available_vars) # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(15) + sage: polymake._available_vars = [] + sage: old = c._name + sage: del c + sage: len(polymake._available_vars) 1 - sage: polymake._next_var_name() in old # optional - jupymake + sage: polymake._next_var_name() in old True """ @@ -500,13 +502,14 @@ def _create(self, value, name=None): EXAMPLES:: - sage: polymake._create("('foo', 'bar')", name="my_array") # optional - jupymake + sage: # optional - jupymake + sage: polymake._create("('foo', 'bar')", name="my_array") '@my_array' - sage: print(polymake.eval('print join(", ", @my_array);')) # optional - jupymake + sage: print(polymake.eval('print join(", ", @my_array);')) foo, bar - sage: polymake._create('"foobar"', name="my_string") # optional - jupymake + sage: polymake._create('"foobar"', name="my_string") '$my_string[0]' - sage: print(polymake.eval('print $my_string[0];')) # optional - jupymake + sage: print(polymake.eval('print $my_string[0];')) foobar """ @@ -743,20 +746,22 @@ def application(self, app): terms of inequalities. Polymake knows to compute the f- and h-vector and finds that the polytope is very ample:: - sage: q = polymake.new_object("Polytope", INEQUALITIES=[[5,-4,0,1],[-3,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1],[1,0,-1,0],[3,-1,0,0]]) # optional - jupymake - sage: q.H_VECTOR # optional - jupymake + sage: # optional - jupymake + sage: q = polymake.new_object("Polytope", INEQUALITIES=[[5,-4,0,1],[-3,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1],[1,0,-1,0],[3,-1,0,0]]) + sage: q.H_VECTOR 1 5 5 1 - sage: q.F_VECTOR # optional - jupymake + sage: q.F_VECTOR 8 14 8 - sage: q.VERY_AMPLE # optional - jupymake + sage: q.VERY_AMPLE true In the application 'fan', polymake can now compute the normal fan of `q` and its (primitive) rays:: - sage: polymake.application('fan') # optional - jupymake - sage: g = q.normal_fan() # optional - jupymake - sage: g.RAYS # optional - jupymake + sage: # optional - jupymake + sage: polymake.application('fan') + sage: g = q.normal_fan() + sage: g.RAYS -1 0 1/4 0 -1 1/4 1 0 0 @@ -765,7 +770,7 @@ def application(self, app): 0 0 -1 0 -1 0 -1 0 0 - sage: g.RAYS.primitive() # optional - jupymake + sage: g.RAYS.primitive() -4 0 1 0 -4 1 1 0 0 @@ -784,14 +789,15 @@ def application(self, app): but only in 'tropical', the following shows the effect of changing the application. :: - sage: polymake.application('polytope') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: # optional - jupymake + sage: polymake.application('polytope') + sage: 'trop_witness' in dir(polymake) False - sage: polymake.application('tropical') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: polymake.application('tropical') + sage: 'trop_witness' in dir(polymake) True - sage: polymake.application('polytope') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: polymake.application('polytope') + sage: 'trop_witness' in dir(polymake) False For completeness, we show what happens when asking for an application @@ -827,17 +833,18 @@ def new_object(self, name, *args, **kwds): EXAMPLES:: - sage: q = polymake.new_object("Polytope", INEQUALITIES=[[4,-4,0,1],[-4,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1]]) # optional - jupymake - sage: q.N_VERTICES # optional - jupymake + sage: # optional - jupymake + sage: q = polymake.new_object("Polytope", INEQUALITIES=[[4,-4,0,1],[-4,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1]]) + sage: q.N_VERTICES 4 - sage: q.BOUNDED # optional - jupymake + sage: q.BOUNDED true - sage: q.VERTICES # optional - jupymake + sage: q.VERTICES 1 2 0 4 1 3 0 8 1 2 1 8 1 3 1 8 - sage: q.full_typename() # optional - jupymake + sage: q.full_typename() 'Polytope' """ @@ -885,11 +892,12 @@ def _repr_(self): of the object that is not longer than single line, it is used for printing:: - sage: p = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake - sage: p # optional - jupymake + sage: # optional - jupymake + sage: p = polymake.rand_sphere(3, 12, seed=15) + sage: p Random spherical polytope of dimension 3; seed=15... - sage: c = polymake.cube(4) # optional - jupymake - sage: c # optional - jupymake + sage: c = polymake.cube(4) + sage: c cube of dimension 4 We use the print representation of scalars to display scalars:: @@ -924,11 +932,12 @@ def _repr_(self): Similarly, polymake matrices and vectors are explicitly listed:: - sage: c.VERTICES.typename() # optional - jupymake + sage: # optional - jupymake + sage: c.VERTICES.typename() 'Matrix' - sage: c.VERTICES[0].typename() # optional - jupymake + sage: c.VERTICES[0].typename() 'Vector' - sage: c.VERTICES # optional - jupymake # random + sage: c.VERTICES 1 -1 -1 -1 -1 1 1 -1 -1 -1 1 -1 1 -1 -1 @@ -945,7 +954,7 @@ def _repr_(self): 1 1 -1 1 1 1 -1 1 1 1 1 1 1 1 1 - sage: c.VERTICES[0] # optional - jupymake + sage: c.VERTICES[0] 1 -1 -1 -1 -1 For other types, we simply use the print representation offered @@ -1225,34 +1234,37 @@ def __getattr__(self, attrname): A property:: - sage: c = polymake.cube(3) # optional - jupymake - sage: c.H_VECTOR # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(3) + sage: c.H_VECTOR 1 5 5 1 - sage: c.N_VERTICES # optional - jupymake + sage: c.N_VERTICES 8 - sage: d = polymake.cross(3) # optional - jupymake - sage: d.N_VERTICES # optional - jupymake + sage: d = polymake.cross(3) + sage: d.N_VERTICES 6 A function:: - sage: c.minkowski_sum_fukuda # optional - jupymake + sage: # optional - jupymake + sage: c.minkowski_sum_fukuda minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object) - sage: s = c.minkowski_sum_fukuda(d) # optional - jupymake - sage: s.N_VERTICES # optional - jupymake + sage: s = c.minkowski_sum_fukuda(d) + sage: s.N_VERTICES 24 - sage: s # optional - jupymake + sage: s Polytope[SAGE...] A member function:: - sage: c = polymake.cube(2) # optional - jupymake - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains # optional - jupymake + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true """ @@ -1281,13 +1293,14 @@ def get_member_function(self, attrname): EXAMPLES:: - sage: c = polymake.cube(2) # optional - jupymake - sage: c.contains # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true Whether a member function of the given name actually exists for that @@ -1438,12 +1451,13 @@ def typeof(self): EXAMPLES:: - sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake - sage: p.typeof() # optional - jupymake + sage: # optional - jupymake + sage: p = polymake.rand_sphere(3, 13, seed=12) + sage: p.typeof() ('Polymake::polytope::Polytope__Rational', 'ARRAY') - sage: p.VERTICES.typeof() # optional - jupymake + sage: p.VERTICES.typeof() ('Polymake::common::Matrix_A_Rational_I_NonSymmetric_Z', 'ARRAY') - sage: p.get_schedule('"F_VECTOR"').typeof() # optional - jupymake + sage: p.get_schedule('"F_VECTOR"').typeof() ('Polymake::Core::Scheduler::RuleChain', 'ARRAY') On "small" objects, it just returns empty strings:: @@ -1666,13 +1680,14 @@ class PolymakeFunctionElement(InterfaceFunctionElement): EXAMPLES:: - sage: c = polymake.cube(2) # optional - jupymake - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains # optional - jupymake + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true """ @@ -1840,16 +1855,17 @@ class PolymakeJuPyMake(PolymakeAbstract): :: - sage: L = polymake.db_query({'"_id"': '"F.4D.0047"'}, # long time, optional - jupymake internet perl_mongodb + sage: # long time, optional - internet jupymake perl_mongodb + sage: L = polymake.db_query({'"_id"': '"F.4D.0047"'}, ....: db='"LatticePolytopes"', ....: collection='"SmoothReflexive"'); L BigObjectArray - sage: len(L) # long time, optional - jupymake internet perl_mongodb + sage: len(L) 1 - sage: P = L[0] # long time, optional - jupymake internet perl_mongodb - sage: sorted(P.list_properties(), key=str) # long time, optional - jupymake internet perl_mongodb + sage: P = L[0] + sage: sorted(P.list_properties(), key=str) [..., LATTICE_POINTS_GENERATORS, ..., POINTED, ...] - sage: P.F_VECTOR # long time, optional - jupymake internet perl_mongodb + sage: P.F_VECTOR 20 40 29 9 """ diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index b6b657515bc..5a69861eec8 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -404,13 +404,14 @@ A :class:`QepcadCell` has accessor methods for the important state held within a cell. For instance:: - sage: c.level() # optional - qepcad + sage: # optional - qepcad + sage: c.level() 2 - sage: c.index() # optional - qepcad + sage: c.index() (3, 4) - sage: qe.cell(3).number_of_children() # optional - qepcad + sage: qe.cell(3).number_of_children() 5 - sage: len(qe.cell(3)) # optional - qepcad + sage: len(qe.cell(3)) 5 One particularly useful thing we can get from a cell is its sample point, @@ -574,19 +575,20 @@ sage: _qepcad_atoms(qepcad(F, solution='extended')) # optional - qepcad {'x > _root_1 2 x^2 - 3', 'x^2 - 3 <= 0'} - sage: qe = qepcad(qf.and_(ellipse == 0, circle == 0), interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(qf.and_(ellipse == 0, circle == 0), interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'Before Projection (y)' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: for c in qe.cell(): # optional - qepcad + sage: for c in qe.cell(): ....: count_ellipse = 0 ....: count_circle = 0 ....: for c2 in c: ....: count_ellipse += (c2.signs()[1][0] == 0) ....: count_circle += (c2.signs()[1][1] == 0) ....: c.set_truth(count_ellipse == 2 and count_circle == 2) - sage: _qepcad_atoms(qe.solution_extension('G')) # optional - qepcad + sage: _qepcad_atoms(qe.solution_extension('G')) {'8 x^2 - 8 x - 29 < 0', 'x^2 - 3 < 0'} @@ -1044,24 +1046,25 @@ def phase(self): EXAMPLES:: - sage: qe = qepcad(x > 2/3, interact=True) # optional - qepcad - sage: qe.phase() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x > 2/3, interact=True) + sage: qe.phase() 'Before Normalization' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'At the end of projection phase' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'At the end of projection phase' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'Before Choice' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'Before Choice' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'Before Solution' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'Before Solution' - sage: qe.go() # optional - qepcad + sage: qe.go() 3 x - 2 > 0 - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'EXITED' """ match = self._qex.expect().match @@ -1079,13 +1082,14 @@ def _parse_answer_stats(self): EXAMPLES:: - sage: qe = qepcad(x^2 > 2, interact=True) # optional - qepcad - sage: qe.finish() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x^2 > 2, interact=True) + sage: qe.finish() x^2 - 2 > 0 - sage: (ans, stats) = qe._parse_answer_stats() # optional - qepcad - sage: ans # optional - qepcad + sage: (ans, stats) = qe._parse_answer_stats() + sage: ans 'x^2 - 2 > 0' - sage: stats # random, optional - qepcad + sage: stats '-----------------------------------------------------------------------------\r\n0 Garbage collections, 0 Cells and 0 Arrays reclaimed, in 0 milliseconds.\r\n492514 Cells in AVAIL, 500000 Cells in SPACE.\r\n\r\nSystem time: 16 milliseconds.\r\nSystem time after the initialization: 4 milliseconds.\r\n-----------------------------------------------------------------------------\r\n' """ if self.phase() != 'EXITED': @@ -1168,14 +1172,15 @@ def cell(self, *index): EXAMPLES:: - sage: qe = qepcad(x + 3 == 42, interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x + 3 == 42, interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'At the end of projection phase' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: qe.cell(2) # optional - qepcad + sage: qe.cell(2) QEPCAD cell (2) - sage: qe.cell(2) is qe.cell(2) # optional - qepcad + sage: qe.cell(2) is qe.cell(2) True """ index_str = _format_cell_index(index) @@ -2696,16 +2701,17 @@ def sample_point(self): EXAMPLES:: - sage: qe = qepcad(x^2 - x - 1 == 0, interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x^2 - x - 1 == 0, interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'At the end of projection phase' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: v1 = qe.cell(2).sample_point()[0]; v1 # optional - qepcad + sage: v1 = qe.cell(2).sample_point()[0]; v1 -0.618033988749895? - sage: v2 = qe.cell(4).sample_point()[0]; v2 # optional - qepcad + sage: v2 = qe.cell(4).sample_point()[0]; v2 1.618033988749895? - sage: v1 + v2 == 1 # optional - qepcad + sage: v1 + v2 == 1 True """ try: diff --git a/src/sage/interfaces/rubik.py b/src/sage/interfaces/rubik.py index 109a2623c95..767c440715d 100644 --- a/src/sage/interfaces/rubik.py +++ b/src/sage/interfaces/rubik.py @@ -137,19 +137,20 @@ def solve(self, facets): EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: solver = DikSolver() # optional - rubiks - sage: solver = OptimalSolver() # optional - rubiks # long time (28s on sage.math, 2012) + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: solver = DikSolver() + sage: solver = OptimalSolver() # long time (28s on sage.math, 2012) Initializing tables... Done. - sage: C = RubiksCube("R U") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R U") + sage: solver.solve(C.facets()) 'R U' - sage: C = RubiksCube("R U F L B D") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R U F L B D") + sage: solver.solve(C.facets()) 'R U F L B D' - sage: C = RubiksCube("R2 D2") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R2 D2") + sage: solver.solve(C.facets()) 'R2 D2' """ self.ready() @@ -193,21 +194,22 @@ def solve(self, facets): """ EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: C = RubiksCube("R U") # optional - rubiks - sage: CubexSolver().solve(C.facets()) # optional - rubiks + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: C = RubiksCube("R U") + sage: CubexSolver().solve(C.facets()) 'R U' - sage: C = RubiksCube("R U F L B D") # optional - rubiks - sage: sol = CubexSolver().solve(C.facets()); sol # optional - rubiks + sage: C = RubiksCube("R U F L B D") + sage: sol = CubexSolver().solve(C.facets()); sol "U' L' L' U L U' L U D L L D' L' D L' D' L D L' U' L D' L' U L' B' U' L' U B L D L D' U' L' U L B L B' L' U L U' L' F' L' F L' F L F' L' D' L' D D L D' B L B' L B' L B F' L F F B' L F' B D' D' L D B' B' L' D' B U' U' L' B' D' F' F' L D F'" - sage: RubiksCube(sol) == C # optional - rubiks + sage: RubiksCube(sol) == C True - sage: C = RubiksCube("R2 F'") # optional - rubiks - sage: CubexSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R2 F'") + sage: CubexSolver().solve(C.facets()) "R' R' F'" - sage: C = RubiksCube().scramble() # optional - rubiks - sage: sol = CubexSolver().solve(C.facets()) # optional - rubiks - sage: C == RubiksCube(sol) # optional - rubiks + sage: C = RubiksCube().scramble() + sage: sol = CubexSolver().solve(C.facets()) + sage: C == RubiksCube(sol) True """ s = self.format_cube(facets) @@ -245,15 +247,16 @@ def solve(self, facets, timeout=10, extra_time=2): """ EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: C = RubiksCube().move("R U") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: C = RubiksCube().move("R U") + sage: DikSolver().solve(C.facets()) 'R U' - sage: C = RubiksCube().move("R U F L B D") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube().move("R U F L B D") + sage: DikSolver().solve(C.facets()) 'R U F L B D' - sage: C = RubiksCube().move("R2 F'") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube().move("R2 F'") + sage: DikSolver().solve(C.facets()) "R2 F'" """ cube_str = self.format_cube(facets) diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index 54c28f55598..b1fd5c1d983 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -15,60 +15,65 @@ EXAMPLES:: - sage: scilab.eval('2+2') # optional - scilab + sage: # optional - scilab + sage: scilab.eval('2+2') 'ans =\n \n 4.' - sage: scilab('2+2') # optional - scilab + sage: scilab('2+2') 4. - sage: a = scilab(10) # optional - scilab - sage: a**10 # optional - scilab + sage: a = scilab(10) + sage: a**10 1.000D+10 Tutorial based the MATLAB interface tutorial: EXAMPLES:: - sage: scilab('4+10') # optional - scilab + sage: # optional - scilab + sage: scilab('4+10') 14. - sage: scilab('date') # optional - scilab; random output + sage: scilab('date') 15-Feb-2010 - sage: scilab('5*10 + 6') # optional - scilab + sage: scilab('5*10 + 6') 56. - sage: scilab('(6+6)/3') # optional - scilab + sage: scilab('(6+6)/3') 4. - sage: scilab('9')^2 # optional - scilab + sage: scilab('9')^2 81. - sage: a = scilab(10); b = scilab(20); c = scilab(30) # optional - scilab - sage: avg = (a+b+c)/3 # optional - scilab - sage: avg # optional - scilab + sage: a = scilab(10); b = scilab(20); c = scilab(30) + sage: avg = (a+b+c)/3 + sage: avg 20. - sage: parent(avg) # optional - scilab + sage: parent(avg) Scilab - sage: my_scalar = scilab('3.1415') # optional - scilab - sage: my_scalar # optional - scilab + sage: # optional - scilab + sage: my_scalar = scilab('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = scilab('[1,5,7]') # optional - scilab - sage: my_vector1 # optional - scilab + sage: my_vector1 = scilab('[1,5,7]') + sage: my_vector1 1. 5. 7. - sage: my_vector2 = scilab('[1;5;7]') # optional - scilab - sage: my_vector2 # optional - scilab + sage: my_vector2 = scilab('[1;5;7]') + sage: my_vector2 1. 5. 7. - sage: my_vector1 * my_vector2 # optional - scilab + sage: my_vector1 * my_vector2 75. - sage: row_vector1 = scilab('[1 2 3]') # optional - scilab - sage: row_vector2 = scilab('[3 2 1]') # optional - scilab - sage: matrix_from_row_vec = scilab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) # optional - scilab - sage: matrix_from_row_vec # optional - scilab + sage: # optional - scilab + sage: row_vector1 = scilab('[1 2 3]') + sage: row_vector2 = scilab('[3 2 1]') + sage: matrix_from_row_vec = scilab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) + sage: matrix_from_row_vec 1. 2. 3. 3. 2. 1. - sage: column_vector1 = scilab('[1;3]') # optional - scilab - sage: column_vector2 = scilab('[2;8]') # optional - scilab - sage: matrix_from_col_vec = scilab('[%s %s]'%(column_vector1.name(), column_vector2.name())) # optional - scilab - sage: matrix_from_col_vec # optional - scilab + sage: # optional - scilab + sage: column_vector1 = scilab('[1;3]') + sage: column_vector2 = scilab('[2;8]') + sage: matrix_from_col_vec = scilab('[%s %s]'%(column_vector1.name(), column_vector2.name())) + sage: matrix_from_col_vec 1. 2. 3. 8. @@ -90,12 +95,13 @@ sage: tm # optional - scilab 0.5 2.5 4.5 6.5 8.5 - sage: my_vector1 = scilab('[1,5,7]') # optional - scilab - sage: my_vector1(1) # optional - scilab + sage: # optional - scilab + sage: my_vector1 = scilab('[1,5,7]') + sage: my_vector1(1) 1. - sage: my_vector1(2) # optional - scilab + sage: my_vector1(2) 5. - sage: my_vector1(3) # optional - scilab + sage: my_vector1(3) 7. Matrix indexing works as follows:: @@ -113,15 +119,16 @@ Setting using parenthesis cannot work (because of how the Python language works). Use square brackets or the set function:: - sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') # optional - scilab - sage: my_matrix.set(2,3, 1999) # optional - scilab - sage: my_matrix # optional - scilab + sage: # optional - scilab + sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') + sage: my_matrix.set(2,3, 1999) + sage: my_matrix 8. 12. 19. 7. 3. 1999. 12. 4. 23. 8. 1. 1. - sage: my_matrix[2,3] = -126 # optional - scilab - sage: my_matrix # optional - scilab + sage: my_matrix[2,3] = -126 + sage: my_matrix 8. 12. 19. 7. 3. - 126. 12. 4. 23. @@ -129,39 +136,40 @@ TESTS:: - sage: M = scilab(x) # optional - scilab + sage: # optional - scilab + sage: M = scilab(x) Traceback (most recent call last): ... TypeError: ..._interface_init_() takes exactly one argument (0 given) - sage: M = scilab(matrix(3,range(9))); M # optional - scilab + sage: M = scilab(matrix(3,range(9))); M 0. 1. 2. 3. 4. 5. 6. 7. 8. - sage: M(10) # optional - scilab + sage: M(10) Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M[10] # optional - scilab + sage: M[10] Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M(4,2) # optional - scilab + sage: M(4,2) Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M[2,4] # optional - scilab + sage: M[2,4] Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M(9) = x # optional - scilab + sage: M(9) = x Traceback (most recent call last): ... SyntaxError: can...t assign to function call (..., line 1) @@ -199,10 +207,11 @@ class Scilab(Expect): EXAMPLES:: - sage: a = scilab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') # optional - scilab - sage: b = scilab('[ 1; 3; 13]') # optional - scilab - sage: c = a * b # optional - scilab - sage: print(c) # optional - scilab + sage: # optional - scilab + sage: a = scilab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') + sage: b = scilab('[ 1; 3; 13]') + sage: c = a * b + sage: print(c) 30. 122. 505. @@ -433,12 +442,13 @@ def __getitem__(self, n): EXAMPLES:: - sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab - sage: M[1] # optional - scilab + sage: # optional - scilab + sage: M = scilab('[1,2,3;4,5,6;7,8,9]') + sage: M[1] 1. - sage: M[7] # optional - scilab + sage: M[7] 3. - sage: M[3,2] # optional - scilab + sage: M[3,2] 8. """ if isinstance(n, tuple): @@ -453,14 +463,15 @@ def __setitem__(self, n, value): EXAMPLES:: - sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab - sage: M[6] = 0 # optional - scilab - sage: M # optional - scilab + sage: # optional - scilab + sage: M = scilab('[1,2,3;4,5,6;7,8,9]') + sage: M[6] = 0 + sage: M 1. 2. 3. 4. 5. 6. 7. 0. 9. - sage: M[3,2] = 10 # optional - scilab - sage: M # optional - scilab + sage: M[3,2] = 10 + sage: M 1. 2. 3. 4. 5. 6. 7. 10. 9. @@ -477,12 +488,13 @@ def _matrix_(self, R): EXAMPLES:: - sage: A = scilab('[1,2;3,4]') # optional - scilab - sage: matrix(ZZ, A) # optional - scilab + sage: # optional - scilab + sage: A = scilab('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = scilab('[1,2;3,4.5]') # optional - scilab - sage: matrix(RR, A) # optional - scilab + sage: A = scilab('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] """ From 0bff9f67fb2edf548df86b5b2c3c8474be73c045 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 15:31:22 -0700 Subject: [PATCH 14/30] Fix # needs for sagemath-pari --- src/sage/interfaces/gp.py | 24 +++++++++++++----------- src/sage/interfaces/macaulay2.py | 8 -------- src/sage/interfaces/maple.py | 16 ---------------- 3 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 6e12504e829..cfea368fc02 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -789,26 +789,27 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def # needs sage.symbolic + sage: # needs sage.symbolic + sage: pi_def = gp(pi); pi_def 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() # needs sage.symbolic + sage: pi_def.precision() 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) # needs sage.symbolic - sage: new_prec = pi_150.precision(); new_prec # needs sage.symbolic + sage: pi_150 = gp.new_with_bits_prec(pi, 150) + sage: new_prec = pi_150.precision(); new_prec 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec # needs sage.symbolic + sage: old_prec = gp.set_precision(new_prec); old_prec 28 # 32-bit 38 # 64-bit - sage: pi_150 # needs sage.symbolic + sage: pi_150 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) # needs sage.symbolic + sage: gp.set_precision(old_prec) 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() # needs sage.symbolic + sage: gp.get_precision() 28 # 32-bit 38 # 64-bit """ @@ -957,11 +958,12 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z # needs sage.symbolic + sage: # needs sage.symbolic + sage: z = gp(SR(1+15*I)); z 1 + 15*I - sage: z._complex_mpfr_field_(CC) # needs sage.symbolic + sage: z._complex_mpfr_field_(CC) 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) # needs sage.symbolic + sage: CC(z) # CC(gp(1+15*I)) 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index e8a4d94d2dc..9b11f02a85f 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -496,11 +496,7 @@ def _contains(self, v1, v2): sage: 0 in a, 2 in a, 3 in a (True, True, False) sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') -<<<<<<< HEAD sage: 'x' in b, '"x"' in b # indirect doctest -======= - sage: 'x' in b, '"x"' in b ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) (False, True) """ return self.eval("%s#?%s" % (v2, v1)) == self._true_symbol() @@ -649,11 +645,7 @@ def cputime(self, t=None): sage: R = macaulay2("QQ[x,y]") sage: x,y = R.gens() sage: a = (x+y+1)^20 -<<<<<<< HEAD sage: macaulay2.cputime() # random -======= - sage: macaulay2.cputime() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.48393700000000001 """ _t = float(self.cpuTime()._sage_()) diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 1f4f209f127..7ba21a66cf6 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -605,20 +605,12 @@ def cputime(self, t=None): sage: # optional - maple sage: t = maple.cputime() -<<<<<<< HEAD sage: t # random -======= - sage: t ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.02 sage: x = maple('x') sage: maple.diff(x^2, x) 2*x -<<<<<<< HEAD sage: maple.cputime(t) # random -======= - sage: maple.cputime(t) ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.0 """ if t is None: @@ -818,11 +810,7 @@ def with_package(self, package): :: sage: # optional - maple -<<<<<<< HEAD sage: maple.quit() # reset maple -======= - sage: maple.quit() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) sage: maple('partition(10)') partition(10) sage: maple('bell(10)') @@ -959,11 +947,7 @@ def __hash__(self): sage: # optional - maple sage: m = maple('x^2+y^2') -<<<<<<< HEAD sage: m.__hash__() # random -======= - sage: m.__hash__() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 188724254834261060184983038723355865733 sage: hash(m) # random 5035731711831192733 From 20b960d3f1146954aee3d35eb2ccfd5b5364d67c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 23:46:22 -0700 Subject: [PATCH 15/30] Add # needs --- src/sage/interfaces/sympy_wrapper.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/interfaces/sympy_wrapper.py b/src/sage/interfaces/sympy_wrapper.py index 792d1eaee99..5ad6095a787 100644 --- a/src/sage/interfaces/sympy_wrapper.py +++ b/src/sage/interfaces/sympy_wrapper.py @@ -97,6 +97,7 @@ def is_finite_set(self): EXAMPLES:: + sage: # needs sage.graphs sage: W = WeylGroup(["A",1,1]) sage: sW = W._sympy_(); sW SageSet(Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)) @@ -112,6 +113,7 @@ def is_iterable(self): EXAMPLES:: + sage: # needs sage.graphs sage: W = WeylGroup(["A",1,1]) sage: sW = W._sympy_(); sW SageSet(Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)) @@ -168,6 +170,7 @@ def __len__(self): EXAMPLES:: + sage: # needs sage.graphs sage: sB3 = WeylGroup(["B", 3])._sympy_(); sB3 SageSet(Weyl Group of type ['B', 3] (as a matrix group acting on the ambient space)) sage: len(sB3) From cd3543c487bad25aeed09b1141d10a64cfcb3302 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 11:21:51 -0700 Subject: [PATCH 16/30] Update # needs --- src/sage/interfaces/gp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index cfea368fc02..4cff85207e2 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -887,6 +887,7 @@ def _sage_(self): :: + sage: # needs sage.modules sage: M = Matrix(ZZ,2,2,[1,2,3,4]); M [1 2] [3 4] From f4999b0d69f1f64d8974cbbf624398ae8409cdcd Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 26 Jun 2023 12:41:10 +0100 Subject: [PATCH 17/30] more distros for fricas --- build/pkgs/fricas/distros/debian.txt | 1 + build/pkgs/fricas/distros/freebsd.txt | 1 + build/pkgs/fricas/distros/gentoo.txt | 1 + build/pkgs/fricas/distros/opensuse.txt | 1 + 4 files changed, 4 insertions(+) create mode 100644 build/pkgs/fricas/distros/debian.txt create mode 100644 build/pkgs/fricas/distros/freebsd.txt create mode 100644 build/pkgs/fricas/distros/gentoo.txt create mode 100644 build/pkgs/fricas/distros/opensuse.txt diff --git a/build/pkgs/fricas/distros/debian.txt b/build/pkgs/fricas/distros/debian.txt new file mode 100644 index 00000000000..ab59e032f00 --- /dev/null +++ b/build/pkgs/fricas/distros/debian.txt @@ -0,0 +1 @@ +fricas diff --git a/build/pkgs/fricas/distros/freebsd.txt b/build/pkgs/fricas/distros/freebsd.txt new file mode 100644 index 00000000000..75e565427a2 --- /dev/null +++ b/build/pkgs/fricas/distros/freebsd.txt @@ -0,0 +1 @@ +math/fricas diff --git a/build/pkgs/fricas/distros/gentoo.txt b/build/pkgs/fricas/distros/gentoo.txt new file mode 100644 index 00000000000..ce3f503e6db --- /dev/null +++ b/build/pkgs/fricas/distros/gentoo.txt @@ -0,0 +1 @@ +sci-mathematics/fricas[sbcl] diff --git a/build/pkgs/fricas/distros/opensuse.txt b/build/pkgs/fricas/distros/opensuse.txt new file mode 100644 index 00000000000..ab59e032f00 --- /dev/null +++ b/build/pkgs/fricas/distros/opensuse.txt @@ -0,0 +1 @@ +fricas From 21ab2c7e083308736386ddf302e7618f8c623a57 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 26 Jun 2023 16:48:23 +0100 Subject: [PATCH 18/30] spkg-configure for fricas --- build/pkgs/fricas/spkg-configure.m4 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 build/pkgs/fricas/spkg-configure.m4 diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 new file mode 100644 index 00000000000..0c26e9ab71a --- /dev/null +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -0,0 +1,17 @@ +SAGE_SPKG_CONFIGURE( + [fricas], [ + AC_CACHE_CHECK([for FriCAS >= 1.3.8], [ac_cv_path_FRICAS], [ + AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ + fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ + | $SED -n -e 's/.* Version: FriCAS //p'` + echo "$fricas_version" + AS_IF([test -n "$fricas_version"], [ + AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ + ac_cv_path_FRICAS="$ac_path_FRICAS" + ac_path_FRICAS_found=: + ]) + ]) + ]) + ]) + AS_IF([test -z "$ac_cv_path_FRICAS"], [sage_spkg_install_fricas=yes]) +]) From 467eff91d7d826c722069fc0b50be73dba33794a Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 27 Jun 2023 12:59:31 +0100 Subject: [PATCH 19/30] remove debugging echo --- build/pkgs/fricas/spkg-configure.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 index 0c26e9ab71a..2eaf39af158 100644 --- a/build/pkgs/fricas/spkg-configure.m4 +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -4,7 +4,6 @@ SAGE_SPKG_CONFIGURE( AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ | $SED -n -e 's/.* Version: FriCAS //p'` - echo "$fricas_version" AS_IF([test -n "$fricas_version"], [ AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ ac_cv_path_FRICAS="$ac_path_FRICAS" From 6ed8cb040b47344dcbe1a2a5eb19426142299952 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 30 Jun 2023 10:48:50 +0100 Subject: [PATCH 20/30] do not insist on sbcl --- build/pkgs/fricas/distros/gentoo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/fricas/distros/gentoo.txt b/build/pkgs/fricas/distros/gentoo.txt index ce3f503e6db..e6cab7611fc 100644 --- a/build/pkgs/fricas/distros/gentoo.txt +++ b/build/pkgs/fricas/distros/gentoo.txt @@ -1 +1 @@ -sci-mathematics/fricas[sbcl] +sci-mathematics/fricas From 2fd6098f974393c7cacfe4f7ba3f2067703e05ed Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 30 Jun 2023 16:20:19 +0100 Subject: [PATCH 21/30] modify the way to send )quit to fricas This is needed as SBCL-built FriCAS does not output anything if )quit is passed via -eval option, as opposed to ECL-built FriCAS. --- build/pkgs/fricas/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 index 2eaf39af158..905859f6a95 100644 --- a/build/pkgs/fricas/spkg-configure.m4 +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -2,7 +2,7 @@ SAGE_SPKG_CONFIGURE( [fricas], [ AC_CACHE_CHECK([for FriCAS >= 1.3.8], [ac_cv_path_FRICAS], [ AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ - fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ + fricas_version=`echo ")quit" | $ac_path_FRICAS -nox -noclef | grep Version | tail -1 2>&1 \ | $SED -n -e 's/.* Version: FriCAS //p'` AS_IF([test -n "$fricas_version"], [ AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ From ba633413ef0d40e52a63ab1cb52c98f75896a581 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 1 Jul 2023 17:52:07 +0100 Subject: [PATCH 22/30] updated design of feature --- src/sage/features/fricas.py | 65 +++++++++++++++++++++++++++++++++++ src/sage/interfaces/fricas.py | 10 ++++-- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/sage/features/fricas.py diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py new file mode 100644 index 00000000000..0d22073ae73 --- /dev/null +++ b/src/sage/features/fricas.py @@ -0,0 +1,65 @@ +r""" +Features for testing the presence of ``fricas`` +""" + +# ***************************************************************************** +# Copyright (C) 2023 Dima Pasechnik +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# https://www.gnu.org/licenses/ +# ***************************************************************************** + +import os +import subprocess +from . import Executable, FeatureTestResult + +class FriCAS(Executable): + r""" + A :class:`~sage.features.Feature` which checks for the :ref:`fricas ` binary. + + EXAMPLES:: + + sage: from sage.features.fricas import FriCAS + sage: FriCAS().is_present() # optional - fricas + FeatureTestResult('fricas', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.fricas import FriCAS + sage: isinstance(FriCAS(), FriCAS) + True + """ + Executable.__init__(self, name="fricas", spkg="fricas", + executable="fricas", + url="https://fricas.github.io") + + def is_functional(self): + r""" + Check whether ``fricas`` works on trivial input. + + EXAMPLES:: + + sage: from sage.features.fricas import FriCAS + sage: FriCAS().is_functional() # optional - fricas + FeatureTestResult('fricas', True) + """ + command = ['fricas -nosman -eval ")quit"'] + try: + lines = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError as e: + return FeatureTestResult(self, False, + reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e)) + + expected = b"Checking" + if lines.find(expected) == -1: + return FeatureTestResult(self, False, + reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected)) + + return FeatureTestResult(self, True) + +def all_features(): + return [FriCAS()] diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index c19feb3a7e5..10384b496b1 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -264,9 +264,9 @@ class FriCAS(ExtraTabCompletion, Expect): """ Interface to a FriCAS interpreter. """ - def __init__(self, name='fricas', command='fricas -nosman', + def __init__(self, name='fricas', command=None, script_subdirectory=None, logfile=None, - server=None, server_tmpdir=None): + server=None, server_tmpdir=None, options=""): """ Create an instance of the FriCAS interpreter. @@ -289,6 +289,12 @@ def __init__(self, name='fricas', command='fricas -nosman', sage: fricas(I*x).sage() # optional - fricas I*x """ + from sage.features.fricas import FriCAS + FriCAS().require() + options =" -nosman" + options + import shlex + command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) + eval_using_file_cutoff = 4096 - 5 # magic number from Expect._eval_line (there might be a bug) assert max(len(c) for c in FRICAS_INIT_CODE) < eval_using_file_cutoff self.__eval_using_file_cutoff = eval_using_file_cutoff From 77b1e7ace17892843df4644be9ebe99be89a1699 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 1 Jul 2023 22:45:10 +0100 Subject: [PATCH 23/30] better string to match (for various lisps) --- src/sage/features/fricas.py | 2 +- src/sage/interfaces/fricas.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py index 0d22073ae73..a52e082d114 100644 --- a/src/sage/features/fricas.py +++ b/src/sage/features/fricas.py @@ -54,7 +54,7 @@ def is_functional(self): return FeatureTestResult(self, False, reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e)) - expected = b"Checking" + expected = b"FriCAS" if lines.find(expected) == -1: return FeatureTestResult(self, False, reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected)) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 10384b496b1..f568dd6e53f 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -291,7 +291,7 @@ def __init__(self, name='fricas', command=None, """ from sage.features.fricas import FriCAS FriCAS().require() - options =" -nosman" + options + options ="-nosman" + options import shlex command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) From 43c85c8381881f9c4cbb52d36c49ba06890921e9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 13:59:51 -0800 Subject: [PATCH 24/30] src/sage/interfaces/fricas.py: Use file-level doctest tag --- src/sage/interfaces/fricas.py | 354 +++++++++++++++++----------------- 1 file changed, 172 insertions(+), 182 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index f568dd6e53f..ab03a7e0b19 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - fricas r""" Interface to FriCAS @@ -21,62 +22,62 @@ EXAMPLES:: - sage: fricas('3 * 5') # optional - fricas + sage: fricas('3 * 5') 15 - sage: a = fricas(3) * fricas(5); a # optional - fricas + sage: a = fricas(3) * fricas(5); a 15 The type of a is :class:`FriCASElement`, i.e., an element of the FriCAS interpreter:: - sage: type(a) # optional - fricas + sage: type(a) - sage: a.parent() # optional - fricas + sage: a.parent() FriCAS The underlying FriCAS type of a is also available, via the type method:: - sage: a.typeOf() # optional - fricas + sage: a.typeOf() PositiveInteger FriCAS objects are normally displayed using "ASCII art":: - sage: fricas(2/3) # optional - fricas + sage: fricas(2/3) 2 - 3 - sage: fricas('x^2 + 3/7') # optional - fricas + sage: fricas('x^2 + 3/7') 2 3 x + - 7 Functions defined in FriCAS are available as methods of the :class:`fricas` object:: - sage: F = fricas.factor('x^5 - y^5'); F # optional - fricas + sage: F = fricas.factor('x^5 - y^5'); F 4 3 2 2 3 4 - (y - x)(y + x y + x y + x y + x ) - sage: type(F) # optional - fricas + sage: type(F) - sage: F.typeOf() # optional - fricas + sage: F.typeOf() Factored(Polynomial(Integer)) We can also create a FriCAS polynomial and apply the function ``factor`` from FriCAS. The notation ``f.factor()`` is consistent with how the rest of SageMath works:: - sage: f = fricas('x^5 - y^5') # optional - fricas - sage: f^2 # optional - fricas + sage: f = fricas('x^5 - y^5') + sage: f^2 10 5 5 10 y - 2 x y + x - sage: f.factor() # optional - fricas + sage: f.factor() 4 3 2 2 3 4 - (y - x)(y + x y + x y + x y + x ) For many FriCAS types, translation to an appropriate SageMath type is available:: - sage: f.factor().sage() # optional - fricas + sage: f.factor().sage() (y - x) * (y^4 + y^3*x + y^2*x^2 + y*x^3 + x^4) Control-C interruption works well with the FriCAS interface. For @@ -92,7 +93,7 @@ differential equation for the generating function for integer partitions:: - sage: fricas("guessADE([partition n for n in 0..40], homogeneous==4)") # optional - fricas + sage: fricas("guessADE([partition n for n in 0..40], homogeneous==4)") [ [ n @@ -121,9 +122,9 @@ FriCAS can solve linear ordinary differential equations:: - sage: fricas.set("y", "operator y") # optional - fricas - sage: fricas.set("deq", "x^3*D(y x, x, 3) + x^2*D(y x, x, 2) - 2*x*D(y x, x) + 2*y x - 2*x^4") # optional - fricas - sage: fricas.set("sol", "solve(deq, y, x)"); fricas("sol") # optional - fricas + sage: fricas.set("y", "operator y") + sage: fricas.set("deq", "x^3*D(y x, x, 3) + x^2*D(y x, x, 2) - 2*x*D(y x, x) + 2*y x - 2*x^4") + sage: fricas.set("sol", "solve(deq, y, x)"); fricas("sol") 5 3 2 x - 10 x + 20 x + 4 [particular = ----------------------, @@ -133,36 +134,36 @@ basis = [---------------, ------, -------------]] x x x - sage: fricas("sol.particular").sage() # optional - fricas + sage: fricas("sol.particular").sage() 1/15*(x^5 - 10*x^3 + 20*x^2 + 4)/x - sage: fricas("sol.basis").sage() # optional - fricas + sage: fricas("sol.basis").sage() [(2*x^3 - 3*x^2 + 1)/x, (x^3 - 1)/x, (x^3 - 3*x^2 - 1)/x] - sage: fricas.eval(")clear values y deq sol") # optional - fricas + sage: fricas.eval(")clear values y deq sol") '' FriCAS can expand expressions into series:: - sage: x = var('x'); ex = sqrt(cos(x)); a = fricas(ex).series(x=0); a # optional - fricas + sage: x = var('x'); ex = sqrt(cos(x)); a = fricas(ex).series(x=0); a 1 2 1 4 19 6 559 8 29161 10 11 1 - - x - -- x - ---- x - ------ x - --------- x + O(x ) 4 96 5760 645120 116121600 - sage: a.coefficients()[38].sage() # optional - fricas + sage: a.coefficients()[38].sage() -29472026335337227150423659490832640468979/274214482066329363682430667508979749984665600000000 - sage: ex = sqrt(atan(x)); a = fricas(ex).series(x=0); a # optional - fricas + sage: ex = sqrt(atan(x)); a = fricas(ex).series(x=0); a 1 5 9 - - - 2 1 2 31 2 6 x - - x + --- x + O(x ) 6 360 - sage: a.coefficient(9/2).sage() # optional - fricas + sage: a.coefficient(9/2).sage() 31/360 - sage: x = fricas("x::TaylorSeries Fraction Integer") # optional - fricas - sage: y = fricas("y::TaylorSeries Fraction Integer") # optional - fricas - sage: 2*(1+2*x+sqrt(1-4*x)-2*x*y).recip() # optional - fricas + sage: x = fricas("x::TaylorSeries Fraction Integer") + sage: y = fricas("y::TaylorSeries Fraction Integer") + sage: 2*(1+2*x+sqrt(1-4*x)-2*x*y).recip() 2 3 2 2 3 4 4 5 1 + (x y + x ) + 2 x + (x y + 2 x y + 6 x ) + (4 x y + 18 x ) + @@ -180,7 +181,7 @@ FriCAS does some limits right:: - sage: x = var('x'); ex = x^2*exp(-x)*Ei(x) - x; fricas(ex).limit(x=oo) # optional - fricas + sage: x = var('x'); ex = x^2*exp(-x)*Ei(x) - x; fricas(ex).limit(x=oo) 1 """ @@ -272,21 +273,21 @@ def __init__(self, name='fricas', command=None, TESTS:: - sage: fricas == loads(dumps(fricas)) # optional - fricas + sage: fricas == loads(dumps(fricas)) True Check that :trac:`25174` is fixed:: - sage: fricas(I) # optional - fricas + sage: fricas(I) %i - sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm="fricas") # optional - fricas + sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm="fricas") 1/2*I*pi - sage: fricas(I*sin(x)).sage() # optional - fricas + sage: fricas(I*sin(x)).sage() I*sin(x) - sage: fricas(I*x).sage() # optional - fricas + sage: fricas(I*x).sage() I*x """ from sage.features.fricas import FriCAS @@ -319,7 +320,6 @@ def _start(self): EXAMPLES:: - sage: # optional - fricas sage: a = FriCAS() sage: a.is_running() False @@ -363,7 +363,6 @@ def _quit_string(self): EXAMPLES:: - sage: # optional - fricas sage: fricas._quit_string() ')quit' sage: a = FriCAS() @@ -380,9 +379,9 @@ def _quit_string(self): Ensure that a new process is started after ``quit()``:: - sage: p = fricas.pid() # optional - fricas - sage: fricas.quit() # optional - fricas - sage: fricas.pid() == p # optional - fricas + sage: p = fricas.pid() + sage: fricas.quit() + sage: fricas.pid() == p False """ @@ -395,7 +394,6 @@ def _commands(self): EXAMPLES:: - sage: # optional - fricas sage: cmds = fricas._commands() sage: len(cmds) > 100 True @@ -417,7 +415,6 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: # optional - fricas sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) sage: len(c) > 100 True @@ -479,7 +476,7 @@ def _read_in_file_command(self, filename): Evaluate a rather long line:: - sage: len(fricas([i for i in range(600)])) # optional - fricas, indirect doctest + sage: len(fricas([i for i in range(600)])) # indirect doctest 600 """ @@ -531,7 +528,7 @@ def _check_errors(self, line, output): TESTS:: - sage: fricas.set("x", "[i fo83r i in 0..17]") # optional - fricas, indirect doctest + sage: fricas.set("x", "[i fo83r i in 0..17]") # indirect doctest Traceback (most recent call last): ... RuntimeError: An error occurred when FriCAS evaluated '[i fo83r i in 0..17]': @@ -542,7 +539,7 @@ def _check_errors(self, line, output): Error B: Possibly missing a ] 3 error(s) parsing - sage: fricas.set("x", "something stupid") # optional - fricas, indirect doctest + sage: fricas.set("x", "something stupid") # indirect doctest Traceback (most recent call last): ... RuntimeError: An error occurred when FriCAS evaluated 'something stupid': @@ -668,8 +665,8 @@ def set(self, var, value): EXAMPLES:: - sage: fricas.set('xx', '2') # optional - fricas - sage: fricas.get('xx') # optional - fricas + sage: fricas.set('xx', '2') + sage: fricas.get('xx') '2' """ @@ -686,7 +683,6 @@ def get(self, var): EXAMPLES:: - sage: # optional - fricas sage: fricas.set('xx', '2') sage: fricas.get('xx') '2' @@ -721,25 +717,24 @@ def get_string(self, var): We test that strings are returned properly:: - sage: r = fricas.get_string('concat([concat(string(i)," ") for i in 0..299])') # optional - fricas - sage: r == " ".join(str(i) for i in range(300)) + ' ' # optional - fricas + sage: r = fricas.get_string('concat([concat(string(i)," ") for i in 0..299])') + sage: r == " ".join(str(i) for i in range(300)) + ' ' True - sage: fricas.get_string('concat([string(1) for i in 1..5])') == "1"*5 # optional - fricas + sage: fricas.get_string('concat([string(1) for i in 1..5])') == "1"*5 True - sage: fricas.get_string('concat([string(1) for i in 1..10000])') == "1"*10000 # optional - fricas + sage: fricas.get_string('concat([string(1) for i in 1..10000])') == "1"*10000 True A problem with leading space:: sage: s = "unparse((-1234567890123456789012345678901234567890123456789012345678901234567890*n::EXPR INT)::INFORM)" - sage: fricas.get_string(s) # optional - fricas + sage: fricas.get_string(s) '(-1234567890123456789012345678901234567890123456789012345678901234567890)*n' Check that :trac:`25628` is fixed:: - sage: # optional - fricas sage: var("a b"); f = 1/(1+a*cos(x)) (a, b) sage: lF = integrate(f, x, algorithm="fricas") @@ -768,7 +763,7 @@ def get_integer(self, var): TESTS:: - sage: fricas.get_integer('factorial 1111') == factorial(1111) # optional - fricas + sage: fricas.get_integer('factorial 1111') == factorial(1111) True """ @@ -781,10 +776,10 @@ def get_boolean(self, var): TESTS:: - sage: fricas.get_boolean('(1=1)::Boolean') == True # optional - fricas + sage: fricas.get_boolean('(1=1)::Boolean') == True True - sage: fricas.get_boolean('(1=2)::Boolean') == False # optional - fricas + sage: fricas.get_boolean('(1=2)::Boolean') == False True """ return self.get(str(var)).replace("\n", "") == "true" @@ -805,7 +800,7 @@ def get_unparsed_InputForm(self, var): TESTS:: - sage: fricas.get_unparsed_InputForm('1..3') # optional - fricas + sage: fricas.get_unparsed_InputForm('1..3') '(1..3)$Segment(PositiveInteger())' """ @@ -817,7 +812,7 @@ def get_InputForm(self, var): TESTS:: - sage: fricas.get_InputForm('1..3') # optional - fricas + sage: fricas.get_InputForm('1..3') '(($elt (Segment (PositiveInteger)) SEGMENT) 1 3)' """ @@ -829,10 +824,10 @@ def _assign_symbol(self): EXAMPLES:: - sage: fricas.set("x", "1"); # optional - fricas, indirect doctest - sage: fricas.get("x") # optional - fricas + sage: fricas.set("x", "1"); # indirect doctest + sage: fricas.get("x") '1' - sage: fricas.eval(")cl val x") # optional - fricas + sage: fricas.eval(")cl val x") '' """ return ":=" @@ -843,15 +838,15 @@ def _equality_symbol(self): EXAMPLES:: - sage: a = fricas(x==6); a # optional - fricas, indirect doctest + sage: a = fricas(x==6); a # indirect doctest x = 6 A warning:: - sage: fricas.set("x", 2); # optional - fricas - sage: a = fricas(x==6); a # optional - fricas + sage: fricas.set("x", 2); + sage: a = fricas(x==6); a 2 = 6 - sage: fricas.eval(")cl val x") # optional - fricas + sage: fricas.eval(")cl val x") '' """ return "=" @@ -862,7 +857,7 @@ def _true_symbol(self): EXAMPLES:: - sage: str(fricas("(1=1)@Boolean")) == fricas._true_symbol() # optional - fricas + sage: str(fricas("(1=1)@Boolean")) == fricas._true_symbol() True """ return "true" @@ -873,7 +868,7 @@ def _false_symbol(self): EXAMPLES:: - sage: str(fricas("(1~=1)@Boolean")) == fricas._false_symbol() # optional - fricas + sage: str(fricas("(1~=1)@Boolean")) == fricas._false_symbol() True """ return "false" @@ -884,7 +879,7 @@ def _inequality_symbol(self): EXAMPLES:: - sage: fricas(x!=0) # optional - fricas, indirect doctest + sage: fricas(x!=0) # indirect doctest true """ return '~=' @@ -893,7 +888,7 @@ def _repr_(self): """ EXAMPLES:: - sage: fricas # indirect doctest + sage: fricas # indirect doctest FriCAS """ return "FriCAS" @@ -926,11 +921,11 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= EXAMPLES:: - sage: fricas.set("x", "1783"); fricas("x") # optional - fricas + sage: fricas.set("x", "1783"); fricas("x") 1783 - sage: fricas.eval(")cl val x"); # optional - fricas + sage: fricas.eval(")cl val x"); '' - sage: fricas("x") # optional - fricas + sage: fricas("x") x """ @@ -958,9 +953,9 @@ def _function_class(self): EXAMPLES:: - sage: fricas._function_class() # optional - fricas + sage: fricas._function_class() - sage: type(fricas.gcd) # optional - fricas + sage: type(fricas.gcd) """ return FriCASExpectFunction @@ -969,9 +964,9 @@ def _object_class(self): """ EXAMPLES:: - sage: fricas._object_class() # optional - fricas + sage: fricas._object_class() - sage: type(fricas(2)) # optional - fricas + sage: type(fricas(2)) """ return FriCASElement @@ -982,9 +977,9 @@ def _function_element_class(self): EXAMPLES:: - sage: fricas._function_element_class() # optional - fricas + sage: fricas._function_element_class() - sage: type(fricas(2).gcd) # optional - fricas + sage: type(fricas(2).gcd) """ return FriCASFunctionElement @@ -1024,16 +1019,16 @@ def __len__(self): EXAMPLES:: - sage: v = fricas('[x^i for i in 0..5]') # optional - fricas - sage: len(v) # optional - fricas + sage: v = fricas('[x^i for i in 0..5]') + sage: len(v) 6 TESTS: Streams are not handled yet:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas - sage: len(oh) # optional - fricas + sage: oh = fricas('[i for i in 1..]') + sage: len(oh) Traceback (most recent call last): ... TypeError: ... @@ -1048,15 +1043,15 @@ def __iter__(self): EXAMPLES:: - sage: L = fricas([4,5,6]) # optional - fricas - sage: list(L) # optional - fricas + sage: L = fricas([4,5,6]) + sage: list(L) [4, 5, 6] TESTS: Streams are not handled yet:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas + sage: oh = fricas('[i for i in 1..]') sage: next(iter(oh)) # known bug """ for i in range(len(self)): @@ -1071,20 +1066,20 @@ def __getitem__(self, n): TESTS:: - sage: fricas("[1,2,3]")[0] # optional - fricas + sage: fricas("[1,2,3]")[0] 1 Negative indices do work:: - sage: fricas("[1,2,3]")[-1] # optional - fricas + sage: fricas("[1,2,3]")[-1] 3 - sage: fricas("[1,2,3]")[-2] # optional - fricas + sage: fricas("[1,2,3]")[-2] 2 Invalid indices raise exceptions:: - sage: fricas("[1,2,3]")[3] # optional - fricas + sage: fricas("[1,2,3]")[3] Traceback (most recent call last): ... TypeError: An error occurred when FriCAS evaluated 'elt(...,...)': @@ -1094,8 +1089,8 @@ def __getitem__(self, n): And streams are ok too:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas - sage: oh[4] # optional - fricas + sage: oh = fricas('[i for i in 1..]') + sage: oh[4] 5 """ n = int(n) @@ -1119,7 +1114,7 @@ def __int__(self): """ TESTS:: - sage: int(fricas(2)) # optional - fricas + sage: int(fricas(2)) 2 """ return int(self.sage()) @@ -1130,9 +1125,9 @@ def bool(self): EXAMPLES:: - sage: fricas("1=1").bool() # optional - fricas + sage: fricas("1=1").bool() True - sage: fricas("1~=1").bool() # optional - fricas + sage: fricas("1~=1").bool() False """ P = self._check_valid() @@ -1144,7 +1139,7 @@ def __bool__(self): EXAMPLES:: - sage: fricas(0).is_zero() # optional - fricas, indirect doctest + sage: fricas(0).is_zero() # indirect doctest True """ P = self._check_valid() @@ -1154,7 +1149,7 @@ def __float__(self): """ TESTS:: - sage: float(fricas(2)) # optional - fricas + sage: float(fricas(2)) 2.0 """ return float(self.sage()) @@ -1163,7 +1158,7 @@ def _integer_(self, ZZ=None): """ EXAMPLES:: - sage: ZZ(fricas('1')) # optional - fricas + sage: ZZ(fricas('1')) 1 """ return ZZ(self.sage()) @@ -1172,7 +1167,7 @@ def _rational_(self): """ EXAMPLES:: - sage: QQ(fricas('-1/2')) # optional - fricas + sage: QQ(fricas('-1/2')) -1/2 """ return QQ(self.sage()) @@ -1187,13 +1182,13 @@ def _latex_(self): r""" EXAMPLES:: - sage: latex(fricas("sin(x+y)/exp(z)*log(1+%e)")) # optional - fricas + sage: latex(fricas("sin(x+y)/exp(z)*log(1+%e)")) \frac{{{\log \left( {{e+1}} \right)} \ {\sin \left( {{y+x}} \right)}}}{{{e} ^{z}}} - sage: latex(fricas("matrix([[1,2],[3,4]])")) # optional - fricas + sage: latex(fricas("matrix([[1,2],[3,4]])")) \left[ \begin{array}{cc} 1 & 2 \\ 3 & 4\end{array} \right] - sage: latex(fricas("integrate(sin(x+1/x),x)")) # optional - fricas + sage: latex(fricas("integrate(sin(x+1/x),x)")) \int ^{\displaystyle x} {{\sin \left( {{\frac{{{{ \%...} ^{2}}+1}}{ \%...}}} \right)} \ {d \%...}} """ replacements = [(r'\sp ', '^'), @@ -1218,14 +1213,14 @@ def _get_sage_type(self, domain): EXAMPLES:: - sage: m = fricas("dom(1/2)::Any") # optional - fricas - sage: fricas(0)._get_sage_type(m) # optional - fricas + sage: m = fricas("dom(1/2)::Any") + sage: fricas(0)._get_sage_type(m) Rational Field TESTS:: - sage: m = fricas("UP(y, UP(x, AN))::INFORM") # optional - fricas - sage: fricas(0)._get_sage_type(m) # optional - fricas + sage: m = fricas("UP(y, UP(x, AN))::INFORM") + sage: fricas(0)._get_sage_type(m) Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Algebraic Field """ from sage.rings.qqbar import QQbar @@ -1309,7 +1304,7 @@ def _parse_and_eval(s, start=0): sage: FriCASElement._parse_and_eval("(asin c)") (arcsin(c), 7) - sage: N(FriCASElement._parse_and_eval("(pi)")[0]) # optional - fricas + sage: N(FriCASElement._parse_and_eval("(pi)")[0]) 3.14159265358979 sage: FriCASElement._parse_and_eval('(a "(b c)")') @@ -1413,7 +1408,7 @@ def _parse_other(s, start=0, make_fun=False): sage: var("D") D - sage: integrate(D/x, x, algorithm="fricas") # optional - fricas + sage: integrate(D/x, x, algorithm="fricas") D*log(x) However, it does have to check for constants, for example @@ -1503,7 +1498,7 @@ def _sage_expression(fricas_InputForm): TESTS:: - sage: f = fricas('integrate(sin(x^2), x)'); f # optional - fricas + sage: f = fricas('integrate(sin(x^2), x)'); f +---+ | 2 fresnelS(x |--- ) @@ -1513,16 +1508,16 @@ def _sage_expression(fricas_InputForm): | 2 |--- \|%pi - sage: s = fricas.get_InputForm(f._name); s # optional - fricas + sage: s = fricas.get_InputForm(f._name); s '(/ (fresnelS (* x (^ (/ 2 (pi)) (/ 1 2)))) (^ (/ 2 (pi)) (/ 1 2)))' sage: from sage.interfaces.fricas import FriCASElement - sage: FriCASElement._sage_expression(s) # optional - fricas + sage: FriCASElement._sage_expression(s) 1/2*sqrt(2)*sqrt(pi)*fresnel_sin(sqrt(2)*x/sqrt(pi)) Check that :trac:`22525` is fixed:: sage: l = [sin, cos, sec, csc, cot, tan, asin, acos, atan, acot, acsc, asec, arcsin, arccos, arctan, arccot, arccsc, arcsec] - sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] # optional - fricas + sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] [0.783326909627483, 0.621609968270664, 1.60872581046605, @@ -1542,7 +1537,7 @@ def _sage_expression(fricas_InputForm): 1.57079632679490 - 0.467145308103262*I, 0.467145308103262*I] sage: l = [tanh, sinh, cosh, coth, sech, csch, asinh, acosh, atanh, acoth, asech, acsch, arcsinh, arccosh, arctanh, arccoth, arcsech, arccsch] - sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] # optional - fricas + sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] [0.716297870199024, 1.02651672570818, 1.43308638544877, @@ -1565,67 +1560,66 @@ def _sage_expression(fricas_InputForm): Check that :trac:`23782` is fixed:: sage: s = '((3*n^10-25*n^9+50*n^8+62*n^7-229*n^6-25*n^5+320*n^4-12*n^3-144*n^2)/11520)::EXPR INT' - sage: fricas(s).sage() # optional - fricas + sage: fricas(s).sage() 1/3840*n^10 - 5/2304*n^9 + 5/1152*n^8 + 31/5760*n^7 - 229/11520*n^6 - 5/2304*n^5 + 1/36*n^4 - 1/960*n^3 - 1/80*n^2 Some checks for digamma and polygamma (:trac:`31853`):: - sage: fricas.digamma(1.0) # optional - fricas + sage: fricas.digamma(1.0) - 0.5772156649_0153286061 sage: psi(1.0) -0.577215664901533 - sage: fricas.polygamma(1, 1.0) # optional - fricas + sage: fricas.polygamma(1, 1.0) 1.644934066848226... sage: psi(1, 1).n() 1.64493406684823 sage: var("w") w - sage: fricas.laplace(log(x), x, w).sage() # optional - fricas + sage: fricas.laplace(log(x), x, w).sage() -(euler_gamma + log(w))/w - sage: fricas(laplace(log(x), x, w)).sage() # optional - fricas + sage: fricas(laplace(log(x), x, w)).sage() -(euler_gamma + log(w))/w Check that :trac:`25224` is fixed:: - sage: integrate(log(x)/(1-x),x,algorithm='fricas') # optional - fricas + sage: integrate(log(x)/(1-x),x,algorithm='fricas') dilog(-x + 1) - sage: fricas(dilog(-x + 1)) # optional - fricas + sage: fricas(dilog(-x + 1)) dilog(x) - sage: dilog._fricas_()(1.0) # optional - fricas + sage: dilog._fricas_()(1.0) 1.6449340668_4822643647_24152 sage: dilog(1.0) 1.64493406684823 Check that :trac:`25987` is fixed:: - sage: integrate(lambert_w(x), x, algorithm="fricas") # optional - fricas + sage: integrate(lambert_w(x), x, algorithm="fricas") (x*lambert_w(x)^2 - x*lambert_w(x) + x)/lambert_w(x) Check that :trac:`25838` is fixed:: sage: F = function('f'); f = SR.var('f') - sage: FF = fricas(F(f)); FF # optional - fricas + sage: FF = fricas(F(f)); FF f(f) - sage: FF.D(f).sage() # optional - fricas + sage: FF.D(f).sage() diff(f(f), f) - sage: bool(FF.D(f).integrate(f).sage() == F(f)) # optional - fricas + sage: bool(FF.D(f).integrate(f).sage() == F(f)) True Check that :trac:`25602` is fixed:: - sage: r = fricas.integrate(72000/(1+x^5),x).sage() # optional - fricas - sage: n(r.subs(x=5)-r.subs(x=3)) # optional - fricas tol 0.1 + sage: r = fricas.integrate(72000/(1+x^5), x).sage() + sage: n(r.subs(x=5) - r.subs(x=3)) # tol 0.1 193.020947266210 - sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5),x).sage() # optional - fricas + sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5), x).sage() a - sage: n(r.subs(a=1, x=5)-r.subs(a=1, x=3)) # optional - fricas tol 0.1 + sage: n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) # tol 0.1 193.020947266268 - 8.73114913702011e-11*I Check conversions of sums and products:: - sage: # optional - fricas sage: var("k, m, n") (k, m, n) sage: fricas("sum(1/factorial(k), k=1..n)").sage() @@ -1635,7 +1629,7 @@ def _sage_expression(fricas_InputForm): sage: fricas("product(1/factorial(k), k=1..n)").sage() 1/product(factorial(_...), _..., 1, n) - sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f # optional - fricas + sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f n - 1 --+ 1 > ------- @@ -1643,10 +1637,10 @@ def _sage_expression(fricas_InputForm): s = 0 10 10 - sage: f.sage() # optional - fricas + sage: f.sage() harmonic_number(n) - sage: f = fricas.guess([0, 1, 3, 9, 33])[0]; f # optional - fricas + sage: f = fricas.guess([0, 1, 3, 9, 33])[0]; f s - 1 n - 1 5 --+ ++-++ @@ -1655,53 +1649,53 @@ def _sage_expression(fricas_InputForm): s = 0 p = 0 5 4 - sage: f.sage() # optional - fricas + sage: f.sage() sum(factorial(_... + 1), _..., 0, n - 1) Check that :trac:`26746` is fixed:: sage: _ = var('x, y, z') sage: f = sin(x^2) + y^z - sage: f.integrate(x, algorithm='fricas') # optional - fricas + sage: f.integrate(x, algorithm='fricas') 1/2*sqrt(2)*sqrt(pi)*(sqrt(2)*x*y^z/sqrt(pi) + fresnel_sin(sqrt(2)*x/sqrt(pi))) - sage: fricas(fresnel_sin(1)) # optional - fricas + sage: fricas(fresnel_sin(1)) fresnelS(1) - sage: fricas("fresnelS(1.0)") # optional - fricas + sage: fricas("fresnelS(1.0)") 0.4382591473_9035476607_676 - sage: fricas(fresnel_cos(1)) # optional - fricas + sage: fricas(fresnel_cos(1)) fresnelC(1) - sage: fricas("fresnelC(1.0)") # optional - fricas + sage: fricas("fresnelC(1.0)") 0.7798934003_7682282947_42 Check that :trac:`17908` is fixed:: - sage: fricas(abs(x)).sage().subs(x=-1783) # optional - fricas + sage: fricas(abs(x)).sage().subs(x=-1783) 1783 Check that :trac:`27310` is fixed:: - sage: fricas.set("F", "operator 'f") # optional - fricas - sage: fricas("eval(D(F(x,y), [x, y], [2, 1]), x=x+y)").sage() # optional - fricas + sage: fricas.set("F", "operator 'f") + sage: fricas("eval(D(F(x,y), [x, y], [2, 1]), x=x+y)").sage() D[0, 0, 1](f)(x + y, y) Conversion of hypergeometric functions (:trac:`31298`):: sage: a,b,c = var("a b c") sage: A = hypergeometric([a, b], [c], x) - sage: fricas(A).sage() - A # optional - fricas + sage: fricas(A).sage() - A 0 - sage: fricas(A).D(x).sage() - diff(A, x) # optional - fricas + sage: fricas(A).D(x).sage() - diff(A, x) 0 Check that :trac:`31858` is fixed:: - sage: fricas.Gamma(3/2).sage() # optional - fricas + sage: fricas.Gamma(3/2).sage() 1/2*sqrt(pi) - sage: fricas.Gamma(3/4).sage() # optional - fricas + sage: fricas.Gamma(3/4).sage() gamma(3/4) - sage: fricas.Gamma(3, 2).sage() # optional - fricas + sage: fricas.Gamma(3, 2).sage() gamma(3, 2) @@ -1709,7 +1703,7 @@ def _sage_expression(fricas_InputForm): sage: var("y") y - sage: f = fricas.zerosOf(y^4 + y + 1, y); f # optional - fricas + sage: f = fricas.zerosOf(y^4 + y + 1, y); f +-----------------------------+ | 2 2 \|- 3 %y1 - 2 %y0 %y1 - 3 %y0 - %y1 - %y0 @@ -1721,7 +1715,7 @@ def _sage_expression(fricas_InputForm): ----------------------------------------------] 2 - sage: f[1].sage() # optional - fricas + sage: f[1].sage() -1/2*sqrt(1/3)*sqrt((3*(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(2/3) + 4)/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) + 1/2*sqrt(-(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3) + 6*sqrt(1/3)/sqrt((3*(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(2/3) + 4)/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) - 4/3/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) """ @@ -1785,7 +1779,6 @@ def _sage_(self): Floats:: - sage: # optional - fricas sage: fricas(2.1234).sage() 2.12340000000000 sage: _.parent() @@ -1804,27 +1797,26 @@ def _sage_(self): Algebraic numbers:: - sage: a = fricas('(1 + sqrt(2))^5'); a # optional - fricas + sage: a = fricas('(1 + sqrt(2))^5'); a +-+ 29 \|2 + 41 - sage: b = a.sage(); b # optional - fricas + sage: b = a.sage(); b 82.0121933088198? - sage: b.radical_expression() # optional - fricas + sage: b.radical_expression() 29*sqrt(2) + 41 Integers modulo n:: - sage: fricas("((42^17)^1783)::IntegerMod(5^(5^5))").sage() == Integers(5^(5^5))((42^17)^1783) # optional - fricas + sage: fricas("((42^17)^1783)::IntegerMod(5^(5^5))").sage() == Integers(5^(5^5))((42^17)^1783) True Matrices over a prime field:: - sage: fricas("matrix [[1::PF 3, 2],[2, 0]]").sage().parent() # optional - fricas + sage: fricas("matrix [[1::PF 3, 2],[2, 0]]").sage().parent() Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 We can also convert FriCAS's polynomials to Sage polynomials:: - sage: # optional - fricas sage: a = fricas("x^2 + 1"); a.typeOf() Polynomial(Integer) sage: a.sage() @@ -1836,52 +1828,52 @@ def _sage_(self): sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field - sage: fricas("1$Polynomial Integer").sage() # optional - fricas + sage: fricas("1$Polynomial Integer").sage() 1 - sage: fricas("x^2/2").sage() # optional - fricas + sage: fricas("x^2/2").sage() 1/2*x^2 sage: x = polygen(QQ, 'x') - sage: fricas(x+3).sage() # optional - fricas + sage: fricas(x+3).sage() x + 3 - sage: fricas(x+3).domainOf() # optional - fricas + sage: fricas(x+3).domainOf() Polynomial(Integer()) - sage: fricas(matrix([[2,3],[4,x+5]])).diagonal().sage() # optional - fricas + sage: fricas(matrix([[2,3],[4,x+5]])).diagonal().sage() (2, x + 5) - sage: f = fricas("(y^2+3)::UP(y, INT)").sage(); f # optional - fricas + sage: f = fricas("(y^2+3)::UP(y, INT)").sage(); f y^2 + 3 - sage: f.parent() # optional - fricas + sage: f.parent() Univariate Polynomial Ring in y over Integer Ring - sage: fricas("(y^2+sqrt 3)::UP(y, AN)").sage() # optional - fricas + sage: fricas("(y^2+sqrt 3)::UP(y, AN)").sage() y^2 + 1.732050807568878? Rational functions:: - sage: fricas("x^2 + 1/z").sage() # optional - fricas + sage: fricas("x^2 + 1/z").sage() x^2 + 1/z Expressions:: - sage: fricas(pi).sage() # optional - fricas + sage: fricas(pi).sage() pi - sage: fricas("sin(x+y)/exp(z)*log(1+%e)").sage() # optional - fricas + sage: fricas("sin(x+y)/exp(z)*log(1+%e)").sage() e^(-z)*log(e + 1)*sin(x + y) - sage: fricas("factorial(n)").sage() # optional - fricas + sage: fricas("factorial(n)").sage() factorial(n) - sage: fricas("integrate(sin(x+y), x=0..1)").sage() # optional - fricas + sage: fricas("integrate(sin(x+y), x=0..1)").sage() -cos(y + 1) + cos(y) - sage: fricas("integrate(x*sin(1/x), x=0..1)").sage() # optional - fricas + sage: fricas("integrate(x*sin(1/x), x=0..1)").sage() 'failed' - sage: fricas("integrate(sin((x^2+1)/x),x)").sage() # optional - fricas + sage: fricas("integrate(sin((x^2+1)/x),x)").sage() integral(sin((x^2 + 1)/x), x) .. TODO:: @@ -1890,7 +1882,7 @@ def _sage_(self): Matrices:: - sage: fricas("matrix [[x^n/2^m for n in 0..5] for m in 0..3]").sage() # optional - fricas, long time + sage: fricas("matrix [[x^n/2^m for n in 0..5] for m in 0..3]").sage() # long time [ 1 x x^2 x^3 x^4 x^5] [ 1/2 1/2*x 1/2*x^2 1/2*x^3 1/2*x^4 1/2*x^5] [ 1/4 1/4*x 1/4*x^2 1/4*x^3 1/4*x^4 1/4*x^5] @@ -1898,25 +1890,25 @@ def _sage_(self): Lists:: - sage: fricas("[2^n/x^n for n in 0..5]").sage() # optional - fricas, long time + sage: fricas("[2^n/x^n for n in 0..5]").sage() # long time [1, 2/x, 4/x^2, 8/x^3, 16/x^4, 32/x^5] - sage: fricas("[matrix [[i for i in 1..n]] for n in 0..5]").sage() # optional - fricas, long time + sage: fricas("[matrix [[i for i in 1..n]] for n in 0..5]").sage() # long time [[], [1], [1 2], [1 2 3], [1 2 3 4], [1 2 3 4 5]] Error handling:: - sage: s = fricas.guessPade("[fibonacci i for i in 0..10]"); s # optional - fricas + sage: s = fricas.guessPade("[fibonacci i for i in 0..10]"); s n x [[[x ]- ----------]] 2 x + x - 1 - sage: s.sage() # optional - fricas + sage: s.sage() Traceback (most recent call last): ... NotImplementedError: the translation of the FriCAS Expression 'rootOfADE' to sage is not yet implemented - sage: s = fricas("series(sqrt(1+x), x=0)"); s # optional - fricas + sage: s = fricas("series(sqrt(1+x), x=0)"); s 1 1 2 1 3 5 4 7 5 21 6 33 7 429 8 1 + - x - - x + -- x - --- x + --- x - ---- x + ---- x - ----- x 2 8 16 128 256 1024 2048 32768 @@ -1925,7 +1917,7 @@ def _sage_(self): ----- x - ------ x + O(x ) 65536 262144 - sage: s.sage() # optional - fricas + sage: s.sage() Traceback (most recent call last): ... NotImplementedError: the translation of the FriCAS object @@ -2082,7 +2074,6 @@ def __init__(self, object, name): TESTS:: - sage: # optional - fricas sage: a = fricas('"Hello"') sage: a.upperCase_q upperCase? @@ -2108,9 +2099,9 @@ def __init__(self, parent, name): TESTS:: - sage: fricas.upperCase_q # optional - fricas + sage: fricas.upperCase_q upperCase? - sage: fricas.upperCase_e # optional - fricas + sage: fricas.upperCase_e upperCase! """ @@ -2132,7 +2123,7 @@ def is_FriCASElement(x): doctest:...: DeprecationWarning: the function is_FriCASElement is deprecated; use isinstance(x, sage.interfaces.abc.FriCASElement) instead See https://github.com/sagemath/sage/issues/34804 for details. False - sage: is_FriCASElement(fricas(2)) # optional - fricas + sage: is_FriCASElement(fricas(2)) True """ from sage.misc.superseded import deprecation @@ -2183,7 +2174,6 @@ def __doctest_cleanup(): """ EXAMPLES:: - sage: # optional - fricas sage: from sage.interfaces.fricas import __doctest_cleanup sage: a = FriCAS() sage: two = a(2) From 9ec6b944651a32f3561847b7af7b34b245249e07 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 15:32:45 -0800 Subject: [PATCH 25/30] sage.interfaces.expect: Delay construction of command to first use, handle Executable --- src/sage/interfaces/expect.py | 58 +++++++++++++++++++++++++---------- src/sage/interfaces/fricas.py | 2 +- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index a5ba8f09f4e..6aacafca9cb 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -40,6 +40,7 @@ import io import os import re +import shlex import signal import sys import weakref @@ -137,11 +138,10 @@ def __init__(self, name, prompt, command=None, env={}, server=None, server = os.getenv(env_name.format('SERVER')) if server_tmpdir is None: server_tmpdir = os.getenv(env_name.format('TMPDIR')) - if command is None: - command = os.getenv(env_name.format('COMMAND')) if script_subdirectory is None: script_subdirectory = os.getenv(env_name.format('SCRIPT_SUBDIRECTORY')) self.__is_remote = False + self.__remote_ulimit = None self.__remote_cleaner = remote_cleaner self._expect = None self._eval_using_file_cutoff = eval_using_file_cutoff @@ -179,11 +179,23 @@ def __init__(self, name, prompt, command=None, env={}, server=None, def set_server_and_command(self, server=None, command=None, server_tmpdir=None, ulimit=None): """ Changes the server and the command to use for this interface. - This raises a Runtime error if the interface is already started. + + This raises a :class:`RuntimeError` if the interface is already started. + + INPUT: + + - ``server`` -- string or ``None`` (default); name of a remote host to connect to using ``ssh``. + + - ``command`` -- one of: + + - a string; command line passed to the shell + + - a sequence of an :class:`~sage.features.Executable` and strings, arguments to + pass to the executable. EXAMPLES:: - sage: magma.set_server_and_command(server = 'remote', command = 'mymagma') # indirect doctest + sage: magma.set_server_and_command(server='remote', command='mymagma') # indirect doctest No remote temporary directory (option server_tmpdir) specified, using /tmp/ on remote sage: magma.server() 'remote' @@ -192,19 +204,13 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, """ if self._expect: raise RuntimeError("interface has already started") - if command is None: - command = self.name() self._server = server + self.__remote_ulimit = ulimit if server is not None: - if ulimit: - command = "ssh -t %s 'ulimit %s; %s'" % (server, ulimit, command) - else: - command = "ssh -t %s '%s'" % (server, command) self.__is_remote = True self._eval_using_file_cutoff = 0 # don't allow this! if self.__verbose_start: print("Using remote server") - print(command) if server_tmpdir is None: # TO DO: Why default to /tmp/? Might be better to use the expect process itself to get a tmp folder print("No remote temporary directory (option server_tmpdir) specified, using /tmp/ on " + server) @@ -221,7 +227,7 @@ def server(self): EXAMPLES:: - sage: magma.set_server_and_command(server = 'remote') + sage: magma.set_server_and_command(server='remote') No remote temporary directory (option server_tmpdir) specified, using /tmp/ on remote sage: magma.server() # indirect doctest 'remote' @@ -230,15 +236,33 @@ def server(self): def command(self): """ - Return the command used in this interface. + Return the command used in this interface as a string. EXAMPLES:: - sage: magma.set_server_and_command(command = 'magma-2.19') - sage: magma.command() # indirect doctest + sage: magma.set_server_and_command(command='magma-2.19') + sage: magma.command() # indirect doctest 'magma-2.19' """ - return self.__command + command = self.__command + server = self.server() + if command is None: + env_name = 'SAGE_%s_{}' % self.name().upper() # same as in __init__ + command = os.getenv(env_name.format('COMMAND'), self.name()) + elif not isinstance(command, str): + executable = self.command[0] + if server: + executable = executable.name + else: + executable = executable.absolute_filename() + command = ' '.join([shlex.quote(executable)] + + [shlex.quote(arg) for arg in self.__command[1:]]) + if server: + if self.__ulimit: + command = f"ulimit {ulimit}; {command}" + command = f"ssh -t {shlex.quote(server)} {shlex.quote(command)}" + + return command def _get(self, wait=0.1, alternate_prompt=None): if self._expect is None: @@ -460,7 +484,7 @@ def _start(self, alt_message=None, block_during_init=True): if self.__logfilename is not None: self.__logfile = open(self.__logfilename, 'wb') - cmd = self.__command + cmd = self.command() if self.__verbose_start: print(cmd) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index ab03a7e0b19..878d5b821e6 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -84,7 +84,7 @@ example, try the following sum but with a much bigger range, and hit control-C:: - sage: f = fricas('(x^5 - y^5)^10000') # not tested - fricas + sage: f = fricas('(x^5 - y^5)^10000') # not tested Interrupting FriCAS... ... KeyboardInterrupt: Ctrl-c pressed while running FriCAS From 26e2e580c3a58f27bd234dad2dd6697d89507bb3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 15:53:53 -0800 Subject: [PATCH 26/30] src/sage/interfaces/fricas.py: Use the FriCAS feature less eagerly --- src/sage/interfaces/expect.py | 4 ++-- src/sage/interfaces/fricas.py | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 6aacafca9cb..0aa0125aeaf 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -250,13 +250,13 @@ def command(self): env_name = 'SAGE_%s_{}' % self.name().upper() # same as in __init__ command = os.getenv(env_name.format('COMMAND'), self.name()) elif not isinstance(command, str): - executable = self.command[0] + executable = command[0] if server: executable = executable.name else: executable = executable.absolute_filename() command = ' '.join([shlex.quote(executable)] - + [shlex.quote(arg) for arg in self.__command[1:]]) + + [shlex.quote(arg) for arg in command[1:]]) if server: if self.__ulimit: command = f"ulimit {ulimit}; {command}" diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 878d5b821e6..3df9ec9fc92 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -267,7 +267,7 @@ class FriCAS(ExtraTabCompletion, Expect): """ def __init__(self, name='fricas', command=None, script_subdirectory=None, logfile=None, - server=None, server_tmpdir=None, options=""): + server=None, server_tmpdir=None): """ Create an instance of the FriCAS interpreter. @@ -290,11 +290,9 @@ def __init__(self, name='fricas', command=None, sage: fricas(I*x).sage() I*x """ - from sage.features.fricas import FriCAS - FriCAS().require() - options ="-nosman" + options - import shlex - command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) + if command is None: + from sage.features.fricas import FriCAS + command = [FriCAS(), "-nosman"] eval_using_file_cutoff = 4096 - 5 # magic number from Expect._eval_line (there might be a bug) assert max(len(c) for c in FRICAS_INIT_CODE) < eval_using_file_cutoff From b474f0ef9f990efa7042517df14bb5b8accb590d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 20:02:19 -0800 Subject: [PATCH 27/30] sage.interfaces.expect: Fix up ulimit --- src/sage/interfaces/expect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 0aa0125aeaf..ab3f68bd188 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -258,8 +258,8 @@ def command(self): command = ' '.join([shlex.quote(executable)] + [shlex.quote(arg) for arg in command[1:]]) if server: - if self.__ulimit: - command = f"ulimit {ulimit}; {command}" + if self.__remote_ulimit: + command = f"ulimit {self.__remote_ulimit}; {command}" command = f"ssh -t {shlex.quote(server)} {shlex.quote(command)}" return command From 256bb8c111b6531ca07bd61be418b51fd727efa2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 20:05:35 -0800 Subject: [PATCH 28/30] sage.interfaces.expect: Update doctest output --- src/sage/interfaces/expect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index ab3f68bd188..cf331f53fd0 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -200,7 +200,7 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, sage: magma.server() 'remote' sage: magma.command() - "ssh -t remote 'mymagma'" + 'ssh -t remote mymagma' """ if self._expect: raise RuntimeError("interface has already started") From ace41e4b2adf2c6b6e8c5d33957351ce685207b7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 07:22:19 -0800 Subject: [PATCH 29/30] src/sage/interfaces/fricas.py: Do not rely on '# tol' for complex tolerances; cf. #36631 --- src/sage/interfaces/fricas.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 3df9ec9fc92..75a277bcd05 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1608,13 +1608,13 @@ def _sage_expression(fricas_InputForm): Check that :trac:`25602` is fixed:: sage: r = fricas.integrate(72000/(1+x^5), x).sage() - sage: n(r.subs(x=5) - r.subs(x=3)) # tol 0.1 - 193.020947266210 + sage: abs(n(r.subs(x=5) - r.subs(x=3)) - 193.020947266210) <= 0.1 + True sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5), x).sage() a - sage: n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) # tol 0.1 - 193.020947266268 - 8.73114913702011e-11*I + sage: abs(n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) - 193.020947266268) <= 0.1 + True Check conversions of sums and products:: From 870fa228fcd96e1724820a6d29ce2c8d6c43289f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 12:05:36 -0800 Subject: [PATCH 30/30] src/sage/functions/special.py: Use 'abs tol' instead of 'tol' in two examples --- src/sage/functions/special.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 93e032d0677..9348b921685 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -511,7 +511,7 @@ def __init__(self): Check that :trac:`34085` is fixed:: sage: _ = var("x y") # needs sage.symbolic - sage: fricas(elliptic_e(x, y)) # optional - fricas, needs sage.symbolic + sage: fricas(elliptic_e(x, y)) # optional - fricas, needs sage.symbolic ellipticE(sin(x),y) However, the conversion is only correct in the interval @@ -525,7 +525,7 @@ def __init__(self): sage: f = lambda x, y: elliptic_e(arcsin(x), y).subs(x=x, y=y) sage: g = lambda x, y: fricas.ellipticE(x, y).sage() sage: d = lambda x, y: f(x, y) - g(x, y) - sage: [d(N(-pi/2 + x), y) # tol 1e-8 # optional - fricas, needs sage.symbolic + sage: [d(N(-pi/2 + x), y) # abs tol 1e-8 # optional - fricas, needs sage.symbolic ....: for x in range(1, 3) for y in range(-2, 2)] [0.000000000000000, 0.000000000000000, @@ -877,7 +877,7 @@ def __init__(self): Check that :trac:`34186` is fixed:: sage: _ = var("x y") # needs sage.symbolic - sage: fricas(elliptic_f(x, y)) # optional - fricas, needs sage.symbolic + sage: fricas(elliptic_f(x, y)) # optional - fricas, needs sage.symbolic ellipticF(sin(x),y) However, the conversion is only correct in the interval @@ -891,7 +891,7 @@ def __init__(self): sage: f = lambda x, y: elliptic_f(arcsin(x), y).subs(x=x, y=y) sage: g = lambda x, y: fricas.ellipticF(x, y).sage() sage: d = lambda x, y: f(x, y) - g(x, y) - sage: [d(N(-pi/2 + x), y) # tol 1e-8 # optional - fricas, needs sage.symbolic + sage: [d(N(-pi/2 + x), y) # abs tol 1e-8 # optional - fricas, needs sage.symbolic ....: for x in range(1, 3) for y in range(-2,2)] [0.000000000000000, 0.000000000000000,