diff --git a/src/sage/cpython/cython_metaclass.pyx b/src/sage/cpython/cython_metaclass.pyx index 744d6e54791..a8fe853661d 100644 --- a/src/sage/cpython/cython_metaclass.pyx +++ b/src/sage/cpython/cython_metaclass.pyx @@ -61,7 +61,7 @@ In Python, this would be ``meta.__init__(cls, name, bases, dict)``. EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: cimport sage.cpython.cython_metaclass ....: cdef class MyCustomType(): @@ -76,9 +76,9 @@ EXAMPLES:: ....: ''') Calling MyMetaclass.__init__(, None, None, None) Calling MyMetaclass.__init__(, None, None, None) - sage: MyCustomType.__class__ # optional - sage.misc.cython + sage: MyCustomType.__class__ # needs sage.misc.cython - sage: class MyPythonType(MyDerivedType): # optional - sage.misc.cython + sage: class MyPythonType(MyDerivedType): # needs sage.misc.cython ....: pass Calling MyMetaclass.__init__(, 'MyPythonType', (,), {...}) @@ -99,7 +99,7 @@ TESTS: Check that a proper exception is raised if ``__getmetaclass__`` returns a non-type:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: cimport sage.cpython.cython_metaclass ....: cdef class MyCustomType(): diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx index 6fd9da310c8..986abff2a99 100644 --- a/src/sage/cpython/debug.pyx +++ b/src/sage/cpython/debug.pyx @@ -101,7 +101,7 @@ def getattr_debug(obj, name, default=_no_default): found '__doc__' in dict of got ... 'str'>) returning ... 'str'>) - sage: _ = getattr_debug(gp(1), "log") + sage: _ = getattr_debug(gp(1), "log") # needs sage.libs.pari getattr_debug(obj=1, name='log'): type(obj) = object has __dict__ slot () diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx index 525ea5aa934..3f603b98040 100644 --- a/src/sage/cpython/getattr.pyx +++ b/src/sage/cpython/getattr.pyx @@ -55,7 +55,7 @@ cdef class AttributeErrorMessage: ... AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla' sage: x = polygen(ZZ, 'x') - sage: QQ[x].gen().bla # optional - sage.libs.flint + sage: QQ[x].gen().bla # needs sage.libs.flint Traceback (most recent call last): ... AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla' @@ -407,20 +407,21 @@ def dir_with_other_class(self, *cls): Check that objects without dicts are well handled:: - sage: cython("cdef class A:\n cdef public int a") # optional - sage.misc.cython - sage: cython("cdef class B:\n cdef public int b") # optional - sage.misc.cython - sage: x = A() # optional - sage.misc.cython - sage: x.a = 1 # optional - sage.misc.cython - sage: hasattr(x,'__dict__') # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython("cdef class A:\n cdef public int a") + sage: cython("cdef class B:\n cdef public int b") + sage: x = A() + sage: x.a = 1 + sage: hasattr(x,'__dict__') False - sage: dir_with_other_class(x, B) # optional - sage.misc.cython + sage: dir_with_other_class(x, B) [..., 'a', 'b'] TESTS: Check that :trac:`13043` is fixed:: - sage: len(dir(RIF))==len(set(dir(RIF))) + sage: len(dir(RIF))==len(set(dir(RIF))) # needs sage.rings.real_interval_field True """ ret = set() diff --git a/src/sage/cpython/string.pyx b/src/sage/cpython/string.pyx index eef3f74f335..554a8a128be 100644 --- a/src/sage/cpython/string.pyx +++ b/src/sage/cpython/string.pyx @@ -6,7 +6,7 @@ TESTS: Check that this can be used outside of Sage (see :trac:`25549`):: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.cpython.string cimport char_to_str ....: print(char_to_str("hello world!")) diff --git a/src/sage/cpython/wrapperdescr.pxd b/src/sage/cpython/wrapperdescr.pxd index d7e67a48ac6..b6775860710 100644 --- a/src/sage/cpython/wrapperdescr.pxd +++ b/src/sage/cpython/wrapperdescr.pxd @@ -39,25 +39,26 @@ cdef inline wrapperbase* get_slotdef(wrapper_descriptor slotwrapper) except NULL TESTS:: - sage: cython( # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython( ....: ''' ....: from sage.cpython.wrapperdescr cimport get_slotdef ....: from cpython.long cimport PyLong_FromVoidPtr ....: def py_get_slotdef(slotwrapper): ....: return PyLong_FromVoidPtr(get_slotdef(slotwrapper)) ....: ''') - sage: py_get_slotdef(object.__init__) # random # optional - sage.misc.cython + sage: py_get_slotdef(object.__init__) # random 140016903442416 - sage: py_get_slotdef(bytes.__lt__) # random # optional - sage.misc.cython + sage: py_get_slotdef(bytes.__lt__) # random 140016903441800 - sage: py_get_slotdef(bytes.__lt__) == py_get_slotdef(Integer.__lt__) # optional - sage.misc.cython + sage: py_get_slotdef(bytes.__lt__) == py_get_slotdef(Integer.__lt__) True - sage: py_get_slotdef(bytes.__lt__) == py_get_slotdef(bytes.__gt__) # optional - sage.misc.cython + sage: py_get_slotdef(bytes.__lt__) == py_get_slotdef(bytes.__gt__) False sage: class X(): ....: def __eq__(self, other): ....: return False - sage: py_get_slotdef(X.__eq__) # optional - sage.misc.cython + sage: py_get_slotdef(X.__eq__) Traceback (most recent call last): ... TypeError: Cannot convert ... to wrapper_descriptor diff --git a/src/sage/cpython/wrapperdescr.pyx b/src/sage/cpython/wrapperdescr.pyx index bea0ecd24a8..66c79ca38e2 100644 --- a/src/sage/cpython/wrapperdescr.pyx +++ b/src/sage/cpython/wrapperdescr.pyx @@ -68,8 +68,9 @@ def wrapperdescr_call(slotwrapper, self, *args, **kwds): 54 sage: wrapperdescr_call(Element.__mul__, 7/5, 9) 63/5 - sage: from sage.numerical.mip import MixedIntegerLinearProgram - sage: wrapperdescr_call(type.__call__, MixedIntegerLinearProgram, maximization=False) + sage: from sage.numerical.mip import MixedIntegerLinearProgram # needs sage.numerical.mip + sage: wrapperdescr_call(type.__call__, # needs sage.numerical.mip + ....: MixedIntegerLinearProgram, maximization=False) Mixed Integer Program (no objective, 0 variables, 0 constraints) TESTS:: diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx index b49f83f46d6..446062554c1 100644 --- a/src/sage/data_structures/bitset.pyx +++ b/src/sage/data_structures/bitset.pyx @@ -204,27 +204,28 @@ cdef class FrozenBitset: the number of elements currently in the bitset, while the capacity is the number of elements that the bitset can hold. :: - sage: p = primes_first_n(10); p + sage: p = primes_first_n(10); p # needs sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - sage: tuple(p) + sage: tuple(p) # needs sage.libs.pari (2, 3, 5, 7, 11, 13, 17, 19, 23, 29) - sage: F = FrozenBitset(p); F; FrozenBitset(tuple(p)) + sage: F = FrozenBitset(p); F; FrozenBitset(tuple(p)) # needs sage.libs.pari 001101010001010001010001000001 001101010001010001010001000001 Recover the primes from the bitset:: - sage: for b in F: + sage: for b in F: # needs sage.libs.pari ....: print(b) 2 3 ... 29 - sage: list(F) + sage: list(F) # needs sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] Query the bitset:: + sage: # needs sage.libs.pari sage: len(F) 10 sage: len(list(F)) @@ -2067,7 +2068,7 @@ def test_bitset(py_a, py_b, long n): Large enough to span multiple limbs. We don't explicitly check the number of limbs below because it will be different in the 32 bit versus 64 bit cases:: - sage: test_bitset('111001'*25, RealField(151)(pi).str(2)[2:], 69) + sage: test_bitset('111001'*25, RealField(151)(pi).str(2)[2:], 69) # needs sage.symbolic a 111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001111001 list a [0, 1, 2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20, 23, 24, 25, 26, 29, 30, 31, 32, 35, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 53, 54, 55, 56, 59, 60, 61, 62, 65, 66, 67, 68, 71, 72, 73, 74, 77, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 107, 108, 109, 110, 113, 114, 115, 116, 119, 120, 121, 122, 125, 126, 127, 128, 131, 132, 133, 134, 137, 138, 139, 140, 143, 144, 145, 146, 149] a.size 150 diff --git a/src/sage/data_structures/blas_dict.pyx b/src/sage/data_structures/blas_dict.pyx index df6bf29641e..c13cab2aab9 100644 --- a/src/sage/data_structures/blas_dict.pyx +++ b/src/sage/data_structures/blas_dict.pyx @@ -398,7 +398,8 @@ cpdef dict sum_of_terms(index_coeff_pairs): {'a': 1, 'b': 3} sage: blas.sum_of_terms([('a', 5), ('b', 3), ('a', -5)]) {'b': 3} - sage: blas.sum_of_terms([('a', 5), ('b', GF(2).one()), ('a', -5), ('b', GF(2).one())]) + sage: blas.sum_of_terms([('a', 5), ('b', GF(2).one()), + ....: ('a', -5), ('b', GF(2).one())]) {} """ cdef dict result = {} diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index b11a27318f5..80316928625 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1669,7 +1669,7 @@ class Stream_dirichlet_invert(Stream_unary): sage: g = Stream_dirichlet_invert(f, True) sage: [g[i] for i in range(10)] [0, 1, -1, -1, 0, -1, 1, -1, 0, 0] - sage: [moebius(i) for i in range(10)] + sage: [moebius(i) for i in range(10)] # needs sage.libs.pari [0, 1, -1, -1, 0, -1, 1, -1, 0, 0] """ def __init__(self, series, is_sparse): @@ -1897,6 +1897,7 @@ class Stream_plethysm(Stream_binary): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_function, Stream_plethysm sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() @@ -1920,6 +1921,7 @@ class Stream_plethysm(Stream_binary): This class also handles the plethysm of an exact stream with a stream of order `0`:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_exact sage: f = Stream_exact([s[1]], order=1) sage: g = Stream_function(lambda n: s[n], True, 0) @@ -1931,6 +1933,7 @@ class Stream_plethysm(Stream_binary): Check corner cases:: + sage: # needs sage.modules sage: f0 = Stream_exact([p([])]) sage: f1 = Stream_exact([p[1]], order=1) sage: f2 = Stream_exact([p[2]], order=2 ) @@ -1944,21 +1947,24 @@ class Stream_plethysm(Stream_binary): Check that degree one elements are treated in the correct way:: + sage: # needs sage.modules sage: R. = QQ[]; p = SymmetricFunctions(R).p() sage: f_s = a1*p[1] + a2*p[2] + a11*p[1,1] sage: g_s = b1*p[1] + b21*p[2,1] + b111*p[1,1,1] sage: r_s = f_s(g_s) - sage: f = Stream_exact([f_s.restrict_degree(k) for k in range(f_s.degree()+1)]) - sage: g = Stream_exact([g_s.restrict_degree(k) for k in range(g_s.degree()+1)]) + sage: f = Stream_exact([f_s.restrict_degree(k) + ....: for k in range(f_s.degree()+1)]) + sage: g = Stream_exact([g_s.restrict_degree(k) + ....: for k in range(g_s.degree()+1)]) sage: r = Stream_plethysm(f, g, True, p) sage: r_s == sum(r[n] for n in range(2*(r_s.degree()+1))) True - sage: r_s - f_s(g_s, include=[]) + sage: r_s - f_s(g_s, include=[]) # needs sage.modules (a2*b1^2-a2*b1)*p[2] + (a2*b111^2-a2*b111)*p[2, 2, 2] + (a2*b21^2-a2*b21)*p[4, 2] - sage: r2 = Stream_plethysm(f, g, True, p, include=[]) - sage: r_s - sum(r2[n] for n in range(2*(r_s.degree()+1))) + sage: r2 = Stream_plethysm(f, g, True, p, include=[]) # needs sage.modules + sage: r_s - sum(r2[n] for n in range(2*(r_s.degree()+1))) # needs sage.modules (a2*b1^2-a2*b1)*p[2] + (a2*b111^2-a2*b111)*p[2, 2, 2] + (a2*b21^2-a2*b21)*p[4, 2] """ @@ -1968,6 +1974,7 @@ def __init__(self, f, g, is_sparse, p, ring=None, include=None, exclude=None): TESTS:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_function, Stream_plethysm sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() @@ -2009,6 +2016,7 @@ def _approximate_order(self): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_function, Stream_plethysm sage: p = SymmetricFunctions(QQ).p() sage: f = Stream_function(lambda n: p[n], True, 1) @@ -2035,6 +2043,7 @@ def get_coefficient(self, n): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_function, Stream_plethysm sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() @@ -2074,6 +2083,7 @@ def compute_product(self, n, la): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_plethysm, Stream_exact, Stream_function, Stream_zero sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() @@ -2086,21 +2096,26 @@ def compute_product(self, n, la): sage: A == p[2, 1](s[2] + s[3]).homogeneous_component(7) True + sage: # needs sage.modules sage: p2 = tensor([p, p]) sage: f = Stream_exact([1]) # irrelevant for this test - sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) for k in range(n+1)), True, 1) + sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) + ....: for k in range(n+1)), True, 1) sage: h = Stream_plethysm(f, g, True, p2) sage: A = h.compute_product(7, Partition([2, 1])) sage: B = p[2, 1](sum(g[n] for n in range(7))) - sage: B = p2.element_class(p2, {m: c for m, c in B if sum(mu.size() for mu in m) == 7}) + sage: B = p2.element_class(p2, {m: c for m, c in B + ....: if sum(mu.size() for mu in m) == 7}) sage: A == B True + sage: # needs sage.modules sage: f = Stream_exact([1]) # irrelevant for this test sage: g = Stream_function(lambda n: s[n], True, 0) sage: h = Stream_plethysm(f, g, True, p) sage: B = p[2, 2, 1](sum(p(s[i]) for i in range(7))) - sage: all(h.compute_product(k, Partition([2, 2, 1])) == B.restrict_degree(k) for k in range(7)) + sage: all(h.compute_product(k, Partition([2, 2, 1])) + ....: == B.restrict_degree(k) for k in range(7)) True """ # This is the approximate order of the result @@ -2134,6 +2149,7 @@ def stretched_power_restrict_degree(self, i, m, d): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import Stream_plethysm, Stream_exact, Stream_function, Stream_zero sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() @@ -2144,14 +2160,17 @@ def stretched_power_restrict_degree(self, i, m, d): sage: A == p[2,2,2](s[2] + s[3]).homogeneous_component(12) True + sage: # needs sage.modules sage: p2 = tensor([p, p]) sage: f = Stream_exact([1]) # irrelevant for this test - sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) for k in range(n+1)), True, 1) + sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) + ....: for k in range(n+1)), True, 1) sage: h = Stream_plethysm(f, g, True, p2) sage: A = h.stretched_power_restrict_degree(2, 3, 6) - sage: B = p[2,2,2](sum(g[n] for n in range(7))) # long time - sage: B = p2.element_class(p2, {m: c for m, c in B if sum(mu.size() for mu in m) == 12}) # long time - sage: A == B # long time + sage: B = p[2,2,2](sum(g[n] for n in range(7))) # long time + sage: B = p2.element_class(p2, {m: c for m, c in B # long time + ....: if sum(mu.size() for mu in m) == 12}) + sage: A == B # long time True """ while len(self._powers) < m: @@ -2298,6 +2317,7 @@ class Stream_rmul(Stream_scalar): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import (Stream_rmul, Stream_function) sage: W = algebras.DifferentialWeyl(QQ, names=('x',)) sage: x, dx = W.gens() @@ -2339,6 +2359,7 @@ class Stream_lmul(Stream_scalar): EXAMPLES:: + sage: # needs sage.modules sage: from sage.data_structures.stream import (Stream_lmul, Stream_function) sage: W = algebras.DifferentialWeyl(QQ, names=('x',)) sage: x, dx = W.gens() diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index 19cd672bb0f..54e83d639ad 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -217,7 +217,7 @@ def cremona_letter_code(n): Traceback (most recent call last): ... ValueError: Cremona letter codes are only defined for non-negative integers - sage: cremona_letter_code(x) + sage: cremona_letter_code(x) # needs sage.symbolic Traceback (most recent call last): ... ValueError: Cremona letter codes are only defined for non-negative integers diff --git a/src/sage/databases/cubic_hecke_db.py b/src/sage/databases/cubic_hecke_db.py index 99e96a9b816..b78e582d91e 100644 --- a/src/sage/databases/cubic_hecke_db.py +++ b/src/sage/databases/cubic_hecke_db.py @@ -1493,6 +1493,7 @@ def read_markov(bas_ele, variables, num_strands=4): EXAMPLES:: + sage: # needs sympy sage: from sage.databases.cubic_hecke_db import read_markov sage: from sympy import var sage: u, v, w, s = var('u, v, w, s') diff --git a/src/sage/databases/db_modular_polynomials.py b/src/sage/databases/db_modular_polynomials.py index d9f4b0752c2..4e0422539fc 100644 --- a/src/sage/databases/db_modular_polynomials.py +++ b/src/sage/databases/db_modular_polynomials.py @@ -20,16 +20,17 @@ def _dbz_to_string(name): r""" TESTS:: + sage: # optional - database_kohel sage: from sage.databases.db_modular_polynomials import _dbz_to_string - sage: _dbz_to_string('PolMod/Atk/pol.002.dbz') # optional - database_kohel + sage: _dbz_to_string('PolMod/Atk/pol.002.dbz') '3 0 1 \n2 1 -1 \n2 0 744 \n1 1 -1 \n1 0 184512 \n0 2 1 \n0 1 7256 \n0 0 15252992 \n' - sage: _dbz_to_string('PolMod/Cls/pol.001.dbz') # optional - database_kohel + sage: _dbz_to_string('PolMod/Cls/pol.001.dbz') '1 0 1 \n' - sage: _dbz_to_string('PolMod/Eta/pol.002.dbz') # optional - database_kohel + sage: _dbz_to_string('PolMod/Eta/pol.002.dbz') '3 0 1 \n2 0 48 \n1 1 -1 \n1 0 768 \n0 0 4096 \n' - sage: _dbz_to_string('PolMod/EtaCrr/crr.02.002.dbz') # optional - database_kohel + sage: _dbz_to_string('PolMod/EtaCrr/crr.02.002.dbz') '2 1 1 \n2 0 -48 \n1 1 2304 \n0 2 -4096 \n0 1 196608 \n' - sage: _dbz_to_string('PolHeeg/Cls/0000001-0005000/pol.0000003.dbz') # optional - database_kohel + sage: _dbz_to_string('PolHeeg/Cls/0000001-0005000/pol.0000003.dbz') '0\n1\n' """ from sage.env import SAGE_SHARE diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 323a7a22910..bad5c846725 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -1556,11 +1556,12 @@ def reset(self): Check that new statistics and maps cannot be reset:: - sage: q = findstat([(d, randint(1, 1000)) for d in DyckWords(4)]) # optional -- internet - sage: q.set_description("Random values on Dyck paths.") # optional -- internet - sage: print(q.description()) # optional -- internet + sage: # optional - internet + sage: q = findstat([(d, randint(1, 1000)) for d in DyckWords(4)]) + sage: q.set_description("Random values on Dyck paths.") + sage: print(q.description()) Random values on Dyck paths. - sage: q.reset() # optional -- internet + sage: q.reset() Traceback (most recent call last): ... ValueError: cannot reset values of St000000: a new statistic on Dyck paths @@ -3280,14 +3281,15 @@ def set_properties_raw(self, value): EXAMPLES:: - sage: from sage.databases.findstat import FindStatMap # optional -- internet - sage: FindStatMap(61).set_properties_raw('surjective') # optional -- internet - sage: FindStatMap(61).properties_raw() # optional -- internet + sage: # optional - internet + sage: from sage.databases.findstat import FindStatMap + sage: FindStatMap(61).set_properties_raw('surjective') + sage: FindStatMap(61).properties_raw() 'surjective' - sage: FindStatMap(61) # optional -- internet + sage: FindStatMap(61) Mp00061(modified): to increasing tree - sage: FindStatMap(61).reset() # optional -- internet - sage: FindStatMap(61) # optional -- internet + sage: FindStatMap(61).reset() + sage: FindStatMap(61) Mp00061: to increasing tree """ if value != self.properties_raw(): @@ -4283,13 +4285,14 @@ def in_range(self, element): EXAMPLES:: + sage: # optional - internet sage: from sage.databases.findstat import FindStatCollection - sage: c = FindStatCollection("GelfandTsetlinPatterns") # optional -- internet - sage: c.in_range(GelfandTsetlinPattern([[2, 1], [1]])) # optional -- internet + sage: c = FindStatCollection("GelfandTsetlinPatterns") + sage: c.in_range(GelfandTsetlinPattern([[2, 1], [1]])) True - sage: c.in_range(GelfandTsetlinPattern([[3, 1], [1]])) # optional -- internet + sage: c.in_range(GelfandTsetlinPattern([[3, 1], [1]])) True - sage: c.in_range(GelfandTsetlinPattern([[7, 1], [1]])) # optional -- internet + sage: c.in_range(GelfandTsetlinPattern([[7, 1], [1]])) False TESTS:: diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py index 5afcaaa3f6b..26d4dbaa373 100644 --- a/src/sage/databases/jones.py +++ b/src/sage/databases/jones.py @@ -256,20 +256,21 @@ def ramified_at(self, S, d=None, var='a'): EXAMPLES:: - sage: J = JonesDatabase() # optional - database_jones_numfield - sage: J.ramified_at([101,109]) # optional - database_jones_numfield + sage: # optional - database_jones_numfield + sage: J = JonesDatabase() + sage: J.ramified_at([101,109]) [] - sage: J.ramified_at([109]) # optional - database_jones_numfield + sage: J.ramified_at([109]) [Number Field in a with defining polynomial x^2 - 109, Number Field in a with defining polynomial x^3 - x^2 - 36*x + 4, Number Field in a with defining polynomial x^4 - x^3 + 14*x^2 + 34*x + 393] - sage: J.ramified_at(101) # optional - database_jones_numfield + sage: J.ramified_at(101) [Number Field in a with defining polynomial x^2 - 101, Number Field in a with defining polynomial x^4 - x^3 + 13*x^2 - 19*x + 361, Number Field in a with defining polynomial x^5 + x^4 - 6*x^3 - x^2 + 18*x + 4, Number Field in a with defining polynomial x^5 + 2*x^4 + 7*x^3 + 4*x^2 + 11*x - 6, Number Field in a with defining polynomial x^5 - x^4 - 40*x^3 - 93*x^2 - 21*x + 17] - sage: J.ramified_at((2, 5, 29), 3, 'c') # optional - database_jones_numfield + sage: J.ramified_at((2, 5, 29), 3, 'c') [Number Field in c with defining polynomial x^3 - x^2 - 8*x - 28, Number Field in c with defining polynomial x^3 - x^2 + 10*x + 102, Number Field in c with defining polynomial x^3 - x^2 - 48*x - 188, diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 368ee80e120..b6eeac3499c 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -5,8 +5,8 @@ You can query the OEIS (Online Database of Integer Sequences) through Sage in order to: - - identify a sequence from its first terms. - - obtain more terms, formulae, references, etc. for a given sequence. +- identify a sequence from its first terms. +- obtain more terms, formulae, references, etc. for a given sequence. AUTHORS: @@ -21,35 +21,36 @@ EXAMPLES:: - sage: oeis - The On-Line Encyclopedia of Integer Sequences (https://oeis.org/) + sage: oeis + The On-Line Encyclopedia of Integer Sequences (https://oeis.org/) What about a sequence starting with `3, 7, 15, 1` ? :: - sage: search = oeis([3, 7, 15, 1], max_results=4) ; search # optional -- internet # random + sage: # optional - internet + sage: search = oeis([3, 7, 15, 1], max_results=4); search # random 0: A001203: Simple continued fraction expansion of Pi. 1: A240698: Partial sums of divisors of n, cf. A027750. 2: A082495: a(n) = (2^n - 1) mod n. - 3: A165416: Irregular array read by rows: The n-th row contains those distinct positive integers that each, when written in binary, occurs as a substring in binary n. - - sage: [u.id() for u in search] # optional -- internet # random + 3: A165416: Irregular array read by rows: The n-th row contains those + distinct positive integers that each, when written in binary, + occurs as a substring in binary n. + sage: [u.id() for u in search] # random ['A001203', 'A240698', 'A082495', 'A165416'] - sage: c = search[0] ; c # optional -- internet + sage: c = search[0]; c A001203: Simple continued fraction expansion of Pi. :: - sage: c.first_terms(15) # optional -- internet + sage: # optional - internet + sage: c.first_terms(15) (3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1) - - sage: c.examples() # optional -- internet + sage: c.examples() 0: Pi = 3.1415926535897932384... 1: = 3 + 1/(7 + 1/(15 + 1/(1 + 1/(292 + ...)))) 2: = [a_0; a_1, a_2, a_3, ...] = [3; 7, 15, 1, 292, ...]. - - sage: c.comments() # optional -- internet + sage: c.comments() 0: The first 5821569425 terms were computed by _Eric W. Weisstein_ on Sep 18 2011. 1: The first 10672905501 terms were computed by _Eric W. Weisstein_ on Jul 17 2013. 2: The first 15000000000 terms were computed by _Eric W. Weisstein_ on Jul 27 2013. @@ -57,51 +58,49 @@ :: - sage: x = c.natural_object() ; type(x) # optional -- internet + sage: # optional - internet + sage: x = c.natural_object(); type(x) - - sage: x.convergents()[:7] # optional -- internet + sage: x.convergents()[:7] [3, 22/7, 333/106, 355/113, 103993/33102, 104348/33215, 208341/66317] - - sage: RR(x.value()) # optional -- internet + sage: RR(x.value()) 3.14159265358979 - sage: RR(x.value()) == RR(pi) # optional -- internet + sage: RR(x.value()) == RR(pi) True -What about posets ? Are they hard to count ? To which other structures are they -related ? +What about posets? Are they hard to count? To which other structures are they +related? :: + sage: # optional - internet sage: [Posets(i).cardinality() for i in range(10)] [1, 1, 2, 5, 16, 63, 318, 2045, 16999, 183231] - sage: oeis(_) # optional -- internet + sage: oeis(_) 0: A000112: Number of partially ordered sets ("posets") with n unlabeled elements. - sage: p = _[0] # optional -- internet - -:: - - sage: 'hard' in p.keywords() # optional -- internet + sage: p = _[0] + sage: 'hard' in p.keywords() True - sage: len(p.formulas()) # optional -- internet + sage: len(p.formulas()) 0 - sage: len(p.first_terms()) # optional -- internet + sage: len(p.first_terms()) 17 - -:: - - sage: p.cross_references(fetch=True) # optional -- internet # random - 0: A000798: Number of different quasi-orders (or topologies, or transitive digraphs) with n labeled elements. - 1: A001035: Number of partially ordered sets ("posets") with n labeled elements (or labeled acyclic transitive digraphs). + sage: p.cross_references(fetch=True) # random + 0: A000798: Number of different quasi-orders (or topologies, or transitive digraphs) + with n labeled elements. + 1: A001035: Number of partially ordered sets ("posets") with n labeled elements + (or labeled acyclic transitive digraphs). 2: A001930: Number of topologies, or transitive digraphs with n unlabeled nodes. 3: A006057: Number of topologies on n labeled points satisfying axioms T_0-T_4. 4: A079263: Number of constrained mixed models with n factors. 5: A079265: Number of antisymmetric transitive binary relations on n unlabeled points. - 6: A263859: Triangle read by rows: T(n,k) (n>=1, k>=0) is the number of posets with n elements and rank k (or depth k+1). + 6: A263859: Triangle read by rows: T(n,k) (n>=1, k>=0) is the number of posets + with n elements and rank k (or depth k+1). 7: A316978: Number of factorizations of n into factors > 1 with no equivalent primes. 8: A319559: Number of non-isomorphic T_0 set systems of weight n. 9: A326939: Number of T_0 sets of subsets of {1..n} that cover all n vertices. - 10: A326943: Number of T_0 sets of subsets of {1..n} that cover all n vertices and are closed under intersection. + 10: A326943: Number of T_0 sets of subsets of {1..n} that cover all n vertices and + are closed under intersection. ... What does the Taylor expansion of the `e^{e^x-1}` function have to do with @@ -109,25 +108,22 @@ :: + sage: # optional - internet, needs sage.symbolic sage: x = var('x') ; f(x) = e^(e^x - 1) - sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coefficients()] ; L + sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coefficients()]; L [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, - 27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159, - 5832742205057, 51724158235372] - - sage: oeis(L) # optional -- internet - 0: A000110: Bell or exponential numbers: number of ways to partition a set of n labeled elements. + 27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159, + 5832742205057, 51724158235372] + sage: oeis(L) + 0: A000110: Bell or exponential numbers: number of ways to partition + a set of n labeled elements. 1: A292935: E.g.f.: exp(exp(-x) - 1). - - sage: b = _[0] # optional -- internet - - sage: b.formulas()[0] # optional -- internet + sage: b = _[0] + sage: b.formulas()[0] 'E.g.f.: exp(exp(x) - 1).' - - sage: [i for i in b.comments() if 'prime' in i][-1] # optional -- internet + sage: [i for i in b.comments() if 'prime' in i][-1] 'Number n is prime if ...' - - sage: [n for n in range(2, 20) if (b(n)-2) % n == 0] # optional -- internet + sage: [n for n in range(2, 20) if (b(n)-2) % n == 0] [2, 3, 5, 7, 11, 13, 17, 19] .. SEEALSO:: @@ -261,18 +257,18 @@ class OEIS: Sequences. You can query it using its methods, but ``OEIS`` can also be called directly with three arguments: - - ``query`` - it can be: + - ``query`` -- it can be: - a string representing an OEIS ID (e.g. 'A000045'). - an integer representing an OEIS ID (e.g. 45). - a list representing a sequence of integers. - a string, representing a text search. - - ``max_results`` - (integer, default: 30) the maximum number of + - ``max_results`` -- (integer, default: 30) the maximum number of results to return, they are sorted according to their relevance. In any cases, the OEIS website will never provide more than 100 results. - - ``first_result`` - (integer, default: 0) allow to skip the + - ``first_result`` -- (integer, default: 0) allow to skip the ``first_result`` first results in the search, to go further. This is useful if you are looking for a sequence that may appear after the 100 first found sequences. @@ -299,16 +295,17 @@ class OEIS: sage: oeis('A000040') # optional -- internet A000040: The prime numbers. - sage: oeis(45) # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. The database can be searched by subsequence:: - sage: search = oeis([1,2,3,5,8,13]) ; search # optional -- internet + sage: search = oeis([1,2,3,5,8,13]); search # optional -- internet 0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. 1: A290689: Number of transitive rooted trees with n nodes. - 2: A027926: Triangular array T read by rows: T(n,0) = T(n,2n) = 1 for n >= 0; T(n,1) = 1 for n >= 1; T(n,k) = T(n-1,k-2) + T(n-1,k-1) for k = 2..2n-1, n >= 2. + 2: A027926: Triangular array T read by rows: T(n,0) = T(n,2n) = 1 for n >= 0; + T(n,1) = 1 for n >= 1; T(n,k) = T(n-1,k-2) + T(n-1,k-1) + for k = 2..2n-1, n >= 2. sage: fibo = search[0] # optional -- internet @@ -349,9 +346,10 @@ class OEIS: The database can be searched by description:: - sage: oeis('prime gap factorization', max_results=4) # optional --internet # random + sage: oeis('prime gap factorization', max_results=4) # random # optional -- internet 0: A073491: Numbers having no prime gaps in their factorization. - 1: A073485: Product of any number of consecutive primes; squarefree numbers with no gaps in their prime factorization. + 1: A073485: Product of any number of consecutive primes; squarefree numbers + with no gaps in their prime factorization. 2: A073490: Number of prime gaps in factorization of n. 3: A073492: Numbers having at least one prime gap in their factorization. @@ -362,7 +360,9 @@ class OEIS: sage: oeis([1,2,3,5,8,13]) # optional -- internet 0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. 1: A290689: Number of transitive rooted trees with n nodes. - 2: A027926: Triangular array T read by rows: T(n,0) = T(n,2n) = 1 for n >= 0; T(n,1) = 1 for n >= 1; T(n,k) = T(n-1,k-2) + T(n-1,k-1) for k = 2..2n-1, n >= 2. + 2: A027926: Triangular array T read by rows: T(n,0) = T(n,2n) = 1 for n >= 0; + T(n,1) = 1 for n >= 1; T(n,k) = T(n-1,k-2) + T(n-1,k-1) + for k = 2..2n-1, n >= 2. sage: oeis('A000045') # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. @@ -659,20 +659,19 @@ class OEISSequence(SageObject, UniqueRepresentation): between calling and getting item, see :meth:`__call__` for more details :: + sage: # optional - internet sage: sfibo = oeis('A039834') - sage: sfibo.first_terms()[:10] # optional -- internet + sage: sfibo.first_terms()[:10] (1, 1, 0, 1, -1, 2, -3, 5, -8, 13) - - sage: sfibo(-2) # optional -- internet + sage: sfibo(-2) 1 - sage: sfibo(3) # optional -- internet + sage: sfibo(3) 2 - sage: sfibo.offsets() # optional -- internet + sage: sfibo.offsets() (-2, 6) - - sage: sfibo[0] # optional -- internet + sage: sfibo[0] 1 - sage: sfibo[6] # optional -- internet + sage: sfibo[6] -3 .. automethod:: __call__ @@ -1005,11 +1004,11 @@ def natural_object(self): OUTPUT: - If the sequence ``self`` corresponds to the digits of a real - number, returns the associated real number (as an element of - RealLazyField()). + number, returns the associated real number (as an element of + RealLazyField()). - If the sequence ``self`` corresponds to the convergents of a - continued fraction, returns the associated continued fraction. + continued fraction, returns the associated continued fraction. .. WARNING:: @@ -1024,25 +1023,25 @@ def natural_object(self): EXAMPLES:: - sage: g = oeis("A002852") ; g # optional -- internet + sage: g = oeis("A002852"); g # optional -- internet A002852: Continued fraction for Euler's constant (or Euler-Mascheroni constant) gamma. - sage: x = g.natural_object() ; type(x) # optional -- internet + sage: x = g.natural_object(); type(x) # optional -- internet sage: RDF(x) == RDF(euler_gamma) # optional -- internet True - sage: cfg = continued_fraction(euler_gamma) - sage: x[:90] == cfg[:90] # optional -- internet + sage: cfg = continued_fraction(euler_gamma) # needs sage.symbolic + sage: x[:90] == cfg[:90] # optional - internet # needs sage.symbolic True :: - sage: ee = oeis('A001113') ; ee # optional -- internet + sage: ee = oeis('A001113'); ee # optional -- internet A001113: Decimal expansion of e. - sage: x = ee.natural_object() ; x # optional -- internet + sage: x = ee.natural_object(); x # optional -- internet 2.718281828459046? sage: x.parent() # optional -- internet @@ -1053,7 +1052,7 @@ def natural_object(self): :: - sage: av = oeis('A087778') ; av # optional -- internet + sage: av = oeis('A087778'); av # optional -- internet A087778: Decimal expansion ... Avogadro... sage: av.natural_object() # optional -- internet @@ -1061,18 +1060,20 @@ def natural_object(self): :: - sage: fib = oeis('A000045') ; fib # optional -- internet + sage: fib = oeis('A000045'); fib # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. - sage: x = fib.natural_object() ; x.universe() # optional -- internet + sage: x = fib.natural_object(); x.universe() # optional -- internet Non negative integer semiring :: - sage: sfib = oeis('A039834') ; sfib # optional -- internet - A039834: a(n+2) = -a(n+1) + a(n) (signed Fibonacci numbers) with a(-2) = a(-1) = 1; or Fibonacci numbers (A000045) extended to negative indices. + sage: sfib = oeis('A039834'); sfib # optional -- internet + A039834: a(n+2) = -a(n+1) + a(n) (signed Fibonacci numbers) with + a(-2) = a(-1) = 1; or Fibonacci numbers (A000045) + extended to negative indices. - sage: x = sfib.natural_object() ; x.universe() # optional -- internet + sage: x = sfib.natural_object(); x.universe() # optional -- internet Integer Ring TESTS:: @@ -1263,7 +1264,7 @@ def first_terms(self, number=None): EXAMPLES:: - sage: f = oeis(45) ; f # optional -- internet + sage: f = oeis(45); f # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. sage: f.first_terms()[:10] # optional -- internet @@ -1271,7 +1272,7 @@ def first_terms(self, number=None): Handle dead sequences, see :trac:`17330` :: - sage: oeis(5000).first_terms(12) # optional -- internet + sage: oeis(5000).first_terms(12) # optional -- internet doctest:warning ... RuntimeWarning: This sequence is dead: "A005000: Erroneous version of A006505." @@ -1440,14 +1441,15 @@ def __iter__(self): sage: w = oeis(7540) ; w # optional -- internet A007540: Wilson primes: primes p such that (p-1)! == -1 (mod p^2). - sage: i = w.__iter__() # optional -- internet - sage: next(i) # optional -- internet + sage: # optional - internet + sage: i = w.__iter__() + sage: next(i) 5 - sage: next(i) # optional -- internet + sage: next(i) 13 - sage: next(i) # optional -- internet + sage: next(i) 563 - sage: next(i) # optional -- internet + sage: next(i) Traceback (most recent call last): ... LookupError: future values not provided by OEIS @@ -1517,17 +1519,16 @@ def links(self, browse=None, format='guess'): INPUT: - ``browse`` -- an integer, a list of integers, or the word 'all' - (default: ``None``) : which links to open in a web browser. + (default: ``None``): which links to open in a web browser. - - ``format`` -- string (default: 'guess') : how to display the links. + - ``format`` -- string (default: 'guess'): how to display the links. - OUTPUT: + OUTPUT: Tuple of strings (with fancy formatting): - - tuple of strings (with fancy formatting): - - if ``format`` is ``url``, returns a tuple of absolute links without description. - - if ``format`` is ``html``, returns nothing but prints a tuple of clickable absolute links in their context. - - if ``format`` is ``guess``, adapts the output to the context (command line or notebook). - - if ``format`` is ``raw``, the links as they appear in the database, relative links are not made absolute. + - if ``format`` is ``url``, returns a tuple of absolute links without description. + - if ``format`` is ``html``, returns nothing but prints a tuple of clickable absolute links in their context. + - if ``format`` is ``guess``, adapts the output to the context (command line or notebook). + - if ``format`` is ``raw``, the links as they appear in the database, relative links are not made absolute. EXAMPLES:: @@ -1635,7 +1636,9 @@ def cross_references(self, fetch=False): 0: A000010: Euler totient function phi(n): count numbers <= n and prime to n. 1: A002088: Sum of totient function: a(n) = Sum_{k=1..n} phi(k), cf. A000010. 2: A011755: a(n) = Sum_{k=1..n} k*phi(k). - 3: A049695: Array T read by diagonals; T(i,j) is the number of nonnegative slopes of lines determined by 2 lattice points in [ 0,i ] X [ 0,j ] if i > 0; T(0,j)=1 if j > 0; T(0,0)=0. + 3: A049695: Array T read by diagonals; T(i,j) is the number of nonnegative + slopes of lines determined by 2 lattice points in + [ 0,i ] X [ 0,j ] if i > 0; T(0,j)=1 if j > 0; T(0,0)=0. 4: A049703: a(0) = 0; for n>0, a(n) = A005598(n)/2. 5: A103116: a(n) = Sum_{i=1..n} (n-i+1)*phi(i). @@ -1664,8 +1667,10 @@ def extensions_or_errors(self): EXAMPLES:: - sage: sfibo = oeis('A039834') ; sfibo # optional -- internet - A039834: a(n+2) = -a(n+1) + a(n) (signed Fibonacci numbers) with a(-2) = a(-1) = 1; or Fibonacci numbers (A000045) extended to negative indices. + sage: sfibo = oeis('A039834'); sfibo # optional -- internet + A039834: a(n+2) = -a(n+1) + a(n) (signed Fibonacci numbers) with + a(-2) = a(-1) = 1; or Fibonacci numbers (A000045) extended + to negative indices. sage: sfibo.extensions_or_errors()[0] # optional -- internet 'Signs corrected by _Len Smiley_ and _N. J. A. Sloane_' @@ -1689,7 +1694,7 @@ def examples(self): EXAMPLES:: - sage: c = oeis(1203) ; c # optional -- internet + sage: c = oeis(1203); c # optional -- internet A001203: Simple continued fraction expansion of Pi. sage: c.examples() # optional -- internet @@ -1715,7 +1720,7 @@ def comments(self): EXAMPLES:: - sage: f = oeis(45) ; f # optional -- internet + sage: f = oeis(45); f # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. sage: f.comments()[:8] # optional -- internet @@ -1747,7 +1752,7 @@ def url(self): EXAMPLES:: - sage: f = oeis(45) ; f # optional -- internet + sage: f = oeis(45); f # optional -- internet A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. sage: f.url() # optional -- internet @@ -1767,7 +1772,7 @@ def browse(self): EXAMPLES:: - sage: f = oeis(45) ; f # optional -- internet webbrowser + sage: f = oeis(45); f # optional -- internet webbrowser A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. sage: f.browse() # optional -- internet webbrowser @@ -1782,7 +1787,7 @@ def browse(self): def show(self): r""" - Display most available informations about the sequence ``self``. + Display most available information about the sequence ``self``. EXAMPLES:: @@ -2001,14 +2006,14 @@ def test_compile_sage_code(self): One correct sequence:: - sage: s = oeis.find_by_id('A027642') # optional -- internet - sage: s.test_compile_sage_code() # optional -- internet + sage: s = oeis.find_by_id('A027642') # optional -- internet + sage: s.test_compile_sage_code() # optional -- internet True One dead sequence:: - sage: s = oeis.find_by_id('A000154') # optional -- internet - sage: s.test_compile_sage_code() # optional -- internet + sage: s = oeis.find_by_id('A000154') # optional -- internet + sage: s.test_compile_sage_code() # optional -- internet doctest:warning ... RuntimeWarning: This sequence is dead: ... @@ -2032,7 +2037,7 @@ class FancyTuple(tuple): EXAMPLES:: sage: from sage.databases.oeis import FancyTuple - sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]) ; t + sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]); t 0: zero 1: one 2: two @@ -2050,14 +2055,14 @@ def __repr__(self): EXAMPLES:: sage: from sage.databases.oeis import FancyTuple - sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]) ; t + sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]); t 0: zero 1: one 2: two 3: three 4: 4 - sage: t = FancyTuple(['Français', 'Español', '中文']) ; t + sage: t = FancyTuple(['Français', 'Español', '中文']); t 0: Français 1: Español 2: 中文 diff --git a/src/sage/databases/stein_watkins.py b/src/sage/databases/stein_watkins.py index 2936fd6da1d..167fa3a195b 100644 --- a/src/sage/databases/stein_watkins.py +++ b/src/sage/databases/stein_watkins.py @@ -44,12 +44,13 @@ We type ``next(d)`` to get each isogeny class of curves from ``d``:: - sage: C = next(d) # optional - database_stein_watkins - sage: C # optional - database_stein_watkins + sage: # optional - database_stein_watkins + sage: C = next(d) + sage: C Stein-Watkins isogeny class of conductor 11 - sage: next(d) # optional - database_stein_watkins + sage: next(d) Stein-Watkins isogeny class of conductor 14 - sage: next(d) # optional - database_stein_watkins + sage: next(d) Stein-Watkins isogeny class of conductor 15 An isogeny class has a number of attributes that give data about @@ -58,21 +59,22 @@ :: - sage: C.data # optional - database_stein_watkins + sage: # optional - database_stein_watkins + sage: C.data ['11', '[11]', '0', '0.253842', '25', '+*1'] - sage: C.curves # optional - database_stein_watkins + sage: C.curves [[[0, -1, 1, 0, 0], '(1)', '1', '5'], [[0, -1, 1, -10, -20], '(5)', '1', '5'], [[0, -1, 1, -7820, -263580], '(1)', '1', '1']] - sage: C.conductor # optional - database_stein_watkins + sage: C.conductor 11 - sage: C.leading_coefficient # optional - database_stein_watkins + sage: C.leading_coefficient '0.253842' - sage: C.modular_degree # optional - database_stein_watkins + sage: C.modular_degree '+*1' - sage: C.rank # optional - database_stein_watkins + sage: C.rank 0 - sage: C.isogeny_number # optional - database_stein_watkins + sage: C.isogeny_number '25' If we were to continue typing ``next(d)`` we would @@ -101,16 +103,17 @@ Each call ``next(d)`` gives another elliptic curve of prime conductor:: - sage: C = next(d) # optional - database_stein_watkins - sage: C # optional - database_stein_watkins + sage: # optional - database_stein_watkins + sage: C = next(d) + sage: C Stein-Watkins isogeny class of conductor 17 - sage: C.curves # optional - database_stein_watkins + sage: C.curves [[[1, -1, 1, -1, 0], '[1]', '1', '4'], [[1, -1, 1, -6, -4], '[2]', '1', '2x'], [[1, -1, 1, -1, -14], '(4)', '1', '4'], [[1, -1, 1, -91, -310], '[1]', '1', '2']] - sage: C = next(d) # optional - database_stein_watkins - sage: C # optional - database_stein_watkins + sage: C = next(d) + sage: C Stein-Watkins isogeny class of conductor 19 REFERENCE: diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 97a16b9452a..236822c7a32 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -15,6 +15,7 @@ This module provides a function, :func:`fast_callable`, to transform such expressions into a form where they can be evaluated quickly:: + sage: # needs sage.symbolic sage: f = sin(x) + 3*x^2 sage: ff = fast_callable(f, vars=[x]) sage: ff(3.5) @@ -29,18 +30,19 @@ huge win over sage.calculus, which evidently has a lot of overhead. Compare the cost of evaluating Wilkinson's polynomial (in unexpanded form) at x=30:: + sage: # needs sage.symbolic sage: wilk = prod((x-i) for i in [1 .. 20]); wilk (x - 1)*(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)*(x - 20) - sage: timeit('wilk.subs(x=30)') # random, long time + sage: timeit('wilk.subs(x=30)') # random # long time 625 loops, best of 3: 1.43 ms per loop sage: fc_wilk = fast_callable(wilk, vars=[x]) - sage: timeit('fc_wilk(30)') # random, long time + sage: timeit('fc_wilk(30)') # random # long time 625 loops, best of 3: 9.72 us per loop You can specify a particular domain for the evaluation using ``domain=``:: - sage: fc_wilk_zz = fast_callable(wilk, vars=[x], domain=ZZ) + sage: fc_wilk_zz = fast_callable(wilk, vars=[x], domain=ZZ) # needs sage.symbolic The meaning of domain=D is that each intermediate and final result is converted to type D. For instance, the previous example of @@ -58,7 +60,7 @@ the correct parent before we call D. We don't yet have a special interpreter with domain ZZ, so we can see how that compares to the generic fc_wilk example above:: - sage: timeit('fc_wilk_zz(30)') # random, long time + sage: timeit('fc_wilk_zz(30)') # random # long time # needs sage.symbolic 625 loops, best of 3: 15.4 us per loop However, for other types, using domain=D will get a large speedup, @@ -68,8 +70,8 @@ operation will be floating-point, we can just execute the floating-point operations directly and skip all the Python object creations that you would get from actually using RDF objects:: - sage: fc_wilk_rdf = fast_callable(wilk, vars=[x], domain=RDF) - sage: timeit('fc_wilk_rdf(30.0)') # random, long time + sage: fc_wilk_rdf = fast_callable(wilk, vars=[x], domain=RDF) # needs sage.symbolic + sage: timeit('fc_wilk_rdf(30.0)') # random # long time # needs sage.symbolic 625 loops, best of 3: 7 us per loop The domain does not need to be a Sage type; for instance, domain=float @@ -78,27 +80,27 @@ and domain=RDF; the only difference is that when domain=RDF is used, the return value is an RDF element, and when domain=float is used, the return value is a Python float.) :: - sage: fc_wilk_float = fast_callable(wilk, vars=[x], domain=float) - sage: timeit('fc_wilk_float(30.0)') # random, long time + sage: fc_wilk_float = fast_callable(wilk, vars=[x], domain=float) # needs sage.symbolic + sage: timeit('fc_wilk_float(30.0)') # random # long time # needs sage.symbolic 625 loops, best of 3: 5.04 us per loop We also have support for ``RR``:: - sage: fc_wilk_rr = fast_callable(wilk, vars=[x], domain=RR) - sage: timeit('fc_wilk_rr(30.0)') # random, long time + sage: fc_wilk_rr = fast_callable(wilk, vars=[x], domain=RR) # needs sage.symbolic + sage: timeit('fc_wilk_rr(30.0)') # random # long time # needs sage.symbolic 625 loops, best of 3: 13 us per loop For ``CC``:: - sage: fc_wilk_cc = fast_callable(wilk, vars=[x], domain=CC) - sage: timeit('fc_wilk_cc(30.0)') # random, long time + sage: fc_wilk_cc = fast_callable(wilk, vars=[x], domain=CC) # needs sage.symbolic + sage: timeit('fc_wilk_cc(30.0)') # random # long time # needs sage.symbolic 625 loops, best of 3: 23 us per loop And support for ``CDF``:: - sage: fc_wilk_cdf = fast_callable(wilk, vars=[x], domain=CDF) - sage: timeit('fc_wilk_cdf(30.0)') # random, long time + sage: fc_wilk_cdf = fast_callable(wilk, vars=[x], domain=CDF) # needs sage.symbolic + sage: timeit('fc_wilk_cdf(30.0)') # random # long time # needs sage.symbolic 625 loops, best of 3: 10.2 us per loop Currently, :func:`fast_callable` can accept two kinds of objects: @@ -122,6 +124,7 @@ ordering (you can include extra variable names here, too). :: For symbolic expressions, you need to specify the variable names, so that :func:`fast_callable` knows what order to use. :: + sage: # needs sage.symbolic sage: var('y,z,x') (y, z, x) sage: f = 10*y + 100*z + x @@ -131,8 +134,8 @@ that :func:`fast_callable` knows what order to use. :: You can also specify extra variable names:: - sage: ff = fast_callable(f, vars=('x','w','z','y')) - sage: ff(1,2,3,4) + sage: ff = fast_callable(f, vars=('x','w','z','y')) # needs sage.symbolic + sage: ff(1,2,3,4) # needs sage.symbolic 341 This should be enough for normal use of :func:`fast_callable`; let's @@ -178,8 +181,9 @@ expression trees, and returns an expression tree representing the function call. :: sage: v3 = etb.call(sin, v1+v2) - sage: v3 - sin(add(add(mul(add(v_0, v_1), add(v_1, v_1)), floordiv(v_1, v_1)), add(mul(3.14159000000000, v_0), mul(1729, v_1)))) + sage: v3 # needs sage.symbolic + sin(add(add(mul(add(v_0, v_1), add(v_1, v_1)), floordiv(v_1, v_1)), + add(mul(3.14159000000000, v_0), mul(1729, v_1)))) Many sage/Python built-in functions are specially handled; for instance, when evaluating an expression involving :func:`sin` over ``RDF``, @@ -201,15 +205,15 @@ expression tree built up using the methods described above. EXAMPLES:: - sage: var('x') + sage: var('x') # needs sage.symbolic x - sage: f = fast_callable(sqrt(x^7+1), vars=[x], domain=float) + sage: f = fast_callable(sqrt(x^7+1), vars=[x], domain=float) # needs sage.symbolic :: - sage: f(1) + sage: f(1) # needs sage.symbolic 1.4142135623730951 - sage: f.op_list() + sage: f.op_list() # needs sage.symbolic [('load_arg', 0), ('ipow', 7), ('load_const', 1.0), 'add', 'sqrt', 'return'] To interpret that last line, we load argument 0 ('x' in this case) onto @@ -225,7 +229,9 @@ Here we take sin of the first argument and add it to f:: sage: f = etb.call(sqrt, x^7 + 1) sage: g = etb.call(sin, x) sage: fast_callable(f+g).op_list() - [('load_arg', 0), ('ipow', 7), ('load_const', 1), 'add', ('py_call', , 1), ('load_arg', 0), ('py_call', sin, 1), 'add', 'return'] + [('load_arg', 0), ('ipow', 7), ('load_const', 1), 'add', + ('py_call', , 1), ('load_arg', 0), ('py_call', sin, 1), + 'add', 'return'] AUTHOR: @@ -261,7 +267,7 @@ AUTHOR: sage: c = etb.var('c') sage: for i in range(16): ....: z = z*z + c - sage: mand = fast_callable(z, domain=CDF) + sage: mand = fast_callable(z, domain=CDF) # needs sage.rings.complex_double Now ``ff`` does 32 complex arithmetic operations on each call (16 additions and 16 multiplications). However, if ``z*z`` produced @@ -335,6 +341,7 @@ def fast_callable(x, domain=None, vars=None, EXAMPLES:: + sage: # needs sage.symbolic sage: var('x') x sage: expr = sin(x) + 3*x^2 @@ -350,6 +357,7 @@ def fast_callable(x, domain=None, vars=None, the RDF interpreter; elements of RDF just don't display all their digits. We have special fast interpreter for domain=CDF:: + sage: # needs sage.symbolic sage: f_float = fast_callable(expr, vars=[x], domain=float) sage: f_float(2) 12.909297426825681 @@ -364,23 +372,34 @@ def fast_callable(x, domain=None, vars=None, sage: f = fast_callable(expr, vars=('z','x','y')) sage: f(1, 2, 3) sin(2) + 12 + sage: K. = QQ[] sage: p = -1/4*x^6 + 1/2*x^5 - x^4 - 12*x^3 + 1/2*x^2 - 1/95*x - 1/2 sage: fp = fast_callable(p, domain=RDF) sage: fp.op_list() - [('load_arg', 0), ('load_const', -0.25), 'mul', ('load_const', 0.5), 'add', ('load_arg', 0), 'mul', ('load_const', -1.0), 'add', ('load_arg', 0), 'mul', ('load_const', -12.0), 'add', ('load_arg', 0), 'mul', ('load_const', 0.5), 'add', ('load_arg', 0), 'mul', ('load_const', -0.010526315789473684), 'add', ('load_arg', 0), 'mul', ('load_const', -0.5), 'add', 'return'] + [('load_arg', 0), ('load_const', -0.25), 'mul', ('load_const', 0.5), 'add', + ('load_arg', 0), 'mul', ('load_const', -1.0), 'add', ('load_arg', 0), 'mul', + ('load_const', -12.0), 'add', ('load_arg', 0), 'mul', ('load_const', 0.5), + 'add', ('load_arg', 0), 'mul', ('load_const', -0.010526315789473684), + 'add', ('load_arg', 0), 'mul', ('load_const', -0.5), 'add', 'return'] sage: fp(3.14159) -552.4182988917153 + sage: K. = QQ[] sage: p = x*y^2 + 1/3*y^2 - x*z - y*z sage: fp = fast_callable(p, domain=RDF) sage: fp.op_list() - [('load_const', 0.0), ('load_const', 1.0), ('load_arg', 0), ('ipow', 1), ('load_arg', 1), ('ipow', 2), 'mul', 'mul', 'add', ('load_const', 0.3333333333333333), ('load_arg', 1), ('ipow', 2), 'mul', 'add', ('load_const', -1.0), ('load_arg', 0), ('ipow', 1), ('load_arg', 2), ('ipow', 1), 'mul', 'mul', 'add', ('load_const', -1.0), ('load_arg', 1), ('ipow', 1), ('load_arg', 2), ('ipow', 1), 'mul', 'mul', 'add', 'return'] - sage: fp(e, pi, sqrt(2)) # abs tol 3e-14 + [('load_const', 0.0), ('load_const', 1.0), ('load_arg', 0), ('ipow', 1), + ('load_arg', 1), ('ipow', 2), 'mul', 'mul', 'add', + ('load_const', 0.3333333333333333), ('load_arg', 1), ('ipow', 2), 'mul', 'add', + ('load_const', -1.0), ('load_arg', 0), ('ipow', 1), ('load_arg', 2), + ('ipow', 1), 'mul', 'mul', 'add', ('load_const', -1.0), ('load_arg', 1), + ('ipow', 1), ('load_arg', 2), ('ipow', 1), 'mul', 'mul', 'add', 'return'] + sage: fp(e, pi, sqrt(2)) # abs tol 3e-14 # needs sage.symbolic 21.831120464939584 - sage: symbolic_result = p(e, pi, sqrt(2)); symbolic_result + sage: symbolic_result = p(e, pi, sqrt(2)); symbolic_result # needs sage.symbolic pi^2*e + 1/3*pi^2 - sqrt(2)*pi - sqrt(2)*e - sage: n(symbolic_result) + sage: n(symbolic_result) # needs sage.symbolic 21.8311204649396 :: @@ -398,7 +417,9 @@ def fast_callable(x, domain=None, vars=None, Check that fast_callable also works for symbolic functions with evaluation functions:: - sage: def evalf_func(self, x, y, parent): return parent(x*y) if parent is not None else x*y + sage: # needs sage.symbolic + sage: def evalf_func(self, x, y, parent): + ....: return parent(x*y) if parent is not None else x*y sage: x,y = var('x,y') sage: f = function('f', evalf_func=evalf_func) sage: fc = fast_callable(f(x, y), vars=[x, y]) @@ -407,7 +428,9 @@ def fast_callable(x, domain=None, vars=None, And also when there are complex values involved:: - sage: def evalf_func(self, x, y, parent): return parent(I*x*y) if parent is not None else I*x*y + sage: # needs sage.symbolic + sage: def evalf_func(self, x, y, parent): + ....: return parent(I*x*y) if parent is not None else I*x*y sage: g = function('g', evalf_func=evalf_func) sage: fc = fast_callable(g(x, y), vars=[x, y]) sage: fc(3, 4) @@ -503,7 +526,7 @@ def _builder_and_stream(vars, domain): interpreter:: sage: domain = RDF - sage: from sage.structure.element import Element as domain # needs sage.modules + sage: from sage.structure.element import Element as domain sage: _builder_and_stream(["x", "y"], domain) (, ) @@ -568,7 +591,7 @@ def function_name(fn): sage: from sage.ext.fast_callable import function_name sage: function_name(operator.pow) 'pow' - sage: function_name(cos) + sage: function_name(cos) # needs sage.symbolic 'cos' sage: function_name(factorial) '{factorial}' @@ -675,9 +698,9 @@ cdef class ExpressionTreeBuilder: sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder('x') - sage: var('x') + sage: var('x') # needs sage.symbolic x - sage: etb._clean_var(x) + sage: etb._clean_var(x) # needs sage.symbolic 'x' sage: x = polygen(RR); x x @@ -700,10 +723,10 @@ cdef class ExpressionTreeBuilder: sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder('x') - sage: etb.constant(pi) + sage: etb.constant(pi) # needs sage.symbolic pi - sage: etb = ExpressionTreeBuilder('x', domain=RealField(200)) - sage: etb.constant(pi) + sage: etb = ExpressionTreeBuilder('x', domain=RealField(200)) # needs sage.rings.real_mpfr + sage: etb.constant(pi) # needs sage.rings.real_mpfr sage.symbolic 3.1415926535897932384626433832795028841971693993751058209749 """ if self._domain is not None: @@ -717,6 +740,7 @@ cdef class ExpressionTreeBuilder: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: var('a,b,some_really_long_name') (a, b, some_really_long_name) @@ -774,6 +798,7 @@ cdef class ExpressionTreeBuilder: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: etb.call(cos, x) @@ -803,8 +828,8 @@ cdef class ExpressionTreeBuilder: EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb.choice(etb.call(operator.eq, x, 0), 0, 1/x) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb.choice(etb.call(operator.eq, x, 0), 0, 1/x) # needs sage.symbolic (0 if {eq}(v_0, 0) else div(1, v_0)) """ return ExpressionChoice(self, @@ -840,6 +865,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb.var(x) @@ -866,10 +892,10 @@ cdef class Expression: EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: v = etb(3); v # indirect doctest + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: v = etb(3); v # indirect doctest # needs sage.symbolic 3 - sage: v._get_etb() is etb + sage: v._get_etb() is etb # needs sage.symbolic True """ self._etb = etb @@ -881,10 +907,10 @@ cdef class Expression: EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: v = etb(3); v + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: v = etb(3); v # needs sage.symbolic 3 - sage: v._get_etb() is etb + sage: v._get_etb() is etb # needs sage.symbolic True """ return self._etb @@ -895,6 +921,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -917,6 +944,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -939,6 +967,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -961,6 +990,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -983,6 +1013,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1008,6 +1039,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1048,6 +1080,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1064,6 +1097,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1082,6 +1116,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1100,6 +1135,7 @@ cdef class Expression: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1118,8 +1154,8 @@ cdef class ExpressionConstant(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: type(etb(3)) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: type(etb(3)) # needs sage.symbolic """ @@ -1131,6 +1167,7 @@ cdef class ExpressionConstant(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, ExpressionConstant sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: etb(3) @@ -1154,8 +1191,8 @@ cdef class ExpressionConstant(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb(3).value() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb(3).value() # needs sage.symbolic 3 """ return self._value @@ -1167,6 +1204,7 @@ cdef class ExpressionConstant(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: v = etb.constant(pi) @@ -1186,8 +1224,8 @@ cdef class ExpressionVariable(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: type(etb.var(x)) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: type(etb.var(x)) # needs sage.symbolic """ cdef int _variable_index @@ -1198,6 +1236,7 @@ cdef class ExpressionVariable(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, ExpressionVariable sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: etb(x) @@ -1219,8 +1258,8 @@ cdef class ExpressionVariable(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb(x).variable_index() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb(x).variable_index() # needs sage.symbolic 0 """ return self._variable_index @@ -1231,6 +1270,7 @@ cdef class ExpressionVariable(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: v = etb._var_number(0) @@ -1253,8 +1293,8 @@ cdef class ExpressionCall(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: type(etb.call(sin, x)) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: type(etb.call(sin, x)) # needs sage.symbolic """ cdef object _function @@ -1266,6 +1306,7 @@ cdef class ExpressionCall(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, ExpressionCall sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1291,8 +1332,8 @@ cdef class ExpressionCall(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb.call(sin, x).function() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb.call(sin, x).function() # needs sage.symbolic sin """ return self._function @@ -1304,8 +1345,8 @@ cdef class ExpressionCall(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb.call(sin, x).arguments() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb.call(sin, x).arguments() # needs sage.symbolic [v_0] """ return copy(self._arguments) @@ -1316,6 +1357,7 @@ cdef class ExpressionCall(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb.var(x) @@ -1342,8 +1384,8 @@ cdef class ExpressionIPow(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: type(etb.var('x')^17) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: type(etb.var('x')^17) # needs sage.symbolic """ cdef object _base @@ -1355,6 +1397,7 @@ cdef class ExpressionIPow(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, ExpressionIPow sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1380,8 +1423,8 @@ cdef class ExpressionIPow(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: (etb(33)^42).base() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: (etb(33)^42).base() # needs sage.symbolic 33 """ return self._base @@ -1393,8 +1436,8 @@ cdef class ExpressionIPow(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: (etb(x)^(-1)).exponent() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: (etb(x)^(-1)).exponent() # needs sage.symbolic -1 """ return self._exponent @@ -1405,6 +1448,7 @@ cdef class ExpressionIPow(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb.var(x) @@ -1431,8 +1475,8 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: etb.choice(etb.call(operator.eq, x, 0), 0, 1/x) + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: etb.choice(etb.call(operator.eq, x, 0), 0, 1/x) # needs sage.symbolic (0 if {eq}(v_0, 0) else div(1, v_0)) """ @@ -1446,6 +1490,7 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, ExpressionChoice sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1474,9 +1519,9 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: x = etb(x) - sage: etb.choice(x, ~x, 0).condition() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: x = etb(x) # needs sage.symbolic + sage: etb.choice(x, ~x, 0).condition() # needs sage.symbolic v_0 """ return self._cond @@ -1488,9 +1533,9 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: x = etb(x) - sage: etb.choice(x, ~x, 0).if_true() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: x = etb(x) # needs sage.symbolic + sage: etb.choice(x, ~x, 0).if_true() # needs sage.symbolic inv(v_0) """ return self._iftrue @@ -1502,9 +1547,9 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder - sage: etb = ExpressionTreeBuilder(vars=(x,)) - sage: x = etb(x) - sage: etb.choice(x, ~x, 0).if_false() + sage: etb = ExpressionTreeBuilder(vars=(x,)) # needs sage.symbolic + sage: x = etb(x) # needs sage.symbolic + sage: etb.choice(x, ~x, 0).if_false() # needs sage.symbolic 0 """ return self._iffalse @@ -1516,6 +1561,7 @@ cdef class ExpressionChoice(Expression): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=(x,)) sage: x = etb(x) @@ -1539,19 +1585,19 @@ cpdef _expression_binop_helper(s, o, op): EXAMPLES:: sage: from sage.ext.fast_callable import _expression_binop_helper, ExpressionTreeBuilder - sage: var('x,y') + sage: var('x,y') # needs sage.symbolic (x, y) - sage: etb = ExpressionTreeBuilder(vars=(x,y)) - sage: x = etb(x) + sage: etb = ExpressionTreeBuilder(vars=(x,y)) # needs sage.symbolic + sage: x = etb(x) # needs sage.symbolic Now x is an Expression, but y is not. Still, all the following cases work:: - sage: _expression_binop_helper(x, x, operator.add) + sage: _expression_binop_helper(x, x, operator.add) # needs sage.symbolic add(v_0, v_0) - sage: _expression_binop_helper(x, y, operator.add) + sage: _expression_binop_helper(x, y, operator.add) # needs sage.symbolic add(v_0, v_1) - sage: _expression_binop_helper(y, x, operator.add) + sage: _expression_binop_helper(y, x, operator.add) # needs sage.symbolic add(v_1, v_0) """ @@ -1595,9 +1641,9 @@ class IntegerPowerFunction(): sage: square = IntegerPowerFunction(2) sage: square (^2) - sage: square(pi) + sage: square(pi) # needs sage.symbolic pi^2 - sage: square(I) + sage: square(I) # needs sage.symbolic -1 sage: square(RIF(-1, 1)).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000]' @@ -1681,9 +1727,11 @@ cpdef dict get_builtin_functions(): sage: from sage.ext.fast_callable import get_builtin_functions sage: builtins = get_builtin_functions() - sage: sorted(set(builtins.values())) - ['abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] - sage: builtins[sin] + sage: sorted(set(builtins.values())) # needs sage.symbolic + ['abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', + 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', + 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] + sage: builtins[sin] # needs sage.symbolic 'sin' sage: builtins[ln] 'log' @@ -1736,9 +1784,11 @@ cpdef generate_code(Expression expr, InstructionStream stream): EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder, generate_code, InstructionStream + + sage: # needs sage.symbolic sage: etb = ExpressionTreeBuilder('x') sage: x = etb.var('x') - sage: expr = ((x+pi)*(x+1)) + sage: expr = (x+pi) * (x+1) sage: from sage.ext.interpreters.wrapper_py import metadata, Wrapper_py sage: instr_stream = InstructionStream(metadata, 1) sage: generate_code(expr, instr_stream) @@ -1756,6 +1806,8 @@ cpdef generate_code(Expression expr, InstructionStream stream): sage: def my_sqrt(x): ....: if x < 0: raise ValueError("sqrt of negative number") ....: return sqrt(x, extend=False) + + sage: # needs sage.symbolic sage: fc = fast_callable(expr, domain=RealField(130)) sage: fc(0) 3.1415926535897932384626433832795028842 @@ -1781,11 +1833,15 @@ cpdef generate_code(Expression expr, InstructionStream stream): sage: fc = fast_callable(etb.call(my_sin, x), domain=RDF) sage: fc(3) 0.1411200080598672 + + sage: # needs sage.rings.real_mpfr sage.symbolic sage: fc = fast_callable(etb.call(my_sin, x), domain=RealField(100)) sage: fc(3) 0.14112000805986722210074480281 sage: fc.op_list() [('load_arg', 0), ('py_call', , 1), 'return'] + + sage: # needs sage.symbolic sage: fc = fast_callable(etb.call(my_sqrt, x), domain=RDF) sage: fc(3) 1.7320508075688772 @@ -1802,6 +1858,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): Traceback (most recent call last): ... ValueError: sqrt of negative number + sage: etb2 = ExpressionTreeBuilder(('y','z')) sage: y = etb2.var('y') sage: z = etb2.var('z') @@ -1812,26 +1869,28 @@ cpdef generate_code(Expression expr, InstructionStream stream): [('load_arg', 0), ('load_arg', 1), ('py_call', , 2), 'sqrt', 'return'] sage: fc.python_calls() [] - sage: fc = fast_callable(etb2.call(sqrt, etb2.call(my_norm, y, z)), domain=RR) - sage: fc(3, 4) + sage: fc = fast_callable(etb2.call(sqrt, etb2.call(my_norm, y, z)), domain=RR) # needs sage.rings.real_mpfr + sage: fc(3, 4) # needs sage.rings.real_mpfr 5.00000000000000 sage: fc = fast_callable(etb2.call(my_norm, y, z), domain=ZZ) sage: fc(3, 4) 25 sage: fc.op_list() [('load_arg', 0), ('load_arg', 1), ('py_call', , 2), 'return'] - sage: fc = fast_callable(expr) # needs sage.symbolic - sage: fc(3.0r) # needs sage.symbolic + + sage: # needs sage.symbolic + sage: fc = fast_callable(expr) + sage: fc(3.0r) 4.0*pi + 12.0 - sage: fc = fast_callable(x+3, domain=ZZ) # needs sage.symbolic - sage: fc(4) # needs sage.symbolic + sage: fc = fast_callable(x+3, domain=ZZ) + sage: fc(4) 7 - sage: fc = fast_callable(x/3, domain=ZZ) # needs sage.symbolic - sage: fc(4) # needs sage.symbolic + sage: fc = fast_callable(x/3, domain=ZZ) + sage: fc(4) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: fc(6) # needs sage.symbolic + sage: fc(6) 2 sage: fc = fast_callable(etb.call(sin, x), domain=ZZ) sage: fc(0) @@ -1843,6 +1902,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): :: + sage: # needs sage.symbolic sage: fc = fast_callable(etb(x)^100) sage: fc(pi) pi^100 @@ -1857,18 +1917,18 @@ cpdef generate_code(Expression expr, InstructionStream stream): [('load_arg', 0), ('ipow', 100), 'return'] sage: fc(1.1) 13780.61233982... - sage: fc = fast_callable(etb(x)^100, domain=RR) - sage: fc.op_list() + sage: fc = fast_callable(etb(x)^100, domain=RR) # needs sage.rings.real_mpfr + sage: fc.op_list() # needs sage.rings.real_mpfr [('load_arg', 0), ('ipow', 100), 'return'] - sage: fc(1.1) + sage: fc(1.1) # needs sage.rings.real_mpfr 13780.6123398224 sage: fc = fast_callable(etb(x)^(-100), domain=RDF) sage: fc.op_list() [('load_arg', 0), ('ipow', -100), 'return'] sage: fc(1.1) 7.25657159014...e-05 - sage: fc = fast_callable(etb(x)^(-100), domain=RR) - sage: fc(1.1) + sage: fc = fast_callable(etb(x)^(-100), domain=RR) # needs sage.rings.real_mpfr + sage: fc(1.1) # needs sage.rings.real_mpfr 0.0000725657159014814 sage: expo = 2^32 sage: base = (1.0).nextabove() @@ -1879,10 +1939,10 @@ cpdef generate_code(Expression expr, InstructionStream stream): 1.0000009536747712 sage: RDF(base)^expo 1.0000009536747712 - sage: fc = fast_callable(etb(x)^expo, domain=RR) - sage: fc.op_list() + sage: fc = fast_callable(etb(x)^expo, domain=RR) # needs sage.rings.real_mpfr + sage: fc.op_list() # needs sage.rings.real_mpfr [('load_arg', 0), ('py_call', (^4294967296), 1), 'return'] - sage: fc(base) + sage: fc(base) # needs sage.rings.real_mpfr 1.00000095367477 sage: base^expo 1.00000095367477 @@ -1890,6 +1950,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): Make sure we do not overflow the stack with highly nested expressions (:trac:`11766`):: + sage: # needs sage.rings.real_mpfr sage: R. = CC[] sage: f = R(list(range(100000))) sage: ff = fast_callable(f) @@ -2005,7 +2066,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.get_current() @@ -2041,7 +2103,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream, op_list sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.load_const(5) @@ -2066,7 +2129,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 12) sage: instr_stream.load_arg(5) @@ -2085,7 +2149,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.has_instr('return') @@ -2108,11 +2173,12 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.instr('load_arg', 0) - sage: instr_stream.instr('sin') + sage: instr_stream.instr('sin') # needs sage.symbolic sage: instr_stream.instr('py_call', math.sin, 1) sage: instr_stream.instr('abs') sage: instr_stream.instr('factorial') @@ -2120,7 +2186,7 @@ cdef class InstructionStream: ... KeyError: 'factorial' sage: instr_stream.instr('return') - sage: instr_stream.current_op_list() + sage: instr_stream.current_op_list() # needs sage.symbolic [('load_arg', 0), 'sin', ('py_call', , 1), 'abs', 'return'] """ self.instr0(opname, args) @@ -2186,7 +2252,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: md = instr_stream.get_metadata() @@ -2204,7 +2271,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.instr('load_arg', 0) @@ -2226,7 +2294,8 @@ cdef class InstructionStream: EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.get_current() @@ -2374,7 +2443,8 @@ def op_list(args, metadata): EXAMPLES:: - sage: from sage.ext.interpreters.wrapper_rdf import metadata + sage: from sage.ext.interpreters.wrapper_el import metadata + sage: from sage.ext.interpreters.wrapper_rdf import metadata # needs sage.modules sage: from sage.ext.fast_callable import InstructionStream, op_list sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.instr('load_arg', 0) @@ -2418,10 +2488,11 @@ cdef class Wrapper: EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import ExpressionTreeBuilder, generate_code, InstructionStream sage: etb = ExpressionTreeBuilder('x') sage: x = etb.var('x') - sage: expr = ((x+pi)*(x+1)) + sage: expr = (x+pi) * (x+1) sage: from sage.ext.interpreters.wrapper_py import metadata, Wrapper_py sage: instr_stream = InstructionStream(metadata, 1) sage: generate_code(expr, instr_stream) @@ -2454,7 +2525,7 @@ cdef class Wrapper: EXAMPLES:: - sage: fast_callable(sin(x)/x, vars=[x], domain=RDF).get_orig_args() + sage: fast_callable(sin(x)/x, vars=[x], domain=RDF).get_orig_args() # needs sage.symbolic {'args': 1, 'code': [0, 0, 16, 0, 0, 8, 2], 'constants': [], @@ -2470,7 +2541,7 @@ cdef class Wrapper: EXAMPLES:: - sage: fast_callable(cos(x)*x, vars=[x], domain=RDF).op_list() + sage: fast_callable(cos(x) * x, vars=[x], domain=RDF).op_list() # needs sage.symbolic [('load_arg', 0), ('load_arg', 0), 'cos', 'mul', 'return'] """ return op_list(self._orig_args, self._metadata) @@ -2486,9 +2557,9 @@ cdef class Wrapper: EXAMPLES:: - sage: fast_callable(abs(sin(x)), vars=[x], domain=RDF).python_calls() + sage: fast_callable(abs(sin(x)), vars=[x], domain=RDF).python_calls() # needs sage.symbolic [] - sage: fast_callable(abs(sin(factorial(x))), vars=[x]).python_calls() + sage: fast_callable(abs(sin(factorial(x))), vars=[x]).python_calls() # needs sage.symbolic [factorial, sin] """ ops = self.op_list() @@ -2557,6 +2628,7 @@ class FastCallableFloatWrapper: An error is thrown if the answer is complex:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import FastCallableFloatWrapper sage: f = sqrt(x) sage: ff = fast_callable(f, vars=[x], domain=CDF) @@ -2595,6 +2667,7 @@ class FastCallableFloatWrapper: The wrapper will ignore an imaginary part smaller in magnitude than ``imag_tol``, but not one larger:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import FastCallableFloatWrapper sage: f = x sage: ff = fast_callable(f, vars=[x], domain=CDF) @@ -2622,6 +2695,7 @@ class FastCallableFloatWrapper: Evaluation either returns a ``float``, or raises a ``ValueError``:: + sage: # needs sage.symbolic sage: from sage.ext.fast_callable import FastCallableFloatWrapper sage: f = x sage: ff = fast_callable(f, vars=[x], domain=CDF) diff --git a/src/sage/ext/fast_eval.pyx b/src/sage/ext/fast_eval.pyx index 7b45ea1c5a0..52fbc8f7406 100644 --- a/src/sage/ext/fast_eval.pyx +++ b/src/sage/ext/fast_eval.pyx @@ -51,14 +51,15 @@ def fast_float(f, *vars, old=None, expect_one_var=False): EXAMPLES:: sage: from sage.ext.fast_eval import fast_float - sage: x,y = var('x,y') - sage: f = fast_float(sqrt(x^2+y^2), 'x', 'y') - sage: f(3,4) + sage: x,y = var('x,y') # needs sage.symbolic + sage: f = fast_float(sqrt(x^2+y^2), 'x', 'y') # needs sage.symbolic + sage: f(3,4) # needs sage.symbolic 5.0 Specifying the argument names is essential, as fast_float objects only distinguish between arguments by order. :: + sage: # needs sage.symbolic sage: f = fast_float(x-y, 'x','y') sage: f(1,2) -1.0 diff --git a/src/sage/ext/memory_allocator.pxd b/src/sage/ext/memory_allocator.pxd index c4f2028f4e4..f96253345f6 100644 --- a/src/sage/ext/memory_allocator.pxd +++ b/src/sage/ext/memory_allocator.pxd @@ -56,7 +56,7 @@ cdef class MemoryAllocator: TESTS:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.ext.memory_allocator cimport MemoryAllocator ....: cdef MemoryAllocator mem = MemoryAllocator() @@ -87,7 +87,7 @@ cdef class MemoryAllocator: TESTS:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.ext.memory_allocator cimport MemoryAllocator ....: def foo(): @@ -97,7 +97,7 @@ cdef class MemoryAllocator: ....: ptr = mem.aligned_calloc(2**i, i, 2**i) ....: assert ptr == ( ptr) & ~(2**i-1) ....: ''') - sage: foo() # optional - sage.misc.cython + sage: foo() # needs sage.misc.cython doctest:...: DeprecationWarning: this class is deprecated; use the class from the python package `memory_allocator` See https://github.com/sagemath/sage/issues/31591 for details. @@ -124,7 +124,7 @@ cdef class MemoryAllocator: TESTS:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.ext.memory_allocator cimport MemoryAllocator ....: def foo(): @@ -134,8 +134,8 @@ cdef class MemoryAllocator: ....: ptr = mem.aligned_allocarray(2**i, i, 2**i) ....: assert ptr == ( ptr) & ~(2**i-1) ....: ''') - sage: foo() # random # might raise deprecation warning # optional - sage.misc.cython - sage: foo() # optional - sage.misc.cython + sage: foo() # random # might raise deprecation warning # needs sage.misc.cython + sage: foo() # needs sage.misc.cython """ # Find extra such that (nmemb + extra) * size >= nmemb * size + alignment - 1 # ⇔ extra * size >= alignment - 1 diff --git a/src/sage/ext/memory_allocator.pyx b/src/sage/ext/memory_allocator.pyx index 1f271a3e82e..0c2814658e9 100644 --- a/src/sage/ext/memory_allocator.pyx +++ b/src/sage/ext/memory_allocator.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.misc.cython +# sage.doctest: needs sage.misc.cython from cysignals.memory cimport * from sage.misc.superseded import deprecation diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 97c612b4e45..5b8572d3f60 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -107,8 +107,8 @@ def __call__(self, f): sage: from sage.parallel.decorate import Parallel sage: p = Parallel() - sage: f = x^2-1 - sage: p(f) + sage: f = x^2 - 1 # needs sage.symbolic + sage: p(f) # needs sage.symbolic sage: P = sage.parallel.decorate.Parallel() @@ -342,7 +342,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): sage: @parallel(ncpus=3, timeout=10) ....: def fac(n): return factor(2^n-1) - sage: for X, Y in sorted(list(fac([101,119,151,197,209]))): print((X,Y)) + sage: for X, Y in sorted(list(fac([101,119,151,197,209]))): print((X,Y)) # needs sage.libs.pari (((101,), {}), 7432339208719 * 341117531003194129) (((119,), {}), 127 * 239 * 20231 * 131071 * 62983048367 * 131105292137) (((151,), {}), 18121 * 55871 * 165799 * 2332951 * 7289088383388253664437433) @@ -531,6 +531,7 @@ def fork(f=None, timeout=0, verbose=False): We illustrate that the state of the pexpect interface is not altered by forked functions (they get their own new pexpect interfaces!):: + sage: # needs sage.libs.pari sage: gp.eval('a = 5') '5' sage: @fork() @@ -545,21 +546,21 @@ def fork(f=None, timeout=0, verbose=False): We illustrate that the forked function has its own pexpect interface:: - sage: gp.eval('a = 15') + sage: gp.eval('a = 15') # needs sage.libs.pari '15' sage: @fork() ....: def g(): return gp.eval('a') - sage: g() + sage: g() # needs sage.libs.pari 'a' We illustrate that segfaulting subprocesses are no trouble at all:: - sage: cython('def f(): print(0)') # optional - sage.misc.cython + sage: cython('def f(): print(0)') # needs sage.misc.cython sage: @fork ....: def g(): ....: os.environ["CYSIGNALS_CRASH_NDEBUG"]="yes" # skip enhanced backtrace (it is slow) ....: f() - sage: print("this works"); g() # optional - sage.misc.cython + sage: print("this works"); g() # needs sage.misc.cython this works... ------------------------------------------------------------------------ diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 47833d9f386..11e0673ee91 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -184,8 +184,8 @@ Compare:: - sage: from sage.combinat.q_analogues import q_factorial - sage: q_factorial(5) + sage: from sage.combinat.q_analogues import q_factorial # needs sage.combinat + sage: q_factorial(5) # needs sage.combinat q^10 + 4*q^9 + 9*q^8 + 15*q^7 + 20*q^6 + 22*q^5 + 20*q^4 + 15*q^3 + 9*q^2 + 4*q + 1 * **Listing the objects.** One can also compute the list of objects in a @@ -1653,14 +1653,14 @@ def steal(self): sage: EX = RESetMPExample(maxl=6) sage: EX.setup_workers(2) + sage: # known bug (Issue #27537) sage: w0, w1 = EX._workers sage: w0._todo.append(42) sage: thief0 = Thread(target = w0._thief, name="Thief") - sage: thief0.start() # known bug (Issue #27537) - - sage: w1.steal() # known bug (Issue #27537) + sage: thief0.start() + sage: w1.steal() 42 - sage: w0._todo # known bug (Issue #27537) + sage: w0._todo deque([]) """ self._mapred._signal_task_done() diff --git a/src/sage/parallel/use_fork.py b/src/sage/parallel/use_fork.py index bf38df167f9..ce240acf9d8 100644 --- a/src/sage/parallel/use_fork.py +++ b/src/sage/parallel/use_fork.py @@ -301,7 +301,12 @@ def _subprocess(self, f, dir, args, kwds={}): # The pexpect interfaces (and objects defined in them) are # not valid. if self.reset_interfaces: - sage.interfaces.quit.invalidate_all() + try: + from sage.interfaces.quit import invalidate_all + except ImportError: + pass + else: + invalidate_all() # Now evaluate the function f. value = f(*args, **kwds) diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index 59f898ad830..a8b21530946 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -2088,13 +2088,20 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: F = RecursivelyEnumeratedSet(seeds, succ, ....: structure='forest', enumeration='depth') + sage: # needs sage.symbolic sage: y = var('y') sage: def map_function(t): ....: li, sum, _ = t ....: return y ^ sum - sage: reduce_function = lambda x,y: x + y + sage: def reduce_function(x, y): + ....: return x + y sage: F.map_reduce(map_function, reduce_function, 0) - y^45 + y^44 + y^43 + 2*y^42 + 2*y^41 + 3*y^40 + 4*y^39 + 5*y^38 + 6*y^37 + 8*y^36 + 9*y^35 + 10*y^34 + 12*y^33 + 13*y^32 + 15*y^31 + 17*y^30 + 18*y^29 + 19*y^28 + 21*y^27 + 21*y^26 + 22*y^25 + 23*y^24 + 23*y^23 + 23*y^22 + 23*y^21 + 22*y^20 + 21*y^19 + 21*y^18 + 19*y^17 + 18*y^16 + 17*y^15 + 15*y^14 + 13*y^13 + 12*y^12 + 10*y^11 + 9*y^10 + 8*y^9 + 6*y^8 + 5*y^7 + 4*y^6 + 3*y^5 + 2*y^4 + 2*y^3 + y^2 + y + y^45 + y^44 + y^43 + 2*y^42 + 2*y^41 + 3*y^40 + 4*y^39 + 5*y^38 + 6*y^37 + + 8*y^36 + 9*y^35 + 10*y^34 + 12*y^33 + 13*y^32 + 15*y^31 + 17*y^30 + + 18*y^29 + 19*y^28 + 21*y^27 + 21*y^26 + 22*y^25 + 23*y^24 + 23*y^23 + + 23*y^22 + 23*y^21 + 22*y^20 + 21*y^19 + 21*y^18 + 19*y^17 + 18*y^16 + + 17*y^15 + 15*y^14 + 13*y^13 + 12*y^12 + 10*y^11 + 9*y^10 + 8*y^9 + 6*y^8 + + 5*y^7 + 4*y^6 + 3*y^5 + 2*y^4 + 2*y^3 + y^2 + y Here is an example with the default values:: diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index cc65dcb7cc1..3859f24095a 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -36,14 +36,15 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) # optional - sage.modules - sage: M # optional - sage.modules + sage: # needs sage.modules + sage: M = FreeModule(ZZ, 4) + sage: M Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() # optional - sage.modules + sage: M.ngens() 4 - sage: M.gen(0) # optional - sage.modules + sage: M.gen(0) (1, 0, 0, 0) - sage: M.gens() # optional - sage.modules + sage: M.gens() ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -270,8 +271,8 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: B.gens_dict() # optional - sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: B.gens_dict() # needs sage.rings.polynomial.pbori {'a': a, 'b': b, 'c': c, 'd': d} TESTS:: @@ -351,16 +352,16 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: A. = ZZ.extension(x^2 + 1) # optional - sage.rings.number_field - sage: i # optional - sage.rings.number_field + sage: A. = ZZ.extension(x^2 + 1) # needs sage.rings.number_field + sage: i # needs sage.rings.number_field i - sage: parent(i) # optional - sage.rings.number_field + sage: parent(i) # needs sage.rings.number_field Order in Number Field in i with defining polynomial x^2 + 1 :: - sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field - sage: z.minpoly() # optional - sage.rings.number_field + sage: B. = EquationOrder(x^2 + 3) # needs sage.rings.number_field + sage: z.minpoly() # needs sage.rings.number_field x^2 + 3 """ return self._defining_names()[:n] @@ -388,18 +389,19 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field - sage: B._defining_names() # optional - sage.rings.number_field + sage: B. = EquationOrder(x^2 + 3) # needs sage.rings.number_field + sage: B._defining_names() # needs sage.rings.number_field (z,) For vector spaces and free modules, we get a basis (which can be different from the given generators):: - sage: V = ZZ^3 # optional - sage.modules - sage: V._defining_names() # optional - sage.modules + sage: # needs sage.modules + sage: V = ZZ^3 + sage: V._defining_names() ((1, 0, 0), (0, 1, 0), (0, 0, 1)) - sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) # optional - sage.modules - sage: W._defining_names() # optional - sage.modules + sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) + sage: W._defining_names() ((1/2, 0, 0), (0, 1, 0)) """ return self.gens() @@ -500,10 +502,11 @@ cdef class CategoryObject(SageObject): wants to print elements of the quotient of such an "unnamed" ring, an error resulted. That was fixed in :trac:`11068`:: - sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.rings.finite_rings sage.modules - sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS # optional - sage.rings.finite_rings sage.modules - sage: Q. = MS.quo(I) # optional - sage.rings.finite_rings sage.modules - sage: a #indirect doctest # optional - sage.rings.finite_rings sage.modules + sage: # needs sage.modules + sage: MS = MatrixSpace(GF(5), 2, 2) + sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS + sage: Q. = MS.quo(I) + sage: a #indirect doctest [1 0] [0 0] @@ -562,42 +565,44 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: from sage.modules.module import Module # optional - sage.modules - sage: Module(ZZ).base_ring() # optional - sage.modules + sage: from sage.modules.module import Module + sage: Module(ZZ).base_ring() Integer Ring - sage: F = FreeModule(ZZ, 3) # optional - sage.modules - sage: F.base_ring() # optional - sage.modules + sage: F = FreeModule(ZZ, 3) # needs sage.modules + sage: F.base_ring() # needs sage.modules Integer Ring - sage: F.__class__.base_ring # optional - sage.modules + sage: F.__class__.base_ring # needs sage.modules Note that the coordinates of the elements of a module can lie in a bigger ring, the ``coordinate_ring``:: - sage: M = (ZZ^2) * (1/2) # optional - sage.modules - sage: v = M([1/2, 0]) # optional - sage.modules - sage: v.base_ring() # optional - sage.modules + sage: # needs sage.modules + sage: M = (ZZ^2) * (1/2) + sage: v = M([1/2, 0]) + sage: v.base_ring() Integer Ring - sage: parent(v[0]) # optional - sage.modules + sage: parent(v[0]) Rational Field - sage: v.coordinate_ring() # optional - sage.modules + sage: v.coordinate_ring() Rational Field More examples:: - sage: F = FreeAlgebra(QQ, 'x') # optional - sage.combinat sage.modules - sage: F.base_ring() # optional - sage.combinat sage.modules + sage: F = FreeAlgebra(QQ, 'x') # needs sage.combinat sage.modules + sage: F.base_ring() # needs sage.combinat sage.modules Rational Field - sage: F.__class__.base_ring # optional - sage.combinat sage.modules + sage: F.__class__.base_ring # needs sage.combinat sage.modules - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules - sage: H = Hom(E, F) # optional - sage.modules - sage: H.base_ring() # optional - sage.modules + sage: # needs sage.modules + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) + sage: H = Hom(E, F) + sage: H.base_ring() Integer Ring - sage: H.__class__.base_ring # optional - sage.modules + sage: H.__class__.base_ring .. TODO:: @@ -893,8 +898,8 @@ cdef class CategoryObject(SageObject): _test_some_elements _test_zero _test_zero_divisors - sage: F = GF(9,'a') # optional - sage.rings.finite_rings - sage: dir(F) # optional - sage.rings.finite_rings + sage: F = GF(9,'a') # needs sage.rings.finite_rings + sage: dir(F) # needs sage.rings.finite_rings [..., '__class__', ..., '_test_pickling', ..., 'extension', ...] """ @@ -950,11 +955,11 @@ cpdef normalize_names(Py_ssize_t ngens, names): sage: nn(1, u'a') ('a',) - sage: var('alpha') + sage: var('alpha') # needs sage.symbolic alpha - sage: nn(2, alpha) + sage: nn(2, alpha) # needs sage.symbolic ('alpha0', 'alpha1') - sage: nn(1, [alpha]) + sage: nn(1, [alpha]) # needs sage.symbolic ('alpha',) With an unknown number of generators:: diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index b3081701b44..23638bf519e 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -35,9 +35,9 @@ On failure, a TypeError is always raised. Some arithmetic operations (such as multiplication) can indicate an action rather than arithmetic in a common parent. For example:: - sage: E = EllipticCurve('37a') # optional - sage.schemes - sage: P = E(0,0) # optional - sage.schemes - sage: 5*P # optional - sage.schemes + sage: E = EllipticCurve('37a') # needs sage.schemes + sage: P = E(0,0) # needs sage.schemes + sage: 5*P # needs sage.schemes (1/4 : -5/8 : 1) where there is action of `\ZZ` on the points of `E` given by the additive @@ -112,7 +112,7 @@ cpdef py_scalar_parent(py_type): Integer Ring sage: py_scalar_parent(float) Real Double Field - sage: py_scalar_parent(complex) + sage: py_scalar_parent(complex) # needs sage.rings.complex_double Complex Double Field sage: py_scalar_parent(bool) Integer Ring @@ -123,6 +123,7 @@ cpdef py_scalar_parent(py_type): sage: py_scalar_parent(fractions.Fraction) Rational Field + sage: # needs numpy sage: import numpy sage: py_scalar_parent(numpy.int16) Integer Ring @@ -130,15 +131,9 @@ cpdef py_scalar_parent(py_type): Integer Ring sage: py_scalar_parent(numpy.uint64) Integer Ring - - sage: py_scalar_parent(float) - Real Double Field sage: py_scalar_parent(numpy.double) Real Double Field - sage: py_scalar_parent(complex) - Complex Double Field - sage: import gmpy2 sage: py_scalar_parent(gmpy2.mpz) Integer Ring @@ -146,7 +141,7 @@ cpdef py_scalar_parent(py_type): Rational Field sage: py_scalar_parent(gmpy2.mpfr) Real Double Field - sage: py_scalar_parent(gmpy2.mpc) + sage: py_scalar_parent(gmpy2.mpc) # needs sage.rings.complex_double Complex Double Field """ if issubclass(py_type, int): @@ -208,8 +203,8 @@ cpdef py_scalar_to_element(x): sage: x = py_scalar_to_element(float(42)) sage: x, parent(x) (42.0, Real Double Field) - sage: x = py_scalar_to_element(complex(42)) - sage: x, parent(x) + sage: x = py_scalar_to_element(complex(42)) # needs sage.rings.complex_double + sage: x, parent(x) # needs sage.rings.complex_double (42.0, Complex Double Field) sage: py_scalar_to_element('hello') 'hello' @@ -236,31 +231,31 @@ cpdef py_scalar_to_element(x): sage: x = py_scalar_to_element(gmpy2.mpfr(42.57)) sage: x, parent(x) (42.57, Real Double Field) - sage: x = py_scalar_to_element(gmpy2.mpc(int(42), int(42))) - sage: x, parent(x) + sage: x = py_scalar_to_element(gmpy2.mpc(int(42), int(42))) # needs sage.rings.complex_double + sage: x, parent(x) # needs sage.rings.complex_double (42.0 + 42.0*I, Complex Double Field) Test compatibility with :func:`py_scalar_parent`:: sage: from sage.structure.coerce import py_scalar_parent sage: elt = [True, int(42), float(42), complex(42)] - sage: for x in elt: + sage: for x in elt: # needs sage.rings.complex_double ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() - sage: import numpy - sage: elt = [numpy.int8('-12'), numpy.uint8('143'), + sage: import numpy # needs numpy + sage: elt = [numpy.int8('-12'), numpy.uint8('143'), # needs numpy ....: numpy.int16('-33'), numpy.uint16('122'), ....: numpy.int32('-19'), numpy.uint32('44'), ....: numpy.int64('-3'), numpy.uint64('552'), ....: numpy.float16('-1.23'), numpy.float32('-2.22'), ....: numpy.float64('-3.412'), numpy.complex64(1.2+I), ....: numpy.complex128(-2+I)] - sage: for x in elt: # optional - numpy + sage: for x in elt: # needs numpy ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() sage: elt = [gmpy2.mpz(42), gmpy2.mpq('3/4'), ....: gmpy2.mpfr(42.57), gmpy2.mpc(int(42), int(42))] - sage: for x in elt: + sage: for x in elt: # needs sage.rings.complex_double ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() """ if isinstance(x, Element): @@ -322,10 +317,10 @@ cpdef bint parent_is_integers(P) except -1: sage: parent_is_integers(dict) False - sage: import numpy - sage: parent_is_integers(numpy.int16) + sage: import numpy # needs numpy + sage: parent_is_integers(numpy.int16) # needs numpy True - sage: parent_is_integers(numpy.uint64) + sage: parent_is_integers(numpy.uint64) # needs numpy True sage: parent_is_integers(float) False @@ -365,17 +360,19 @@ def parent_is_numerical(P): sage: from sage.structure.coerce import parent_is_numerical sage: import gmpy2 - sage: [parent_is_numerical(R) for R in [RR, CC, QQ, int, complex, gmpy2.mpc]] - [True, True, True, True, True, True] - sage: parent_is_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + sage: [parent_is_numerical(R) for R in [QQ, int, complex, gmpy2.mpc]] # needs sage.rings.complex_double + [True, True, True, True] + sage: [parent_is_numerical(R) for R in [RR, CC]] # needs sage.rings.real_mpfr + [True, True] + sage: parent_is_numerical(QuadraticField(-1)) # needs sage.rings.number_field True - sage: import numpy; parent_is_numerical(numpy.complexfloating) # optional - numpy + sage: import numpy; parent_is_numerical(numpy.complexfloating) # needs numpy True - sage: parent_is_numerical(SR) # optional - sage.symbolic + sage: parent_is_numerical(SR) # needs sage.symbolic False sage: [parent_is_numerical(R) for R in [QQ['x'], QQ[['x']], str]] [False, False, False] - sage: [parent_is_numerical(R) for R in [RIF, RBF, CIF, CBF]] + sage: [parent_is_numerical(R) for R in [RIF, RBF, CIF, CBF]] # needs sage.libs.flint [False, False, False, False] """ if not isinstance(P, Parent): @@ -395,20 +392,20 @@ def parent_is_real_numerical(P): sage: import gmpy2 sage: [parent_is_real_numerical(R) for R in [RR, QQ, ZZ, RLF, int, float, gmpy2.mpq]] [True, True, True, True, True, True, True] - sage: parent_is_real_numerical(QuadraticField(2)) # optional - sage.rings.number_field + sage: parent_is_real_numerical(QuadraticField(2)) # needs sage.rings.number_field True - sage: import numpy; parent_is_real_numerical(numpy.integer) # optional - numpy + sage: import numpy; parent_is_real_numerical(numpy.integer) # needs numpy True - sage: parent_is_real_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + sage: parent_is_real_numerical(QuadraticField(-1)) # needs sage.rings.number_field False - sage: [parent_is_real_numerical(R) + sage: [parent_is_real_numerical(R) # needs numpy ....: for R in [CC, complex, gmpy2.mpc, numpy.complexfloating]] [False, False, False, False] sage: [parent_is_real_numerical(R) for R in [QQ['x'], QQ[['x']], str]] [False, False, False] - sage: parent_is_real_numerical(SR) # optional - sage.symbolic + sage: parent_is_real_numerical(SR) # needs sage.symbolic False - sage: [parent_is_real_numerical(R) for R in [RIF, RBF, CIF, CBF]] + sage: [parent_is_real_numerical(R) for R in [RIF, RBF, CIF, CBF]] # needs sage.libs.flint [False, False, False, False] """ if not isinstance(P, Parent): @@ -426,6 +423,8 @@ cpdef bint is_numpy_type(t): EXAMPLES:: sage: from sage.structure.coerce import is_numpy_type + + sage: # needs numpy sage: import numpy sage: is_numpy_type(numpy.int16) True @@ -435,11 +434,12 @@ cpdef bint is_numpy_type(t): True sage: is_numpy_type(numpy.matrix) True + sage: is_numpy_type(int) False sage: is_numpy_type(Integer) False - sage: is_numpy_type(Sudoku) # optional - sage.combinat + sage: is_numpy_type(Sudoku) # needs sage.combinat False sage: is_numpy_type(None) False @@ -473,6 +473,7 @@ cpdef bint is_mpmath_type(t): EXAMPLES:: + sage: # needs mpmath sage: from sage.structure.coerce import is_mpmath_type sage: is_mpmath_type(int) False @@ -494,14 +495,14 @@ cdef class CoercionModel: EXAMPLES:: - sage: f = ZZ['t', 'x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f # optional - sage.rings.number_field + sage: f = ZZ['t', 'x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f # needs sage.rings.number_field t + x + zeta13 - sage: f.parent() # optional - sage.rings.number_field + sage: f.parent() # needs sage.rings.number_field Multivariate Polynomial Ring in t, x over Cyclotomic Field of order 13 and degree 12 sage: ZZ['x','y'].0 + ~Frac(QQ['y']).0 (x*y + 1)/y - sage: MatrixSpace(ZZ['x'], 2, 2)(2) + ~Frac(QQ['x']).0 + sage: MatrixSpace(ZZ['x'], 2, 2)(2) + ~Frac(QQ['x']).0 # needs sage.modules [(2*x + 1)/x 0] [ 0 (2*x + 1)/x] sage: f = ZZ['x,y,z'].0 + QQ['w,x,z,a'].0; f @@ -515,11 +516,11 @@ cdef class CoercionModel: Check that :trac:`8426` is fixed (see also :trac:`18076`):: - sage: import numpy + sage: import numpy # needs numpy sage: x = polygen(RR) - sage: numpy.float32('1.5') * x + sage: numpy.float32('1.5') * x # needs numpy 1.50000000000000*x - sage: x * numpy.float32('1.5') + sage: x * numpy.float32('1.5') # needs numpy 1.50000000000000*x sage: p = x**3 + 2*x - 1 sage: p(float('1.2')) @@ -529,26 +530,26 @@ cdef class CoercionModel: This used to fail (see :trac:`18076`):: - sage: 1/3 + numpy.int8('12') + sage: 1/3 + numpy.int8('12') # needs numpy 37/3 - sage: -2/3 + numpy.int16('-2') + sage: -2/3 + numpy.int16('-2') # needs numpy -8/3 - sage: 2/5 + numpy.uint8('2') + sage: 2/5 + numpy.uint8('2') # needs numpy 12/5 The numpy types do not interact well with the Sage coercion framework. More precisely, if a numpy type is the first operand in a binary operation then this operation is done in numpy. The result is hence a numpy type:: - sage: numpy.uint8('2') + 3 + sage: numpy.uint8('2') + 3 # needs numpy 5 - sage: type(_) + sage: type(_) # needs numpy # 32-bit # 64-bit - sage: numpy.int8('12') + 1/3 + sage: numpy.int8('12') + 1/3 # needs numpy 12.333333333333334 - sage: type(_) + sage: type(_) # needs numpy AUTHOR: @@ -562,8 +563,8 @@ cdef class CoercionModel: sage: from sage.structure.coerce import CoercionModel sage: cm = CoercionModel() sage: x = polygen(ZZ, 'x') - sage: K = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field - sage: A = cm.get_action(ZZ, K, operator.mul) # optional - sage.rings.number_field + sage: K = NumberField(x^2 - 2, 'a') # needs sage.rings.number_field + sage: A = cm.get_action(ZZ, K, operator.mul) # needs sage.rings.number_field sage: f, g = cm.coercion_maps(QQ, int) sage: f, g = cm.coercion_maps(ZZ, int) """ @@ -761,7 +762,7 @@ cdef class CoercionModel: 5/2 sage: cm.exception_stack() [] - sage: 1/2 + GF(3)(2) # optional - sage.rings.finite_rings + sage: 1/2 + GF(3)(2) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: @@ -770,9 +771,9 @@ cdef class CoercionModel: Now see what the actual problem was:: sage: import traceback - sage: cm.exception_stack() # optional - sage.rings.finite_rings + sage: cm.exception_stack() ['Traceback (most recent call last):...', 'Traceback (most recent call last):...'] - sage: print(cm.exception_stack()[-1]) # optional - sage.rings.finite_rings + sage: print(cm.exception_stack()[-1]) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -782,7 +783,7 @@ cdef class CoercionModel: :: - sage: coercion_traceback() # optional - sage.rings.finite_rings + sage: coercion_traceback() Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -847,11 +848,11 @@ cdef class CoercionModel: Sometimes with non-sage types there is not enough information to deduce what will actually happen:: - sage: R100 = RealField(100) - sage: cm.explain(R100, float, operator.add) + sage: R100 = RealField(100) # needs sage.rings.real_mpfr + sage: cm.explain(R100, float, operator.add) # needs sage.rings.real_mpfr Right operand is numeric, will attempt coercion in both directions. Unknown result parent. - sage: parent(R100(1) + float(1)) + sage: parent(R100(1) + float(1)) # needs sage.rings.real_mpfr sage: cm.explain(QQ, float, operator.add) Right operand is numeric, will attempt coercion in both directions. @@ -925,25 +926,28 @@ cdef class CoercionModel: cpdef analyse(self, xp, yp, op=mul): """ Emulate the process of doing arithmetic between xp and yp, returning - a list of steps and the parent that the result will live in. The - ``explain`` function is easier to use, but if one wants access to + a list of steps and the parent that the result will live in. + + The :meth:`explain` method is easier to use, but if one wants access to the actual morphism and action objects (rather than their string - representations) then this is the function to use. + representations), then this is the function to use. EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() - sage: GF7 = GF(7) # optional - sage.rings.finite_rings - sage: steps, res = cm.analyse(GF7, ZZ) # optional - sage.rings.finite_rings - sage: steps # optional - sage.rings.finite_rings - ['Coercion on right operand via', Natural morphism: + sage: GF7 = GF(7) + sage: steps, res = cm.analyse(GF7, ZZ) + sage: steps + ['Coercion on right operand via', + Natural morphism: From: Integer Ring - To: Finite Field of size 7, 'Arithmetic performed after coercions.'] - sage: res # optional - sage.rings.finite_rings + To: Finite Field of size 7, + 'Arithmetic performed after coercions.'] + sage: res Finite Field of size 7 - sage: f = steps[1]; type(f) # optional - sage.rings.finite_rings + sage: f = steps[1]; type(f) - sage: f(100) # optional - sage.rings.finite_rings + sage: f(100) 2 """ self._exceptions_cleared = False @@ -1018,9 +1022,10 @@ cdef class CoercionModel: def common_parent(self, *args): """ - Computes a common parent for all the inputs. It's essentially - an `n`-ary canonical coercion except it can operate on parents - rather than just elements. + Compute a common parent for all the inputs. + + It's essentially an `n`-ary canonical coercion except it can + operate on parents rather than just elements. INPUT: @@ -1029,14 +1034,14 @@ cdef class CoercionModel: OUTPUT: A :class:`Parent` into which each input should coerce, or raises a - ``TypeError`` if no such :class:`Parent` can be found. + :class:`TypeError` if no such :class:`Parent` can be found. EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() sage: cm.common_parent(ZZ, QQ) Rational Field - sage: cm.common_parent(ZZ, QQ, RR) + sage: cm.common_parent(ZZ, QQ, RR) # needs sage.rings.real_mpfr Real Field with 53 bits of precision sage: ZZT = ZZ[['T']] sage: QQT = QQ['T'] @@ -1046,8 +1051,8 @@ cdef class CoercionModel: sage: cm.common_parent(int, float, ZZ) - sage: real_fields = [RealField(prec) for prec in [10,20..100]] - sage: cm.common_parent(*real_fields) + sage: real_fields = [RealField(prec) for prec in [10,20..100]] # needs sage.rings.real_mpfr + sage: cm.common_parent(*real_fields) # needs sage.rings.real_mpfr Real Field with 10 bits of precision There are some cases where the ordering does matter, but if a parent @@ -1100,14 +1105,14 @@ cdef class CoercionModel: sage: ZZx = ZZ['x'] sage: cm.division_parent(ZZx) Fraction Field of Univariate Polynomial Ring in x over Integer Ring - sage: K = GF(41) # optional - sage.rings.finite_rings - sage: cm.division_parent(K) # optional - sage.rings.finite_rings + sage: K = GF(41) + sage: cm.division_parent(K) Finite Field of size 41 sage: Zmod100 = Integers(100) sage: cm.division_parent(Zmod100) Ring of integers modulo 100 - sage: S5 = SymmetricGroup(5) # optional - sage.groups - sage: cm.division_parent(S5) # optional - sage.groups + sage: S5 = SymmetricGroup(5) # needs sage.groups + sage: cm.division_parent(S5) # needs sage.groups Symmetric group of order 5! as a permutation group """ try: @@ -1124,23 +1129,25 @@ cdef class CoercionModel: cpdef bin_op(self, x, y, op): """ - Execute the operation op on x and y. It first looks for an action - corresponding to op, and failing that, it tries to coerces x and y - into a common parent and calls op on them. + Execute the operation ``op`` on `x` and `y`. + + It first looks for an action + corresponding to ``op``, and failing that, it tries to coerce `x` and `y` + into a common parent and calls ``op`` on them. - If it cannot make sense of the operation, a TypeError is raised. + If it cannot make sense of the operation, a :class:`TypeError` is raised. INPUT: - - ``x`` - the left operand + - ``x`` -- the left operand - - ``y`` - the right operand + - ``y`` -- the right operand - - ``op`` - a python function taking 2 arguments + - ``op`` -- a python function taking 2 arguments .. NOTE:: - op is often an arithmetic operation, but need not be so. + ``op`` is often an arithmetic operation, but need not be so. EXAMPLES:: @@ -1156,9 +1163,9 @@ cdef class CoercionModel: Actions are detected and performed:: - sage: M = matrix(ZZ, 2, 2, range(4)) # optional - sage.modules - sage: V = vector(ZZ, [5,7]) # optional - sage.modules - sage: cm.bin_op(M, V, operator.mul) # optional - sage.modules + sage: M = matrix(ZZ, 2, 2, range(4)) # needs sage.modules + sage: V = vector(ZZ, [5,7]) # needs sage.modules + sage: cm.bin_op(M, V, operator.mul) # needs sage.modules (7, 31) TESTS:: @@ -1270,26 +1277,28 @@ cdef class CoercionModel: cpdef canonical_coercion(self, x, y): r""" - Given two elements x and y, with parents S and R respectively, - find a common parent Z such that there are coercions - `f: S \mapsto Z` and `g: R \mapsto Z` and return `f(x), g(y)` + Given two elements `x` and `y`, with parents `S` and `R` respectively, + find a common parent `Z` such that there are coercions + `f: S \to Z` and `g: R \to Z` and return `f(x), g(y)`, which will have the same parent. - Raises a type error if no such Z can be found. + Raises a type error if no such `Z` can be found. EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() sage: cm.canonical_coercion(mod(2, 10), 17) (2, 7) - sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) # optional - sage.modules - sage: x # optional - sage.modules + + sage: # needs sage.modules + sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) + sage: x [1/2 0] [ 0 1/2] - sage: y # optional - sage.modules + sage: y [0 1] [2 3] - sage: parent(x) is parent(y) # optional - sage.modules + sage: parent(x) is parent(y) True There is some support for non-Sage datatypes as well:: @@ -1298,7 +1307,6 @@ cdef class CoercionModel: sage: type(x), type(y) (, ) - sage: x, y = cm.canonical_coercion(int(5), complex(3)) sage: type(x), type(y) (, ) @@ -1314,9 +1322,9 @@ cdef class CoercionModel: We also make an exception for 0, even if `\ZZ` does not map in:: - sage: canonical_coercion(vector([1, 2, 3]), 0) # optional - sage.modules + sage: canonical_coercion(vector([1, 2, 3]), 0) # needs sage.modules ((1, 2, 3), (0, 0, 0)) - sage: canonical_coercion(GF(5)(0), float(0)) # optional - sage.rings.finite_rings + sage: canonical_coercion(GF(5)(0), float(0)) (0, 0) """ xp = parent(x) @@ -1413,7 +1421,6 @@ cdef class CoercionModel: raise TypeError("no common canonical parent for objects with parents: '%s' and '%s'"%(xp, yp)) - cpdef coercion_maps(self, R, S): r""" Give two parents `R` and `S`, return a pair of coercion maps @@ -1457,13 +1464,14 @@ cdef class CoercionModel: From: Rational Field To: Univariate Polynomial Ring in x over Rational Field - sage: K = GF(7) # optional - sage.rings.finite_rings - sage: cm.coercion_maps(QQ, K) is None # optional - sage.rings.finite_rings + sage: K = GF(7) + sage: cm.coercion_maps(QQ, K) is None True Note that to break symmetry, if there is a coercion map in both directions, the parent on the left is used:: + sage: # needs sage.modules sage: V = QQ^3 sage: W = V.__class__(QQ, 3) sage: V == W @@ -1472,20 +1480,22 @@ cdef class CoercionModel: False sage: cm = sage.structure.element.get_coercion_model() sage: cm.coercion_maps(V, W) - (None, (map internal to coercion system -- copy before use) + (None, + (map internal to coercion system -- copy before use) Coercion map: From: Vector space of dimension 3 over Rational Field To: Vector space of dimension 3 over Rational Field) sage: cm.coercion_maps(W, V) - (None, (map internal to coercion system -- copy before use) + (None, + (map internal to coercion system -- copy before use) Coercion map: From: Vector space of dimension 3 over Rational Field To: Vector space of dimension 3 over Rational Field) sage: v = V([1,2,3]) sage: w = W([1,2,3]) - sage: parent(v+w) is V + sage: parent(v + w) is V True - sage: parent(w+v) is W + sage: parent(w + v) is W True TESTS: @@ -1493,20 +1503,21 @@ cdef class CoercionModel: We check that with :trac:`14058`, parents are still eligible for garbage collection after being involved in binary operations:: + sage: # needs sage.libs.pari sage: import gc - sage: T = type(GF(2)) # optional - sage.rings.finite_rings - sage: gc.collect() #random + sage: T = type(GF(2)) + sage: gc.collect() # random 852 - sage: N0 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings - sage: L = [ZZ(1) + GF(p)(1) for p in prime_range(2, 50)] # optional - sage.rings.finite_rings - sage: N1 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings - sage: N1 > N0 # optional - sage.rings.finite_rings + sage: N0 = len(list(o for o in gc.get_objects() if type(o) is T)) + sage: L = [ZZ(1) + GF(p)(1) for p in prime_range(2, 50)] + sage: N1 = len(list(o for o in gc.get_objects() if type(o) is T)) + sage: N1 > N0 True - sage: del L # optional - sage.rings.finite_rings - sage: gc.collect() #random + sage: del L + sage: gc.collect() # random 3939 - sage: N2 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings - sage: N2 - N0 # optional - sage.rings.finite_rings + sage: N2 = len(list(o for o in gc.get_objects() if type(o) is T)) + sage: N2 - N0 0 """ @@ -1561,7 +1572,7 @@ cdef class CoercionModel: cpdef verify_coercion_maps(self, R, S, homs, bint fix=False): """ - Make sure this is a valid pair of homomorphisms from R and S to a common parent. + Make sure this is a valid pair of homomorphisms from `R` and `S` to a common parent. This function is used to protect the user against buggy parents. EXAMPLES:: @@ -1631,7 +1642,7 @@ cdef class CoercionModel: cpdef discover_coercion(self, R, S): """ This actually implements the finding of coercion maps as described in - the ``coercion_maps`` method. + the :meth:`coercion_maps` method. EXAMPLES:: @@ -1639,7 +1650,7 @@ cdef class CoercionModel: If R is S, then two identity morphisms suffice:: - sage: cm.discover_coercion(SR, SR) # optional - sage.symbolic + sage: cm.discover_coercion(SR, SR) # needs sage.symbolic (None, None) If there is a coercion map either direction, use that:: @@ -1649,7 +1660,7 @@ cdef class CoercionModel: Natural morphism: From: Integer Ring To: Rational Field, None) - sage: cm.discover_coercion(RR, QQ) + sage: cm.discover_coercion(RR, QQ) # needs sage.rings.real_mpfr (None, (map internal to coercion system -- copy before use) Generic map: From: Rational Field @@ -1670,9 +1681,9 @@ cdef class CoercionModel: Sometimes there is a reasonable "cover," but no canonical coercion:: - sage: sage.categories.pushout.pushout(QQ, QQ^3) + sage: sage.categories.pushout.pushout(QQ, QQ^3) # needs sage.modules Vector space of dimension 3 over Rational Field - sage: print(cm.discover_coercion(QQ, QQ^3)) + sage: print(cm.discover_coercion(QQ, QQ^3)) # needs sage.modules None """ if R is S: @@ -1811,15 +1822,15 @@ cdef class CoercionModel: """ INPUT: - - ``R`` - the left Parent (or type) - - ``S`` - the right Parent (or type) - - ``op`` - the operand, typically an element of the operator module - - ``r`` - (optional) element of R - - ``s`` - (optional) element of S. + - ``R`` -- the left :class:`Parent` (or type) + - ``S`` -- the right :class:`Parent` (or type) + - ``op`` -- the operand, typically an element of the :mod:`operator` module + - ``r`` -- (optional) element of `R` + - ``s`` -- (optional) element of `S`. OUTPUT: - - An action A such that s op r is given by A(s,r). + - An action `A` such that `s` ``op`` `r` is given by `A(s,r)`. The steps taken are illustrated below. @@ -1827,52 +1838,59 @@ cdef class CoercionModel: sage: P. = ZZ['x'] sage: P.get_action(ZZ) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring sage: ZZ.get_action(P) is None True sage: cm = sage.structure.element.get_coercion_model() - If R or S is a Parent, ask it for an action by/on R:: + If `R` or `S` is a :class:`Parent`, ask it for an action by/on `R`:: sage: cm.discover_action(ZZ, P, operator.mul) - Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring - If R or S a type, recursively call get_action with the Sage versions of R and/or S:: + If `R` or `S` a type, recursively call :meth:`get_action` + with the Sage versions of `R` and/or `S`:: sage: cm.discover_action(P, int, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring - with precomposition on right by Native morphism: + Right scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring + with precomposition on right by Native morphism: From: Set of Python objects of class 'int' To: Integer Ring - If op is division, look for action on right by inverse:: + If ``op`` is division, look for action on ``right`` by inverse:: sage: cm.discover_action(P, ZZ, operator.truediv) - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right inverse action by Rational Field on + Univariate Polynomial Ring in x over Integer Ring with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field Check that :trac:`17740` is fixed:: - sage: R = GF(5)['x'] # optional - sage.rings.finite_rings - sage: cm.discover_action(R, ZZ, operator.truediv) # optional - sage.rings.finite_rings + sage: R = GF(5)['x'] + sage: cm.discover_action(R, ZZ, operator.truediv) Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 - sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() # optional - sage.rings.finite_rings + sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() Univariate Polynomial Ring in x over Finite Field of size 5 Check that :trac:`18221` is fixed:: + sage: # needs sage.combinat sage.modules sage: F. = FreeAlgebra(QQ) sage: x / 2 1/2*x sage: cm.discover_action(F, ZZ, operator.truediv) - Right inverse action by Rational Field on Free Algebra on 1 generators (x,) over Rational Field - with precomposition on right by Natural morphism: + Right inverse action by Rational Field on + Free Algebra on 1 generators (x,) over Rational Field + with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field """ @@ -1962,12 +1980,12 @@ cdef class CoercionModel: If there is no coercion, we only support ``==`` and ``!=``:: - sage: x = QQ.one(); y = GF(2).one() # optional - sage.rings.finite_rings - sage: richcmp(x, y, op_EQ) # optional - sage.rings.finite_rings + sage: x = QQ.one(); y = GF(2).one() + sage: richcmp(x, y, op_EQ) False - sage: richcmp(x, y, op_NE) # optional - sage.rings.finite_rings + sage: richcmp(x, y, op_NE) True - sage: richcmp(x, y, op_GT) # optional - sage.rings.finite_rings + sage: richcmp(x, y, op_GT) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for >: diff --git a/src/sage/structure/coerce_actions.pyx b/src/sage/structure/coerce_actions.pyx index 146c41379b7..cdc5bddd0a6 100644 --- a/src/sage/structure/coerce_actions.pyx +++ b/src/sage/structure/coerce_actions.pyx @@ -55,14 +55,15 @@ cdef class GenericAction(Action): for otherwise they could be garbage collected, giving rise to random errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules - sage: sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules + sage: from sage.structure.coerce_actions import ActedUponAction, GenericAction + sage: M = MatrixSpace(ZZ, 2) # needs sage.modules + sage: ActedUponAction(M, Cusps, True) # needs sage.modular sage.modules Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps sage: Z6 = Zmod(6) - sage: sage.structure.coerce_actions.GenericAction(QQ, Z6, True) + sage: GenericAction(QQ, Z6, True) Traceback (most recent call last): ... NotImplementedError: action for not implemented @@ -94,15 +95,16 @@ cdef class GenericAction(Action): errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules - sage: A.codomain() # optional - sage.modular sage.modules + sage: M = MatrixSpace(ZZ, 2) # needs sage.modules + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # needs sage.modular sage.modules + sage: A.codomain() # needs sage.modular sage.modules Set P^1(QQ) of all cusps - sage: S3 = SymmetricGroup(3) # optional - sage.groups - sage: QQxyz = QQ['x,y,z'] # optional - sage.groups - sage: A = sage.structure.coerce_actions.ActOnAction(S3, QQxyz, False) # optional - sage.groups - sage: A.codomain() # optional - sage.groups + sage: # needs sage.groups + sage: S3 = SymmetricGroup(3) + sage: QQxyz = QQ['x,y,z'] + sage: A = sage.structure.coerce_actions.ActOnAction(S3, QQxyz, False) + sage: A.codomain() Multivariate Polynomial Ring in x, y, z over Rational Field """ @@ -120,15 +122,15 @@ cdef class ActOnAction(GenericAction): """ TESTS:: - sage: G = SymmetricGroup(3) # optional - sage.groups - sage: R. = QQ[] # optional - sage.groups - sage: A = sage.structure.coerce_actions.ActOnAction(G, R, False) # optional - sage.groups - sage: A(x^2 + y - z, G((1,2))) # optional - sage.groups + sage: # needs sage.groups + sage: G = SymmetricGroup(3) + sage: R. = QQ[] + sage: A = sage.structure.coerce_actions.ActOnAction(G, R, False) + sage: A(x^2 + y - z, G((1,2))) y^2 + x - z - sage: A(x+2*y+3*z, G((1,3,2))) # optional - sage.groups + sage: A(x + 2*y + 3*z, G((1,3,2))) 2*x + 3*y + z - - sage: type(A) # optional - sage.groups + sage: type(A) <... 'sage.structure.coerce_actions.ActOnAction'> """ return (g)._act_on_(x, self._is_left) @@ -142,14 +144,14 @@ cdef class ActedUponAction(GenericAction): """ TESTS:: - sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules - sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modular sage.modules + sage: # needs sage.modular sage.modules + sage: M = MatrixSpace(ZZ, 2) + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) + sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) Infinity - sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modular sage.modules + sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) Infinity - - sage: type(A) # optional - sage.modular sage.modules + sage: type(A) <... 'sage.structure.coerce_actions.ActedUponAction'> """ return (x)._acted_upon_(g, not self._is_left) @@ -168,16 +170,16 @@ def detect_element_action(Parent X, Y, bint X_on_left, X_el=None, Y_el=None): sage: from sage.structure.coerce_actions import detect_element_action sage: ZZx = ZZ['x'] - sage: M = MatrixSpace(ZZ,2) + sage: M = MatrixSpace(ZZ, 2) # needs sage.modules sage: detect_element_action(ZZx, ZZ, False) Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring sage: detect_element_action(ZZx, QQ, True) Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring - sage: detect_element_action(Cusps, M, False) # optional - sage.modular sage.modules + sage: detect_element_action(Cusps, M, False) # needs sage.modular sage.modules Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps - sage: detect_element_action(Cusps, M, True), # optional - sage.modular sage.modules + sage: detect_element_action(Cusps, M, True), # needs sage.modular sage.modules (None,) sage: detect_element_action(ZZ, QQ, True), (None,) @@ -404,7 +406,8 @@ cdef class ModuleAction(Action): sage: GF5 = GF(5) sage: GF5t = GF5[['t']] sage: RightModuleAction(GF5, GF5t) - Right scalar multiplication by Finite Field of size 5 on Power Series Ring in t over Finite Field of size 5 + Right scalar multiplication by Finite Field of size 5 + on Power Series Ring in t over Finite Field of size 5 """ return "scalar multiplication" @@ -487,7 +490,8 @@ cdef class ModuleAction(Action): sage: GF5x = GF(5)['x'] sage: A = ~RightModuleAction(ZZ, GF5x); A - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in x over Finite Field of size 5 + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -496,7 +500,8 @@ cdef class ModuleAction(Action): sage: GF5xy = GF5x['y'] sage: A = ~RightModuleAction(ZZ, GF5xy); A - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Finite Field of size 5 + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -520,6 +525,7 @@ cdef class ModuleAction(Action): See :trac:`19521`:: + sage: # needs sage.symbolic sage: Q. = SR.subring(no_variables=True)[[]] sage: (y / 1).parent() Power Series Ring in y over Symbolic Constants Subring @@ -682,8 +688,8 @@ cdef class IntegerAction(Action): Check that this action can be pickled (:trac:`29031`):: sage: from sage.structure.coerce_actions import IntegerMulAction - sage: act = IntegerMulAction(ZZ, CDF) - sage: loads(dumps(act)) is not None + sage: act = IntegerMulAction(ZZ, CDF) # needs sage.rings.complex_double + sage: loads(dumps(act)) is not None # needs sage.rings.complex_double True """ # All base classes must take the signature @@ -695,8 +701,8 @@ cdef class IntegerAction(Action): EXAMPLES:: sage: from sage.structure.coerce_actions import IntegerMulAction - sage: act = IntegerMulAction(ZZ, CDF) - sage: ~act + sage: act = IntegerMulAction(ZZ, CDF) # needs sage.rings.complex_double + sage: ~act # needs sage.rings.complex_double Traceback (most recent call last): ... TypeError: actions by ZZ cannot be inverted @@ -767,13 +773,14 @@ cdef class IntegerMulAction(IntegerAction): This used to hang before :trac:`17844`:: - sage: E = EllipticCurve(GF(5), [4,0]) - sage: P = E.random_element() - sage: (-2^63)*P + sage: E = EllipticCurve(GF(5), [4,0]) # needs sage.schemes + sage: P = E.random_element() # needs sage.schemes + sage: (-2^63)*P # needs sage.schemes (0 : 1 : 0) Check that large multiplications can be interrupted:: + sage: # needs sage.schemes sage: alarm(0.001); 2^(10^7) * P Traceback (most recent call last): ... @@ -782,6 +789,7 @@ cdef class IntegerMulAction(IntegerAction): Verify that cysignals correctly detects that the above exception has been handled:: + sage: # needs sage.schemes sage: from cysignals.tests import print_sig_occurred sage: print_sig_occurred() No current exception @@ -806,7 +814,8 @@ cdef class IntegerMulAction(IntegerAction): sage: from sage.structure.coerce_actions import IntegerMulAction sage: GF5 = GF(5) sage: IntegerMulAction(ZZ, GF5) - Left Integer Multiplication by Integer Ring on Finite Field of size 5 + Left Integer Multiplication by Integer Ring + on Finite Field of size 5 """ return "Integer Multiplication" @@ -844,18 +853,18 @@ cdef class IntegerPowAction(IntegerAction): Traceback (most recent call last): ... ValueError: powering must be a right action - sage: IntegerPowAction(ZZ, QQ^3) + sage: IntegerPowAction(ZZ, QQ^3) # needs sage.modules Traceback (most recent call last): ... TypeError: no integer powering action defined on Vector space of dimension 3 over Rational Field :: - sage: var('x,y') + sage: var('x,y') # needs sage.symbolic (x, y) - sage: RDF('-2.3')^(x+y^3+sin(x)) + sage: RDF('-2.3')^(x+y^3+sin(x)) # needs sage.symbolic (-2.3)^(y^3 + x + sin(x)) - sage: RDF('-2.3')^x + sage: RDF('-2.3')^x # needs sage.symbolic (-2.3)^x """ def __init__(self, Z, M, is_left=False, m=None): diff --git a/src/sage/structure/coerce_dict.pyx b/src/sage/structure/coerce_dict.pyx index d38997d807c..a2e8443084c 100644 --- a/src/sage/structure/coerce_dict.pyx +++ b/src/sage/structure/coerce_dict.pyx @@ -35,18 +35,19 @@ coerce maps. In previous versions of Sage, the cache was by strong references and resulted in a memory leak in the following example. However, this leak was fixed by :trac:`715`, using weak references:: - sage: K. = GF(2^55) # optional - sage.rings.finite_rings sage.combinat - sage: for i in range(50): # optional - sage.rings.finite_rings sage.combinat + sage: # needs sage.combinat sage.modules sage.rings.finite_rings + sage: K. = GF(2^55) + sage: for i in range(20): ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: P = E.random_point() ....: Q = 2*P - sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation # optional - sage.rings.finite_rings sage.combinat + sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation sage: import gc sage: n = gc.collect() - sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field # optional - sage.rings.finite_rings sage.combinat - sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] # optional - sage.rings.finite_rings sage.combinat - sage: len(LE) # optional - sage.rings.finite_rings sage.combinat + sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field + sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] + sage: len(LE) 1 """ diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index e40f9ddb5db..1c1464a7899 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -32,11 +32,11 @@ cdef class DefaultConvertMap(Map): Maps of this type are morphisms in the category of sets with partial maps (see :trac:`15618`):: - sage: f = GF(11).convert_map_from(GF(7)); f # optional - sage.rings.finite_rings + sage: f = GF(11).convert_map_from(GF(7)); f # needs sage.rings.finite_rings Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 - sage: f.parent() # optional - sage.rings.finite_rings + sage: f.parent() # needs sage.rings.finite_rings Set of Morphisms from Finite Field of size 7 to Finite Field of size 11 @@ -44,7 +44,7 @@ cdef class DefaultConvertMap(Map): Test that :trac:`23211` is resolved:: - sage: f._is_coercion # optional - sage.rings.finite_rings + sage: f._is_coercion # needs sage.rings.finite_rings False sage: QQ[['x']].coerce_map_from(QQ)._is_coercion True @@ -85,8 +85,8 @@ cdef class DefaultConvertMap(Map): EXAMPLES:: - sage: f = GF(11).convert_map_from(GF(7)) # optional - sage.rings.finite_rings - sage: f._repr_type() # optional - sage.rings.finite_rings + sage: f = GF(11).convert_map_from(GF(7)) # needs sage.rings.finite_rings + sage: f._repr_type() # needs sage.rings.finite_rings 'Conversion' """ return self._repr_type_str or ("Coercion" if self._is_coercion else "Conversion") @@ -194,14 +194,15 @@ cdef class NamedConvertMap(Map): """ EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') # optional - sage.symbolic + sage: var('t') t - sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic - sage: mor(t^2/4 + 1) # optional - sage.symbolic + sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') + sage: mor(t^2/4 + 1) 1/4*t^2 + 1 - sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') # optional - sage.symbolic - sage: mor(t^2/4 + 1) # optional - sage.symbolic + sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') + sage: mor(t^2/4 + 1) 1 + 2*t^2 """ if isinstance(domain, type): @@ -217,20 +218,21 @@ cdef class NamedConvertMap(Map): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') # optional - sage.symbolic + sage: var('t') t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic - sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic - sage: psi # optional - sage.symbolic + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') + sage: psi = copy(phi) # indirect doctest + sage: psi Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic + sage: phi == psi # not implemented True - sage: psi(t^2/4 + 1) # optional - sage.symbolic + sage: psi(t^2/4 + 1) 1/4*t^2 + 1 - sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) True """ slots = Map._extra_slots(self) @@ -243,20 +245,21 @@ cdef class NamedConvertMap(Map): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') # optional - sage.symbolic + sage: var('t') t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic - sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic - sage: psi # optional - sage.symbolic + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') + sage: psi = copy(phi) # indirect doctest + sage: psi Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic + sage: phi == psi # not implemented True - sage: psi(t^2/4 + 1) # optional - sage.symbolic + sage: psi(t^2/4 + 1) 1/4*t^2 + 1 - sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) True """ self.method_name = _slots['method_name'] @@ -267,13 +270,13 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f # optional - sage.rings.finite_rings + sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f Conversion via _integer_ method map: From: Finite Field of size 5 To: Rational Field - sage: f(19) # optional - sage.rings.finite_rings + sage: f(19) 4 - sage: f(19).parent() # optional - sage.rings.finite_rings + sage: f(19).parent() Rational Field """ cdef Parent C = self._codomain @@ -301,8 +304,8 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') # optional - sage.symbolic - sage: f(x^2 + 1, check=True) # optional - sage.symbolic + sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') # needs sage.symbolic + sage: f(x^2 + 1, check=True) # needs sage.symbolic x^2 + 1 """ cdef Parent C = self._codomain @@ -335,12 +338,13 @@ cdef class CallableConvertMap(Map): :: - sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) # optional - sage.symbolic - sage: f(0) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) + sage: f(0) 1.00000000000000 - sage: f(1) # optional - sage.symbolic + sage: f(1) 2.71828182845905 - sage: f(-3) # optional - sage.symbolic + sage: f(-3) 0.0497870683678639 """ if isinstance(domain, type): diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index 4403ddd685a..79e86d8a5c3 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -34,16 +34,16 @@ cpdef inline parent(x): sage: parent(b) Rational Field sage: c = 42.0 - sage: parent(c) + sage: parent(c) # needs sage.rings.real_mpfr Real Field with 53 bits of precision Some more complicated examples:: - sage: x = Partition([3,2,1,1,1]) - sage: parent(x) + sage: x = Partition([3,2,1,1,1]) # needs sage.combinat + sage: parent(x) # needs sage.combinat Partitions - sage: v = vector(RDF, [1,2,3]) - sage: parent(v) + sage: v = vector(RDF, [1,2,3]) # needs sage.modules + sage: parent(v) # needs sage.modules Vector space of dimension 3 over Real Double Field The following are not considered to be elements, so the type is @@ -126,18 +126,18 @@ cpdef inline bint have_same_parent(left, right): True sage: have_same_parent(1, 1/2) False - sage: have_same_parent(gap(1), gap(1/2)) + sage: have_same_parent(gap(1), gap(1/2)) # needs sage.libs.gap True These have different types but the same parent:: sage: a = RLF(2) - sage: b = exp(a) # optional - sage.symbolic - sage: type(a) # optional - sage.symbolic + sage: b = exp(a) + sage: type(a) <... 'sage.rings.real_lazy.LazyWrapper'> - sage: type(b) # optional - sage.symbolic + sage: type(b) <... 'sage.rings.real_lazy.LazyNamedUnop'> - sage: have_same_parent(a, b) # optional - sage.symbolic + sage: have_same_parent(a, b) True """ return HAVE_SAME_PARENT(classify_elements(left, right)) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 70deeeeb8bd..ab6ee157a94 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -354,7 +354,7 @@ def is_Element(x): sage: from sage.structure.element import is_Element sage: is_Element(2/3) True - sage: is_Element(QQ^3) # optional - sage.modules + sage: is_Element(QQ^3) # needs sage.modules False """ return isinstance(x, Element) @@ -412,10 +412,10 @@ cdef class Element(SageObject): sage: q = 3/5 sage: parent(q) Rational Field - sage: q._set_parent(CC) - sage: parent(q) + sage: q._set_parent(CC) # needs sage.rings.real_mpfr + sage: parent(q) # needs sage.rings.real_mpfr Complex Field with 53 bits of precision - sage: q._set_parent(float) + sage: q._set_parent(float) # needs sage.rings.real_mpfr Traceback (most recent call last): ... TypeError: Cannot convert type to sage.structure.parent.Parent @@ -648,7 +648,7 @@ cdef class Element(SageObject): sage: QQ.base_ring() Rational Field - sage: identity_matrix(3).base_ring() # optional - sage.modules + sage: identity_matrix(3).base_ring() # needs sage.modules Integer Ring """ return self._parent.base_ring() @@ -848,18 +848,18 @@ cdef class Element(SageObject): EXAMPLES:: - sage: (2/3).numerical_approx() + sage: (2/3).numerical_approx() # needs sage.rings.real_mpfr 0.666666666666667 - sage: pi.n(digits=10) + sage: pi.n(digits=10) # needs sage.symbolic 3.141592654 - sage: pi.n(prec=20) + sage: pi.n(prec=20) # needs sage.symbolic 3.1416 TESTS: Check that :trac:`14778` is fixed:: - sage: (0).n(algorithm='foo') + sage: (0).n(algorithm='foo') # needs sage.rings.real_mpfr 0.000000000000000 """ from sage.arith.numerical_approx import numerical_approx_generic @@ -873,7 +873,7 @@ cdef class Element(SageObject): EXAMPLES:: - sage: (2/3).n() + sage: (2/3).n() # needs sage.rings.real_mpfr 0.666666666666667 """ return self.numerical_approx(prec, digits, algorithm) @@ -889,17 +889,18 @@ cdef class Element(SageObject): EXAMPLES:: + sage: # needs mpmath sage: from sage.libs.mpmath.all import mp, mpmathify sage: mp.dps = 30 sage: 25._mpmath_(53) mpf('25.0') - sage: mpmathify(3 + 4*I) # optional - mpmath + sage: mpmathify(3 + 4*I) mpc(real='3.0', imag='4.0') - sage: mpmathify(1 + pi) # optional - mpmath + sage: mpmathify(1 + pi) # needs sage.symbolic mpf('4.14159265358979323846264338327933') - sage: (1 + pi)._mpmath_(10) # optional - mpmath + sage: (1 + pi)._mpmath_(10) # needs sage.symbolic mpf('4.140625') - sage: (1 + pi)._mpmath_(mp.prec) # optional - mpmath + sage: (1 + pi)._mpmath_(mp.prec) # needs sage.symbolic mpf('4.14159265358979323846264338327933') """ return self.n(prec)._mpmath_(prec=prec) @@ -988,7 +989,7 @@ cdef class Element(SageObject): sage: n = 5; n._is_atomic() True - sage: n = x+1; n._is_atomic() + sage: n = x + 1; n._is_atomic() # needs sage.symbolic False """ if self._parent._repr_option('element_is_atomic'): @@ -1024,13 +1025,14 @@ cdef class Element(SageObject): Verify that :trac:`5185` is fixed:: - sage: v = vector({1: 1, 3: -1}) # optional - sage.modules - sage: w = vector({1: -1, 3: 1}) # optional - sage.modules - sage: v + w # optional - sage.modules + sage: # needs sage.modules + sage: v = vector({1: 1, 3: -1}) + sage: w = vector({1: -1, 3: 1}) + sage: v + w (0, 0, 0, 0) - sage: (v + w).is_zero() # optional - sage.modules + sage: (v + w).is_zero() True - sage: bool(v + w) # optional - sage.modules + sage: bool(v + w) False """ @@ -1130,7 +1132,8 @@ cdef class Element(SageObject): We now create an ``Element`` class where we define ``_richcmp_`` and check that comparison works:: - sage: cython( # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython( ....: ''' ....: from sage.structure.richcmp cimport rich_to_bool ....: from sage.structure.element cimport Element @@ -1143,9 +1146,9 @@ cdef class Element(SageObject): ....: cdef float x2 = (other).x ....: return rich_to_bool(op, (x1 > x2) - (x1 < x2)) ....: ''') - sage: a = FloatCmp(1) # optional - sage.misc.cython - sage: b = FloatCmp(2) # optional - sage.misc.cython - sage: a <= b, b <= a # optional - sage.misc.cython + sage: a = FloatCmp(1) + sage: b = FloatCmp(2) + sage: a <= b, b <= a (True, False) """ # Obvious case @@ -1280,16 +1283,17 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython( # long time ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _add_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i + e, e + i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time + sage: i = int(42) + sage: i + e, e + i # long time (42, 42) """ return coercion_model.bin_op(self, n, add) @@ -1490,13 +1494,14 @@ cdef class Element(SageObject): :: - sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: A = AlgebrasWithBasis(QQ).example(); A An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: x = A.an_element() # optional - sage.combinat sage.modules - sage: x # optional - sage.combinat sage.modules + sage: x = A.an_element() + sage: x B[word: ] + 2*B[word: a] + 3*B[word: b] + B[word: bab] - sage: x.__mul__(x) # optional - sage.combinat sage.modules + sage: x.__mul__(x) B[word: ] + 4*B[word: a] + 4*B[word: aa] + 6*B[word: ab] + 2*B[word: abab] + 6*B[word: b] + 6*B[word: ba] + 2*B[word: bab] + 2*B[word: baba] + 3*B[word: babb] @@ -1558,16 +1563,17 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython( # long time ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _mul_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i * e, e * i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time + sage: i = int(42) + sage: i * e, e * i # long time (42, 42) """ return coercion_model.bin_op(self, n, mul) @@ -1675,11 +1681,11 @@ cdef class Element(SageObject): sage: operator.truediv(2, 3) 2/3 - sage: operator.truediv(pi, 3) # optional - sage.symbolic + sage: operator.truediv(pi, 3) # needs sage.symbolic 1/3*pi sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: operator.truediv(2, K.ideal(i + 1)) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) # needs sage.rings.number_field + sage: operator.truediv(2, K.ideal(i + 1)) # needs sage.rings.number_field Fractional ideal (-i + 1) :: @@ -1994,19 +2000,21 @@ cdef class Element(SageObject): :: - sage: (2/3)^I # optional - sage.symbolic + sage: # needs sage.symbolic + sage: (2/3)^I (2/3)^I - sage: (2/3)^sqrt(2) # optional - sage.symbolic + sage: (2/3)^sqrt(2) (2/3)^sqrt(2) - sage: var('x,y,z,n') # optional - sage.symbolic + sage: var('x,y,z,n') (x, y, z, n) - sage: (2/3)^(x^n + y^n + z^n) # optional - sage.symbolic + sage: (2/3)^(x^n + y^n + z^n) (2/3)^(x^n + y^n + z^n) - sage: (-7/11)^(tan(x)+exp(x)) # optional - sage.symbolic + sage: (-7/11)^(tan(x)+exp(x)) (-7/11)^(e^x + tan(x)) + sage: float(1.2)**(1/2) 1.0954451150103321 - sage: complex(1,2)**(1/2) + sage: complex(1,2)**(1/2) # needs sage.rings.complex_double (1.272019649514069+0.786151377757423...j) TESTS:: @@ -2140,7 +2148,7 @@ def is_ModuleElement(x): sage: from sage.structure.element import is_ModuleElement sage: is_ModuleElement(2/3) True - sage: is_ModuleElement((QQ^3).0) # optional - sage.modules + sage: is_ModuleElement((QQ^3).0) # needs sage.modules True sage: is_ModuleElement('a') False @@ -2183,6 +2191,7 @@ cdef class ElementWithCachedMethod(Element): category whose element and parent classes define cached methods. :: + sage: # needs sage.misc.cython sage: cython_code = ["from sage.structure.element cimport Element, ElementWithCachedMethod", ....: "from sage.structure.richcmp cimport richcmp", ....: "cdef class MyBrokenElement(Element):", @@ -2219,7 +2228,7 @@ cdef class ElementWithCachedMethod(Element): ....: "from sage.structure.parent cimport Parent", ....: "cdef class MyParent(Parent):", ....: " Element = MyElement"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) sage: cython_code = ["from sage.misc.cachefunc import cached_method", ....: "from sage.misc.cachefunc import cached_in_parent_method", ....: "from sage.categories.category import Category", @@ -2242,21 +2251,22 @@ cdef class ElementWithCachedMethod(Element): ....: " @cached_method", ....: " def invert(self, x):", ....: " return -x"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) + sage: C = MyCategory() + sage: P = MyParent(category=C) + sage: ebroken = MyBrokenElement(P, 5) + sage: e = MyElement(P, 5) The cached methods inherited by ``MyElement`` works:: - sage: e.element_cache_test() # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: e.element_cache_test() <-5> - sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() is e.element_cache_test() True - sage: e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() <-5> - sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() is e.element_via_parent_test() True The other element class can only inherit a @@ -2264,36 +2274,36 @@ cdef class ElementWithCachedMethod(Element): parent. In fact, equal elements share the cache, even if they are of different types:: - sage: e == ebroken # optional - sage.misc.cython + sage: e == ebroken # needs sage.misc.cython True - sage: type(e) == type(ebroken) # optional - sage.misc.cython + sage: type(e) == type(ebroken) # needs sage.misc.cython False - sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # needs sage.misc.cython True However, the cache of the other inherited method breaks, although the method as such works:: - sage: ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() # needs sage.misc.cython <-5> - sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() is ebroken.element_cache_test() # needs sage.misc.cython False Since ``e`` and ``ebroken`` share the cache, when we empty it for one element it is empty for the other as well:: - sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython - sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython - sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: b = ebroken.element_via_parent_test() # needs sage.misc.cython + sage: e.element_via_parent_test.clear_cache() # needs sage.misc.cython + sage: b is ebroken.element_via_parent_test() # needs sage.misc.cython False Note that the cache only breaks for elements that do no allow attribute assignment. A Python version of ``MyBrokenElement`` therefore allows for cached methods:: - sage: epython = MyPythonElement(P, 5) # optional - sage.misc.cython - sage: epython.element_cache_test() # optional - sage.misc.cython + sage: epython = MyPythonElement(P, 5) # needs sage.misc.cython + sage: epython.element_cache_test() # needs sage.misc.cython <-5> - sage: epython.element_cache_test() is epython.element_cache_test() # optional - sage.misc.cython + sage: epython.element_cache_test() is epython.element_cache_test() # needs sage.misc.cython True """ @@ -2310,7 +2320,8 @@ cdef class ElementWithCachedMethod(Element): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: # needs sage.misc.cython + sage: cython( ....: ''' ....: from sage.structure.element cimport ElementWithCachedMethod ....: cdef class MyElement(ElementWithCachedMethod): @@ -2336,12 +2347,12 @@ cdef class ElementWithCachedMethod(Element): ....: def my_lazy_attr(self): ....: return 'lazy attribute of <%s>'%self.x ....: ''') - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython - sage: e.my_lazy_attr # optional - sage.misc.cython + sage: C = MyCategory() + sage: P = MyParent(category=C) + sage: e = MyElement(P, 5) + sage: e.my_lazy_attr 'lazy attribute of <5>' - sage: e.my_lazy_attr is e.my_lazy_attr # optional - sage.misc.cython + sage: e.my_lazy_attr is e.my_lazy_attr True """ try: @@ -2453,8 +2464,8 @@ cdef class ModuleElementWithMutability(ModuleElement): """ EXAMPLES:: - sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) # optional - sage.modules - sage: type(v) # optional - sage.modules + sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) # needs sage.modules + sage: type(v) # needs sage.modules """ self._parent = parent @@ -2466,11 +2477,12 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector([1..5]); v # optional - sage.modules + sage: # needs sage.modules + sage: v = vector([1..5]); v (1, 2, 3, 4, 5) - sage: v[1] = 10 # optional - sage.modules - sage: v.set_immutable() # optional - sage.modules - sage: v[1] = 10 # optional - sage.modules + sage: v[1] = 10 + sage: v.set_immutable() + sage: v[1] = 10 Traceback (most recent call last): ... ValueError: vector is immutable; please change a copy instead (use copy()) @@ -2484,10 +2496,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() # optional - sage.modules + sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() # needs sage.modules True - sage: v.set_immutable() # optional - sage.modules - sage: v.is_mutable() # optional - sage.modules + sage: v.set_immutable() # needs sage.modules + sage: v.is_mutable() # needs sage.modules False """ return not self._is_immutable @@ -2499,10 +2511,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() # optional - sage.modules + sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() # needs sage.modules False - sage: v.set_immutable() # optional - sage.modules - sage: v.is_immutable() # optional - sage.modules + sage: v.set_immutable() # needs sage.modules + sage: v.is_immutable() # needs sage.modules True """ return self._is_immutable @@ -2550,9 +2562,9 @@ cdef class MonoidElement(Element): EXAMPLES:: - sage: G = SymmetricGroup(4) # optional - sage.groups - sage: g = G([2, 3, 4, 1]) # optional - sage.groups - sage: g.powers(4) # optional - sage.groups + sage: G = SymmetricGroup(4) # needs sage.groups + sage: g = G([2, 3, 4, 1]) # needs sage.groups + sage: g.powers(4) # needs sage.groups [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] """ if n < 0: @@ -2681,22 +2693,22 @@ cdef class RingElement(ModuleElement): True sage: p(a,200) * p(a,-64) == p(a,136) True - sage: p(2, 1/2) # optional - sage.symbolic + sage: p(2, 1/2) # needs sage.symbolic sqrt(2) TESTS: These are not testing this code, but they are probably good to have around:: - sage: 2r**(SR(2)-1-1r) # optional - sage.symbolic + sage: 2r**(SR(2)-1-1r) # needs sage.symbolic 1 - sage: 2r^(1/2) # optional - sage.symbolic + sage: 2r^(1/2) # needs sage.symbolic sqrt(2) Exponent overflow should throw an OverflowError (:trac:`2956`):: - sage: K. = AA[] # optional - sage.rings.number_field - sage: x^(2^64 + 12345) # optional - sage.rings.number_field + sage: K. = AA[] # needs sage.rings.number_field + sage: x^(2^64 + 12345) # needs sage.rings.number_field Traceback (most recent call last): ... OverflowError: exponent overflow (2147483648) @@ -2793,13 +2805,13 @@ cdef class RingElement(ModuleElement): :: - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: divmod(x^2, x - 1) # optional - sage.rings.finite_rings + sage: R. = GF(7)[] + sage: divmod(x^2, x - 1) (x + 1, 1) :: - sage: divmod(22./7, RR(pi)) + sage: divmod(22./7, RR(pi)) # needs sage.symbolic (1.00040249943477, 0.000000000000000) """ try: @@ -2839,8 +2851,8 @@ cdef class RingElement(ModuleElement): sage: a = QQ(0) sage: a.is_nilpotent() True - sage: m = matrix(QQ, 3, [[3,2,3], [9,0,3], [-9,0,-3]]) # optional - sage.modules - sage: m.is_nilpotent() # optional - sage.modules + sage: m = matrix(QQ, 3, [[3,2,3], [9,0,3], [-9,0,-3]]) # needs sage.modules + sage: m.is_nilpotent() # needs sage.modules Traceback (most recent call last): ... AttributeError: ... object has no attribute 'is_nilpotent' @@ -2883,31 +2895,33 @@ cdef class RingElement(ModuleElement): For polynomial rings, prime is the same as irreducible:: + sage: # needs sage.libs.singular sage: R. = QQ[] - sage: x.is_prime() # optional - sage.libs.singular + sage: x.is_prime() True - sage: (x^2 + y^3).is_prime() # optional - sage.libs.singular + sage: (x^2 + y^3).is_prime() True - sage: (x^2 - y^2).is_prime() # optional - sage.libs.singular + sage: (x^2 - y^2).is_prime() False - sage: R(0).is_prime() # optional - sage.libs.singular + sage: R(0).is_prime() False - sage: R(2).is_prime() # optional - sage.libs.singular + sage: R(2).is_prime() False For the Gaussian integers:: - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: ZI = K.ring_of_integers() # optional - sage.rings.number_field - sage: ZI(3).is_prime() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-1) + sage: ZI = K.ring_of_integers() + sage: ZI(3).is_prime() True - sage: ZI(5).is_prime() # optional - sage.rings.number_field + sage: ZI(5).is_prime() False - sage: ZI(2 + i).is_prime() # optional - sage.rings.number_field + sage: ZI(2 + i).is_prime() True - sage: ZI(0).is_prime() # optional - sage.rings.number_field + sage: ZI(0).is_prime() False - sage: ZI(1).is_prime() # optional - sage.rings.number_field + sage: ZI(1).is_prime() False In fields, an element is never prime:: @@ -2922,7 +2936,7 @@ cdef class RingElement(ModuleElement): sage: (-2).is_prime() False - sage: RingElement.is_prime(-2) + sage: RingElement.is_prime(-2) # needs sage.libs.pari True Similarly, @@ -2930,13 +2944,14 @@ cdef class RingElement(ModuleElement): redefines :meth:`is_prime` to determine primality in the ring of integers:: - sage: (1 + i).is_prime() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: (1 + i).is_prime() True - sage: K(5).is_prime() # optional - sage.rings.number_field + sage: K(5).is_prime() False - sage: K(7).is_prime() # optional - sage.rings.number_field + sage: K(7).is_prime() True - sage: K(7/13).is_prime() # optional - sage.rings.number_field + sage: K(7/13).is_prime() False However, for rationals, :meth:`is_prime` *does* follow the @@ -2980,16 +2995,17 @@ cdef class CommutativeRingElement(RingElement): EXAMPLES:: - sage: F = GF(25) # optional - sage.rings.finite_rings - sage: x = F.gen() # optional - sage.rings.finite_rings - sage: z = F.zero() # optional - sage.rings.finite_rings - sage: x.inverse_mod(F.ideal(z)) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F = GF(25) + sage: x = F.gen() + sage: z = F.zero() + sage: x.inverse_mod(F.ideal(z)) 2*z2 + 3 - sage: x.inverse_mod(F.ideal(1)) # optional - sage.rings.finite_rings + sage: x.inverse_mod(F.ideal(1)) 1 - sage: z.inverse_mod(F.ideal(1)) # optional - sage.rings.finite_rings + sage: z.inverse_mod(F.ideal(1)) 1 - sage: z.inverse_mod(F.ideal(z)) # optional - sage.rings.finite_rings + sage: z.inverse_mod(F.ideal(z)) Traceback (most recent call last): ... ValueError: an element of a proper ideal does not have an inverse modulo that ideal @@ -3026,10 +3042,10 @@ cdef class CommutativeRingElement(RingElement): :trac:`5347` has been fixed:: - sage: K = GF(7) # optional - sage.rings.finite_rings - sage: K(3).divides(1) # optional - sage.rings.finite_rings + sage: K = GF(7) + sage: K(3).divides(1) True - sage: K(3).divides(K(1)) # optional - sage.rings.finite_rings + sage: K(3).divides(K(1)) True :: @@ -3154,22 +3170,22 @@ cdef class CommutativeRingElement(RingElement): and an ideal:: sage: R. = PolynomialRing(QQ, 3) - sage: (x^2 + y^2 + z^2).mod(x+y+z) + sage: (x^2 + y^2 + z^2).mod(x + y + z) # needs sage.libs.singular 2*y^2 + 2*y*z + 2*z^2 Notice above that `x` is eliminated. In the next example, both `y` and `z` are eliminated:: - sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) ) + sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) ) # needs sage.libs.singular 3*z^2 sage: f = (x^2 + y^2 + z^2)^2; f x^4 + 2*x^2*y^2 + y^4 + 2*x^2*z^2 + 2*y^2*z^2 + z^4 - sage: f.mod( (x - y, y - z) ) + sage: f.mod( (x - y, y - z) ) # needs sage.libs.singular 9*z^4 In this example `y` is eliminated:: - sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) ) + sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) ) # needs sage.libs.singular x^2 + 2*z^2 """ from sage.rings.ideal import is_Ideal @@ -3227,45 +3243,53 @@ cdef class CommutativeRingElement(RingElement): def sqrt(self, extend=True, all=False, name=None): """ - It computes the square root. + Compute the square root. INPUT: - - ``extend`` - Whether to make a ring extension containing a square root if ``self`` is not a square (default: ``True``) + - ``extend`` -- boolean (default: ``True``); whether to make a ring + extension containing a square root if ``self`` is not a square - - ``all`` - Whether to return a list of all square roots or just a square root (default: False) + - ``all`` -- boolean (default: ``False``); whether to return a list of + all square roots or just a square root - - ``name`` - Required when ``extend=True`` and ``self`` is not a square. This will be the name of the generator extension. + - ``name`` -- required when ``extend=True`` and ``self`` is not a + square. This will be the name of the generator of the extension. OUTPUT: - - if ``all=False`` it returns a square root. (throws an error if ``extend=False`` and ``self`` is not a square) + - if ``all=False``, a square root; raises an error if ``extend=False`` + and ``self`` is not a square - - if ``all=True`` it returns a list of all the square roots (could be empty if ``extend=False`` and ``self`` is not a square) + - if ``all=True``, a list of all the square roots (empty if + ``extend=False`` and ``self`` is not a square) ALGORITHM: - It uses ``is_square(root=true)`` for the hard part of the work, the rest is just wrapper code. + It uses ``is_square(root=true)`` for the hard part of the work, the rest + is just wrapper code. EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = ZZ[] sage: (x^2).sqrt() x - sage: f=x^2-4*x+4; f.sqrt(all=True) + sage: f = x^2 - 4*x + 4; f.sqrt(all=True) [x - 2, -x + 2] - sage: sqrtx=x.sqrt(name="y"); sqrtx + sage: sqrtx = x.sqrt(name="y"); sqrtx y sage: sqrtx^2 x - sage: x.sqrt(all=true,name="y") + sage: x.sqrt(all=true, name="y") [y, -y] - sage: x.sqrt(extend=False,all=True) + sage: x.sqrt(extend=False, all=True) [] sage: x.sqrt() Traceback (most recent call last): ... - TypeError: Polynomial is not a square. You must specify the name of the square root when using the default extend = True + TypeError: Polynomial is not a square. You must specify the name + of the square root when using the default extend = True sage: x.sqrt(extend=False) Traceback (most recent call last): ... @@ -3273,9 +3297,10 @@ cdef class CommutativeRingElement(RingElement): TESTS:: - sage: f = (x+3)^2; f.sqrt() + sage: # needs sage.libs.pari + sage: f = (x + 3)^2; f.sqrt() x + 3 - sage: f = (x+3)^2; f.sqrt(all=True) + sage: f = (x + 3)^2; f.sqrt(all=True) [x + 3, -x - 3] sage: f = (x^2 - x + 3)^2; f.sqrt() x^2 - x + 3 @@ -3285,6 +3310,7 @@ cdef class CommutativeRingElement(RingElement): sage: g.sqrt()^2 == g True + sage: # needs sage.libs.pari sage: R. = GF(250037)[] sage: f = x^2/(x+1)^2; f.sqrt() x/(x + 1) @@ -3300,14 +3326,15 @@ cdef class CommutativeRingElement(RingElement): y sage: sqrtx^2 1/x - sage: (1/x).sqrt(all=true,name="y") + sage: (1/x).sqrt(all=true, name="y") [y, -y] - sage: (1/x).sqrt(extend=False,all=True) + sage: (1/x).sqrt(extend=False, all=True) [] sage: (1/(x^2-1)).sqrt() Traceback (most recent call last): ... - TypeError: Polynomial is not a square. You must specify the name of the square root when using the default extend = True + TypeError: Polynomial is not a square. You must specify the name + of the square root when using the default extend = True sage: (1/(x^2-3)).sqrt(extend=False) Traceback (most recent call last): ... @@ -3361,7 +3388,7 @@ cdef class Expression(CommutativeRingElement): EXAMPLES:: - sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic + sage: isinstance(SR.var('y'), sage.structure.element.Expression) # needs sage.symbolic True By design, there is a unique direct subclass:: @@ -3398,195 +3425,259 @@ cdef class Vector(ModuleElementWithMutability): Here we test (vector * vector) multiplication:: - sage: parent(vector(ZZ,[1,2])*vector(ZZ,[1,2])) + sage: # needs sage.modules + sage: parent(vector(ZZ, [1,2]) * vector(ZZ, [1,2])) Integer Ring - sage: parent(vector(ZZ,[1,2])*vector(QQ,[1,2])) + sage: parent(vector(ZZ, [1,2]) * vector(QQ, [1,2])) Rational Field - sage: parent(vector(QQ,[1,2])*vector(ZZ,[1,2])) + sage: parent(vector(QQ, [1,2]) * vector(ZZ, [1,2])) Rational Field - sage: parent(vector(QQ,[1,2])*vector(QQ,[1,2])) + sage: parent(vector(QQ, [1,2]) * vector(QQ, [1,2])) Rational Field - sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ['x'],[1,2,3,4])) + sage: parent(vector(QQ, [1,2,3,4]) * vector(ZZ['x'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(QQ,[1,2,3,4])) + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(QQ, [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ,[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ, [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ['x'],[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ['x'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ['y'],[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ['y'], [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) # needs sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(ZZ['y'],[1,2,3,4])) + sage: # needs sage.modules + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(ZZ['y'], [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(ZZ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(ZZ['y'], [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' Here we test (vector * matrix) multiplication:: - sage: parent(vector(ZZ,[1,2])*matrix(ZZ,2,2,[1,2,3,4])) + sage: # needs sage.modules + sage: parent(vector(ZZ, [1,2]) * matrix(ZZ, 2, 2, [1,2,3,4])) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(vector(QQ,[1,2])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(ZZ, 2, 2, [1,2,3,4])) Vector space of dimension 2 over Rational Field - sage: parent(vector(ZZ,[1,2])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(vector(ZZ, [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*matrix(ZZ['x'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2])*matrix(QQ,2,2,[1,2,3,4])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ,[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ,2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['x'],[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ['x'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['y'],[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(ZZ['x'],[1,2])*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x'], [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ, [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['x'], [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['y'], [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(vector(ZZ['x'], [1,2]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2])*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' Here we test (vector * scalar) multiplication:: - sage: parent(vector(ZZ,[1,2])*ZZ(1)) + sage: # needs sage.modules + sage: parent(vector(ZZ, [1,2]) * ZZ(1)) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(vector(QQ,[1,2])*ZZ(1)) + sage: parent(vector(QQ, [1,2]) * ZZ(1)) Vector space of dimension 2 over Rational Field - sage: parent(vector(ZZ,[1,2])*QQ(1)) + sage: parent(vector(ZZ, [1,2]) * QQ(1)) Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*QQ(1)) + sage: parent(vector(QQ, [1,2]) * QQ(1)) Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*ZZ['x'](1)) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2])*QQ(1)) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ,[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ(1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['x'],[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ['x'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['y'],[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(ZZ['x'],[1,2])*ZZ['y'](1)) + sage: parent(vector(QQ, [1,2]) * ZZ['x'](1)) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x'], [1,2]) * QQ(1)) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ, [1,2]) * ZZ['x']['y'](1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ(1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['x'], [1,2]) * ZZ['x']['y'](1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ['x'](1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['y'], [1,2]) * ZZ['x']['y'](1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ['y'](1)) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(vector(ZZ['x'], [1,2]) * ZZ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2]) * QQ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2])*ZZ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2]) * ZZ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2]) * QQ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Rational Field' Here we test (scalar * vector) multiplication:: - sage: parent(ZZ(1)*vector(ZZ,[1,2])) + sage: # needs sage.modules + sage: parent(ZZ(1) * vector(ZZ, [1,2])) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(QQ(1)*vector(ZZ,[1,2])) + sage: parent(QQ(1) * vector(ZZ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(ZZ(1)*vector(QQ,[1,2])) + sage: parent(ZZ(1) * vector(QQ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(QQ(1)*vector(QQ,[1,2])) + sage: parent(QQ(1) * vector(QQ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(QQ(1)*vector(ZZ['x'],[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x'](1)*vector(QQ,[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ(1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ,[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['x'](1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ['x'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['y'](1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(ZZ['x'](1)*vector(ZZ['y'],[1,2])) + sage: parent(QQ(1) * vector(ZZ['x'], [1,2])) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x'](1) * vector(QQ, [1,2])) # needs sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ(1) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ, [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['x'](1) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ['x'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['y'](1) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(ZZ['x'](1) * vector(ZZ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(ZZ['x'](1)*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(ZZ['x'](1) * vector(QQ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(QQ['x'](1)*vector(ZZ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(QQ['x'](1) * vector(ZZ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(QQ['x'](1)*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(QQ['x'](1) * vector(QQ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' """ if have_same_parent(left, right): return (left)._dot_product_(right) @@ -3607,14 +3698,15 @@ cdef class Vector(ModuleElementWithMutability): TESTS:: - sage: A = matrix([[1, 2], [0, 3]]) # optional - sage.modules - sage: b = vector([0, 1]) # optional - sage.modules - sage: x = b / A; x # optional - sage.modules + sage: # needs sage.modules + sage: A = matrix([[1, 2], [0, 3]]) + sage: b = vector([0, 1]) + sage: x = b / A; x (0, 1/3) - sage: x == b * ~A # optional - sage.modules + sage: x == b * ~A True - sage: A = matrix([[1, 2], [0, 3], [1, 5]]) # optional - sage.modules - sage: (b / A) * A == b # optional - sage.modules + sage: A = matrix([[1, 2], [0, 3], [1, 5]]) + sage: (b / A) * A == b True """ right = py_scalar_to_element(right) @@ -3641,31 +3733,34 @@ cdef class Vector(ModuleElementWithMutability): EXAMPLES:: - sage: v = vector([1,2,3]) # optional - sage.modules - sage: v._magma_init_(magma) # optional - magma # optional - sage.modules + sage: # optional - magma, needs sage.modules + sage: v = vector([1,2,3]) + sage: v._magma_init_(magma) '_sage_[...]![1,2,3]' - sage: mv = magma(v); mv # optional - magma # optional - sage.modules + sage: mv = magma(v); mv (1 2 3) - sage: mv.Type() # optional - magma # optional - sage.modules + sage: mv.Type() ModTupRngElt - sage: mv.Parent() # optional - magma # optional - sage.modules + sage: mv.Parent() Full RSpace of degree 3 over Integer Ring - sage: v = vector(QQ, [1/2, 3/4, 5/6]) # optional - sage.modules - sage: mv = magma(v); mv # optional - magma # optional - sage.modules + sage: # optional - magma, needs sage.modules + sage: v = vector(QQ, [1/2, 3/4, 5/6]) + sage: mv = magma(v); mv (1/2 3/4 5/6) - sage: mv.Type() # optional - magma # optional - sage.modules + sage: mv.Type() ModTupFldElt - sage: mv.Parent() # optional - magma # optional - sage.modules + sage: mv.Parent() Full Vector space of degree 3 over Rational Field A more demanding example:: + sage: # optional - magma, needs sage.modules sage: R. = QQ[] - sage: v = vector([x^3, y, 2/3*z + x/y]) # optional - sage.modules - sage: magma(v) # optional - magma # optional - sage.modules + sage: v = vector([x^3, y, 2/3*z + x/y]) + sage: magma(v) ( x^3 y (2/3*y*z + x)/y) - sage: magma(v).Parent() # optional - magma # optional - sage.modules + sage: magma(v).Parent() Full Vector space of degree 3 over Multivariate rational function field of rank 3 over Rational Field """ @@ -3701,57 +3796,73 @@ cdef class Matrix(ModuleElement): Here we test (matrix * matrix) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4])) + sage: # needs sage.modules + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * matrix(ZZ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ['x'],2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ['x'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' We test that the bug reported in :trac:`27352` has been fixed:: - sage: A = matrix(QQ, [[1, 2], [-1, 0], [1, 1]]) - sage: B = matrix(QQ, [[0, 4], [1, -1], [1, 2]]) - sage: A*B + sage: A = matrix(QQ, [[1, 2], [-1, 0], [1, 1]]) # needs sage.modules + sage: B = matrix(QQ, [[0, 4], [1, -1], [1, 2]]) # needs sage.modules + sage: A * B # needs sage.modules Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: @@ -3759,48 +3870,64 @@ cdef class Matrix(ModuleElement): Here we test (matrix * vector) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(ZZ,[1,2])) + sage: # needs sage.modules + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * vector(ZZ, [1,2])) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ,[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(QQ,[1,2])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(QQ,[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) Vector space of dimension 2 over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ['x'],[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(QQ,[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ,[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ['x'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(ZZ['y'],[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ['x'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # needs sage.modules + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ['x'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) # needs sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(ZZ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['y'], [1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: @@ -3809,105 +3936,137 @@ cdef class Matrix(ModuleElement): Here we test (matrix * scalar) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*ZZ(1)) + sage: # needs sage.modules + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * ZZ(1)) Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ(1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ(1)) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * QQ(1)) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * QQ(1)) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ['x'](1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ['x'](1)) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * QQ(1)) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ(1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ['x'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*ZZ['y'](1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ(1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ['x'](1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ['y'](1)) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * ZZ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * QQ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*ZZ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * ZZ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * QQ['y'](1)) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Rational Field' Here we test (scalar * matrix) multiplication:: - sage: parent(ZZ(1)*matrix(ZZ,2,2,[1,2,3,4])) + sage: # needs sage.modules + sage: parent(ZZ(1) * matrix(ZZ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(QQ(1)*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(ZZ(1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(ZZ(1) * matrix(QQ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(QQ(1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(QQ, 2, 2, [1,2,3,4])) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(QQ(1)*matrix(ZZ['x'],2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x'](1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(ZZ['x'](1) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(QQ(1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ,2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['x'](1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ['x'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['y'](1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(ZZ['x'](1)*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ, 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['x'](1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['y'](1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # needs sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: # needs sage.modules + sage: parent(ZZ['x'](1) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(ZZ['x'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(ZZ['x'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(QQ['x'](1)*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(QQ['x'](1) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(QQ['x'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(QQ['x'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' Examples with matrices having matrix coefficients:: - sage: m = matrix - sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) - sage: 3*a + sage: m = matrix # needs sage.modules + sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) # needs sage.modules + sage: 3 * a # needs sage.modules [[ 3 6] [ 9 12] [15 18] [21 24]] @@ -3915,9 +4074,9 @@ cdef class Matrix(ModuleElement): [33 36] [39 42] [45 48]] - sage: m = matrix - sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) - sage: a*3 + sage: m = matrix # needs sage.modules + sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) # needs sage.modules + sage: a * 3 # needs sage.modules [[ 3 6] [ 9 12] [15 18] [21 24]] @@ -3959,32 +4118,34 @@ cdef class Matrix(ModuleElement): EXAMPLES:: - sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules - sage: operator.truediv(a, 5) # optional - sage.modules + sage: # needs sage.modules + sage: a = matrix(ZZ, 2, range(4)) + sage: operator.truediv(a, 5) [ 0 1/5] [2/5 3/5] - sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules - sage: b = matrix(ZZ, 2, [1,1,0,5]) # optional - sage.modules - sage: operator.truediv(a, b) # optional - sage.modules + sage: a = matrix(ZZ, 2, range(4)) + sage: b = matrix(ZZ, 2, [1,1,0,5]) + sage: operator.truediv(a, b) [ 0 1/5] [ 2 1/5] - sage: c = matrix(QQ, 2, [3,2,5,7]) # optional - sage.modules - sage: operator.truediv(c, a) # optional - sage.modules + sage: c = matrix(QQ, 2, [3,2,5,7]) + sage: operator.truediv(c, a) [-5/2 3/2] [-1/2 5/2] TESTS:: - sage: a = matrix(ZZ, [[1, 2], [0, 3]]) # optional - sage.modules - sage: b = matrix(ZZ, 3, 2, range(6)) # optional - sage.modules - sage: x = b / a; x # optional - sage.modules + sage: # needs sage.modules + sage: a = matrix(ZZ, [[1, 2], [0, 3]]) + sage: b = matrix(ZZ, 3, 2, range(6)) + sage: x = b / a; x [ 0 1/3] [ 2 -1/3] [ 4 -1] - sage: x == b * ~a # optional - sage.modules + sage: x == b * ~a True - sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) # optional - sage.modules - sage: (b / a) * a == b # optional - sage.modules + sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) + sage: (b / a) * a == b True """ if is_Matrix(right): @@ -4040,14 +4201,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.gcd(pari(3)) # optional - sage.libs.pari + sage: 2.gcd(pari(3)) # needs sage.libs.pari 1 - sage: type(2.gcd(pari(3))) # optional - sage.libs.pari + sage: type(2.gcd(pari(3))) # needs sage.libs.pari - sage: 2.gcd(pari('1/3')) # optional - sage.libs.pari + sage: 2.gcd(pari('1/3')) # needs sage.libs.pari 1/3 - sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari + sage: type(2.gcd(pari('1/3'))) # needs sage.libs.pari sage: import gmpy2 @@ -4058,7 +4219,7 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): sage: 2.gcd(gmpy2.mpq(1,3)) 1/3 - sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari + sage: type(2.gcd(pari('1/3'))) # needs sage.libs.pari """ # NOTE: in order to handle nicely pari or gmpy2 integers we do not rely only on coercion @@ -4079,14 +4240,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.lcm(pari(3)) # optional - sage.libs.pari + sage: 2.lcm(pari(3)) # needs sage.libs.pari 6 - sage: type(2.lcm(pari(3))) # optional - sage.libs.pari + sage: type(2.lcm(pari(3))) # needs sage.libs.pari - sage: 2.lcm(pari('1/3')) # optional - sage.libs.pari + sage: 2.lcm(pari('1/3')) # needs sage.libs.pari 2 - sage: type(2.lcm(pari('1/3'))) # optional - sage.libs.pari + sage: type(2.lcm(pari('1/3'))) # needs sage.libs.pari sage: import gmpy2 @@ -4136,15 +4297,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e // e # optional - sage.misc.cython + sage: e = MyElt(SR) # needs sage.misc.cython sage.symbolic + sage: e // e # needs sage.misc.cython sage.symbolic quo """ Q, _ = self.quo_rem(right) @@ -4167,15 +4328,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): :: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e % e # optional - sage.misc.cython + sage: e = MyElt(SR) # needs sage.misc.cython sage.symbolic + sage: e % e # needs sage.misc.cython sage.symbolic rem """ _, R = self.quo_rem(other) @@ -4196,13 +4357,14 @@ cdef class FieldElement(CommutativeRingElement): EXAMPLES:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^4 + x^2 + 2/3) # optional - sage.rings.number_field - sage: c = (1+b) // (1-b); c # optional - sage.rings.number_field + sage: K. = NumberField(x^4 + x^2 + 2/3) + sage: c = (1+b) // (1-b); c 3/4*b^3 + 3/4*b^2 + 3/2*b + 1/2 - sage: (1+b) / (1-b) == c # optional - sage.rings.number_field + sage: (1+b) / (1-b) == c True - sage: c * (1-b) # optional - sage.rings.number_field + sage: c * (1-b) b + 1 """ return self._div_(right) @@ -4251,9 +4413,10 @@ cdef class FieldElement(CommutativeRingElement): Test if :trac:`8671` is fixed:: + sage: # needs sage.libs.pari sage.libs.singular sage: R. = QQ[] sage: S. = R.quo(y^2 + 1) - sage: S.is_field = lambda : False + sage: S.is_field = lambda: False sage: F = Frac(S); u = F.one() sage: u.quo_rem(u) (1, 0) @@ -4271,14 +4434,15 @@ cdef class FieldElement(CommutativeRingElement): EXAMPLES:: - sage: K. = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic - sage: K(0).divides(rt3) # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: K. = QQ[sqrt(3)] + sage: K(0).divides(rt3) False - sage: rt3.divides(K(17)) # optional - sage.rings.number_field sage.symbolic + sage: rt3.divides(K(17)) True - sage: K(0).divides(K(0)) # optional - sage.rings.number_field sage.symbolic + sage: K(0).divides(K(0)) True - sage: rt3.divides(K(0)) # optional - sage.rings.number_field sage.symbolic + sage: rt3.divides(K(0)) True """ if not (other._parent is self._parent): @@ -4293,8 +4457,8 @@ def is_AlgebraElement(x): TESTS:: sage: from sage.structure.element import is_AlgebraElement - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: is_AlgebraElement(x * y) # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) # needs sage.combinat sage.modules + sage: is_AlgebraElement(x * y) # needs sage.combinat sage.modules True sage: is_AlgebraElement(1) @@ -4352,8 +4516,8 @@ cpdef canonical_coercion(x, y): EXAMPLES:: - sage: A = Matrix([[0, 1], [1, 0]]) # optional - sage.modules - sage: canonical_coercion(A, 1) # optional - sage.modules + sage: A = Matrix([[0, 1], [1, 0]]) # needs sage.modules + sage: canonical_coercion(A, 1) # needs sage.modules ( [0 1] [1 0] [1 0], [0 1] @@ -4403,12 +4567,12 @@ def coercion_traceback(dump=True): sage: 1 + 1/5 6/5 sage: coercion_traceback() # Should be empty, as all went well. - sage: 1/5 + GF(5).gen() # optional - sage.rings.finite_rings + sage: 1/5 + GF(5).gen() Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: 'Rational Field' and 'Finite Field of size 5' - sage: coercion_traceback() # optional - sage.rings.finite_rings + sage: coercion_traceback() Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: diff --git a/src/sage/structure/element_wrapper.pyx b/src/sage/structure/element_wrapper.pyx index 44aa88ea530..3aa87527d92 100644 --- a/src/sage/structure/element_wrapper.pyx +++ b/src/sage/structure/element_wrapper.pyx @@ -209,8 +209,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') # optional - sage.symbolic - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() # optional - sage.symbolic + sage: x = var('x') # needs sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() # needs sage.symbolic 2 x + x """ @@ -226,8 +226,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') # optional - sage.symbolic - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() # optional - sage.symbolic + sage: x = var('x') # needs sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() # needs sage.symbolic 2 x + x """ @@ -561,8 +561,8 @@ cdef class ElementWrapperCheckWrappedClass(ElementWrapper): :: sage: A = cartesian_product([ZZ, ZZ]) - sage: B = cartesian_product([GF(3), GF(5)]) # optional - sage.rings.finite_rings - sage: A((3,5)) == B((0,0)) # optional - sage.rings.finite_rings + sage: B = cartesian_product([GF(3), GF(5)]) + sage: A((3,5)) == B((0,0)) True """ if type(self) is type(right): diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 347aa727947..00571876e39 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -66,87 +66,94 @@ This more complicated example involving polynomials also illustrates that the unit part is not discarded from factorizations:: + sage: # needs sage.libs.pari sage: x = QQ['x'].0 sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F # optional - sage.libs.pari + sage: F = f.factor(); F (-5) * (x - 3) * (x - 2) - sage: F.unit() # optional - sage.libs.pari + sage: F.unit() -5 - sage: F.value() # optional - sage.libs.pari + sage: F.value() -5*x^2 + 25*x - 30 The underlying list is the list of pairs `(p_i, e_i)`, where each `p_i` is a 'prime' and each `e_i` is an integer. The unit part is discarded by the list:: - sage: list(F) # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: list(F) [(x - 3, 1), (x - 2, 1)] - sage: len(F) # optional - sage.libs.pari + sage: len(F) 2 - sage: F[1] # optional - sage.libs.pari + sage: F[1] (x - 2, 1) In the ring `\ZZ[x]`, the integer `-5` is not a unit, so the factorization has three factors:: + sage: # needs sage.libs.pari sage: x = ZZ['x'].0 sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F # optional - sage.libs.pari + sage: F = f.factor(); F (-1) * 5 * (x - 3) * (x - 2) - sage: F.universe() # optional - sage.libs.pari + sage: F.universe() Univariate Polynomial Ring in x over Integer Ring - sage: F.unit() # optional - sage.libs.pari + sage: F.unit() -1 - sage: list(F) # optional - sage.libs.pari + sage: list(F) [(5, 1), (x - 3, 1), (x - 2, 1)] - sage: F.value() # optional - sage.libs.pari + sage: F.value() -5*x^2 + 25*x - 30 - sage: len(F) # optional - sage.libs.pari + sage: len(F) 3 On the other hand, -1 is a unit in `\ZZ`, so it is included in the unit:: + sage: # needs sage.libs.pari sage: x = ZZ['x'].0 - sage: f = -1*(x-2)*(x-3) # optional - sage.libs.pari - sage: F = f.factor(); F # optional - sage.libs.pari + sage: f = -1 * (x-2) * (x-3) + sage: F = f.factor(); F (-1) * (x - 3) * (x - 2) - sage: F.unit() # optional - sage.libs.pari + sage: F.unit() -1 - sage: list(F) # optional - sage.libs.pari + sage: list(F) [(x - 3, 1), (x - 2, 1)] Factorizations can involve fairly abstract mathematical objects:: - sage: F = ModularSymbols(11,4).factorization(); F # optional - sage.modular + sage: # needs sage.modular + sage: F = ModularSymbols(11,4).factorization(); F (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) - sage: type(F) # optional - sage.modular + sage: type(F) - sage: K. = NumberField(x^2 + 3); K # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: x = ZZ['x'].0 + sage: K. = NumberField(x^2 + 3); K Number Field in a with defining polynomial x^2 + 3 - sage: f = K.factor(15); f # optional - sage.rings.number_field + sage: f = K.factor(15); f (Fractional ideal (1/2*a + 3/2))^2 * (Fractional ideal (5)) - sage: f.universe() # optional - sage.rings.number_field + sage: f.universe() Monoid of ideals of Number Field in a with defining polynomial x^2 + 3 - sage: f.unit() # optional - sage.rings.number_field + sage: f.unit() Fractional ideal (1) - sage: g = K.factor(9); g # optional - sage.rings.number_field + sage: g = K.factor(9); g (Fractional ideal (1/2*a + 3/2))^4 - sage: f.lcm(g) # optional - sage.rings.number_field + sage: f.lcm(g) (Fractional ideal (1/2*a + 3/2))^4 * (Fractional ideal (5)) - sage: f.gcd(g) # optional - sage.rings.number_field + sage: f.gcd(g) (Fractional ideal (1/2*a + 3/2))^2 - sage: f.is_integral() # optional - sage.rings.number_field + sage: f.is_integral() True TESTS:: @@ -208,7 +215,7 @@ class Factorization(SageObject): -1 sage: loads(F.dumps()) == F True - sage: F = Factorization([(x, 1/3)]) # optional - sage.symbolic + sage: F = Factorization([(x, 1/3)]) # needs sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer @@ -284,13 +291,13 @@ def __init__(self, x, unit=None, cr=False, sort=True, simplify=True): sage: Factorization([(2, 7), (5,2), (2, 5)]) 2^12 * 5^2 - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: Factorization([(a,1), (b,1), (a,2)]) # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) # needs sage.combinat sage.modules + sage: Factorization([(a,1), (b,1), (a,2)]) # needs sage.combinat sage.modules a * b * a^2 Autosorting (the default) swaps around the factors below:: - sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F # optional - sage.modules + sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F # needs sage.modules (Ambient free module of rank 2 over the principal ideal domain Integer Ring)^5 * (Ambient free module of rank 3 over the principal ideal domain Integer Ring)^2 """ @@ -416,7 +423,7 @@ def __richcmp__(self, other, op): sage: x = polygen(QQ) sage: x^2 - 1 > x^2 - 4 True - sage: factor(x^2 - 1) > factor(x^2 - 4) # optional - sage.libs.pari + sage: factor(x^2 - 1) > factor(x^2 - 4) # needs sage.libs.pari True """ if not isinstance(other, Factorization): @@ -523,13 +530,13 @@ def universe(self): sage: F.universe() Integer Ring - sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules - sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules - sage: (F*F^-1).universe() # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 3) # needs sage.combinat sage.modules + sage: F = Factorization([(z, 2)], 3) # needs sage.combinat sage.modules + sage: (F*F^-1).universe() # needs sage.combinat sage.modules Free Algebra on 3 generators (x, y, z) over Rational Field - sage: F = ModularSymbols(11,4).factorization() # optional - sage.modular - sage: F.universe() # optional - sage.modular + sage: F = ModularSymbols(11,4).factorization() # needs sage.modular + sage: F.universe() # needs sage.modular """ try: return self.__universe @@ -554,11 +561,11 @@ def base_change(self, U): possible:: sage: g = x^2 - 1 - sage: F = factor(g); F # optional - sage.libs.pari + sage: F = factor(g); F # needs sage.libs.pari (x - 1) * (x + 1) - sage: F.universe() # optional - sage.libs.pari + sage: F.universe() # needs sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: F.base_change(ZZ) # optional - sage.libs.pari + sage: F.base_change(ZZ) # needs sage.libs.pari Traceback (most recent call last): ... TypeError: Impossible to coerce the factors of (x - 1) * (x + 1) into Integer Ring @@ -579,15 +586,19 @@ def is_commutative(self) -> bool: sage: F = factor(2006) sage: F.is_commutative() True - sage: K = QuadraticField(23, 'a') # optional - sage.rings.number_field - sage: F = K.factor(13) # optional - sage.rings.number_field - sage: F.is_commutative() # optional - sage.rings.number_field + + sage: # needs sage.rings.number_field + sage: K = QuadraticField(23, 'a') + sage: F = K.factor(13) + sage: F.is_commutative() True - sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules - sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules - sage: F.is_commutative() # optional - sage.combinat sage.modules + + sage: # needs sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 3) + sage: F = Factorization([(z, 2)], 3) + sage: F.is_commutative() False - sage: (F*F^-1).is_commutative() # optional - sage.combinat sage.modules + sage: (F*F^-1).is_commutative() False """ try: @@ -605,14 +616,14 @@ def _set_cr(self, cr): EXAMPLES:: sage: x = polygen(QQ,'x') - sage: F = factor(x^6 - 1); F # optional - sage.libs.pari + sage: F = factor(x^6 - 1); F # needs sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(True); F # optional - sage.libs.pari + sage: F._set_cr(True); F # needs sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(False); F # optional - sage.libs.pari + sage: F._set_cr(False); F # needs sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) """ self.__cr = bool(cr) @@ -623,12 +634,13 @@ def simplify(self): TESTS:: - sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: R. = FreeAlgebra(ZZ, 2) + sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F x^3 * y^2 * y^2 - sage: F.simplify(); F # optional - sage.combinat sage.modules + sage: F.simplify(); F x^3 * y^4 - sage: F * Factorization([(y, -2)], 2) # optional - sage.combinat sage.modules + sage: F * Factorization([(y, -2)], 2) (2) * x^3 * y^2 """ repeat = False @@ -677,13 +689,13 @@ def sort(self, key=None): We create a factored polynomial:: sage: x = polygen(QQ, 'x') - sage: F = factor(x^3 + 1); F # optional - sage.libs.pari + sage: F = factor(x^3 + 1); F # needs sage.libs.pari (x + 1) * (x^2 - x + 1) We sort it by decreasing degree:: - sage: F.sort(key=lambda x: (-x[0].degree(), x)) # optional - sage.libs.pari - sage: F # optional - sage.libs.pari + sage: F.sort(key=lambda x: (-x[0].degree(), x)) # needs sage.libs.pari + sage: F # needs sage.libs.pari (x^2 - x + 1) * (x + 1) """ if len(self) == 0: @@ -728,12 +740,12 @@ def unit(self): We create a polynomial over the real double field and factor it:: sage: x = polygen(RDF, 'x') - sage: F = factor(-2*x^2 - 1); F + sage: F = factor(-2*x^2 - 1); F # needs numpy (-2.0) * (x^2 + 0.5000000000000001) Note that the unit part of the factorization is `-2.0`:: - sage: F.unit() + sage: F.unit() # needs numpy -2.0 sage: F = factor(-2006); F @@ -772,7 +784,7 @@ def _cr(self): Next we factor a modular symbols space:: - sage: F = ModularSymbols(11).factor(); F # optional - sage.modular + sage: F = ModularSymbols(11).factor(); F # needs sage.modular (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...) @@ -864,7 +876,7 @@ def _latex_(self): -1 \cdot 2^{2} \cdot 5^{2} sage: f._latex_() '-1 \\cdot 2^{2} \\cdot 5^{2}' - sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 # optional - sage.rings.number_field + sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 # needs sage.rings.number_field '(x^{2} + x + 1.000000000000000?)' """ if len(self) == 0: @@ -901,12 +913,12 @@ def __pari__(self): EXAMPLES:: sage: f = factor(-24) - sage: pari(f) # optional - sage.libs.pari + sage: pari(f) # needs sage.libs.pari [-1, 1; 2, 3; 3, 1] sage: R. = QQ[] - sage: g = factor(x^10 - 1) # optional - sage.libs.pari - sage: pari(g) # optional - sage.libs.pari + sage: g = factor(x^10 - 1) # needs sage.libs.pari + sage: pari(g) # needs sage.libs.pari [x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1] """ @@ -1006,12 +1018,12 @@ def __rmul__(self, left): -2 * 3 * 5 sage: a * -2 -2 * 3 * 5 - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: f = Factorization([(x,2), (y,3)]); f # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) # needs sage.combinat sage.modules + sage: f = Factorization([(x,2), (y,3)]); f # needs sage.combinat sage.modules x^2 * y^3 - sage: x * f # optional - sage.combinat sage.modules + sage: x * f # needs sage.combinat sage.modules x^3 * y^3 - sage: f * x # optional - sage.combinat sage.modules + sage: f * x # needs sage.combinat sage.modules x^2 * y^3 * x Note that this does not automatically factor ``left``:: @@ -1038,12 +1050,13 @@ def __mul__(self, other): sage: factor(-10) * factor(16) -1 * 2^5 * 5 - sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: R. = FreeAlgebra(ZZ, 2) + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F x^3 * y^2 * x - sage: F*F # optional - sage.combinat sage.modules + sage: F*F x^3 * y^2 * x^4 * y^2 * x - sage: -1 * F # optional - sage.combinat sage.modules + sage: -1 * F (-1) * x^3 * y^2 * x sage: P. = ZZ[] @@ -1101,16 +1114,16 @@ def __pow__(self, n): 2^8 * 5^8 sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - 39*x - 91) # optional - sage.rings.number_field - sage: F = K.factor(7); F # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 39*x - 91) # needs sage.rings.number_field + sage: F = K.factor(7); F # needs sage.rings.number_field (Fractional ideal (7, a)) * (Fractional ideal (7, a + 2)) * (Fractional ideal (7, a - 2)) - sage: F^9 # optional - sage.rings.number_field + sage: F^9 # needs sage.rings.number_field (Fractional ideal (7, a))^9 * (Fractional ideal (7, a + 2))^9 * (Fractional ideal (7, a - 2))^9 - sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(ZZ, 2) # needs sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # needs sage.combinat sage.modules x^3 * y^2 * x - sage: F**2 # optional - sage.combinat sage.modules + sage: F**2 # needs sage.combinat sage.modules x^3 * y^2 * x^4 * y^2 * x """ from sage.rings.integer import Integer @@ -1143,10 +1156,10 @@ def __invert__(self): sage: F^-1 2^-1 * 17^-1 * 59^-1 - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) # needs sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F # needs sage.combinat sage.modules (2) * x^3 * y^2 * x - sage: F^-1 # optional - sage.combinat sage.modules + sage: F^-1 # needs sage.combinat sage.modules (1/2) * x^-1 * y^-2 * x^-3 """ return Factorization([(p, -e) for p, e in reversed(self)], @@ -1164,12 +1177,13 @@ def __truediv__(self, other): sage: factor(-10) / factor(16) -1 * 2^-3 * 5 - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F x^3 * y^2 * x - sage: G = Factorization([(y, 1), (x,1)],1); G # optional - sage.combinat sage.modules + sage: G = Factorization([(y, 1), (x,1)],1); G y * x - sage: F / G # optional - sage.combinat sage.modules + sage: F / G x^3 * y """ if not isinstance(other, Factorization): @@ -1187,11 +1201,12 @@ def __call__(self, *args, **kwds): EXAMPLES:: - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)]) # optional - sage.combinat sage.modules - sage: F(x=4) # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: R. = FreeAlgebra(QQ, 2) + sage: F = Factorization([(x,3), (y, 2), (x,1)]) + sage: F(x=4) (1) * 4^3 * y^2 * 4 - sage: F.subs({y:2}) # optional - sage.combinat sage.modules + sage: F.subs({y:2}) x^3 * 2^2 * x sage: R. = PolynomialRing(QQ, 2) @@ -1217,9 +1232,9 @@ def __call__(self, *args, **kwds): sage: F(t=0) 0 - sage: R. = LaurentPolynomialRing(QQ, 1) - sage: F = ((x+2)/x**3).factor() - sage: F(x=4) + sage: R. = LaurentPolynomialRing(QQ, 1) # needs sage.modules + sage: F = ((x+2)/x**3).factor() # needs sage.modules + sage: F(x=4) # needs sage.modules 1/64 * 6 """ unit = self.__unit.subs(*args, **kwds) @@ -1243,10 +1258,10 @@ def value(self): sage: F.value() -2006 - sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules + sage: R. = FreeAlgebra(ZZ, 2) # needs sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # needs sage.combinat sage.modules x^3 * y^2 * x - sage: F.value() # optional - sage.combinat sage.modules + sage: F.value() # needs sage.combinat sage.modules x^3*y^2*x """ from sage.misc.misc_c import prod @@ -1272,7 +1287,7 @@ def gcd(self, other): 2 * 5 sage: R. = ZZ[] - sage: (factor(-20).gcd(factor(5*x+10))).universe() # optional - sage.libs.pari + sage: (factor(-20).gcd(factor(5*x+10))).universe() # needs sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): @@ -1314,7 +1329,7 @@ def lcm(self, other): 2^4 * 5 sage: R. = ZZ[] - sage: (factor(-20).lcm(factor(5*x + 10))).universe() # optional - sage.libs.pari + sage: (factor(-20).lcm(factor(5*x + 10))).universe() # needs sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): diff --git a/src/sage/structure/factory.pyx b/src/sage/structure/factory.pyx index f47f0ea96fa..ddb55501d94 100644 --- a/src/sage/structure/factory.pyx +++ b/src/sage/structure/factory.pyx @@ -196,7 +196,7 @@ cdef class UniqueFactory(SageObject): :class:`object`. The third allows attribute assignment and is derived from :class:`object`. :: - sage: cython("cdef class C: pass") # optional - sage.misc.cython + sage: cython("cdef class C: pass") # needs sage.misc.cython sage: class D: ....: def __init__(self, *args): ....: self.t = args @@ -214,7 +214,7 @@ cdef class UniqueFactory(SageObject): It is impossible to create an instance of ``C`` with our factory, since it does not allow weak references:: - sage: F(1, impl='C') # optional - sage.misc.cython + sage: F(1, impl='C') # needs sage.misc.cython Traceback (most recent call last): ... TypeError: cannot create weak reference to '....C' object @@ -222,14 +222,14 @@ cdef class UniqueFactory(SageObject): Let us try again, with a Cython class that does allow weak references. Now, creation of an instance using the factory works:: - sage: cython( # optional - sage.misc.cython + sage: cython( # needs sage.misc.cython ....: ''' ....: cdef class C: ....: cdef __weakref__ ....: ''') ....: - sage: c = F(1, impl='C') # optional - sage.misc.cython - sage: isinstance(c, C) # optional - sage.misc.cython + sage: c = F(1, impl='C') # needs sage.misc.cython + sage: isinstance(c, C) # needs sage.misc.cython True The cache is used when calling the factory again---even if it is suggested @@ -237,16 +237,16 @@ cdef class UniqueFactory(SageObject): only considered an "extra argument" that does not count for the key. :: - sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # optional - sage.misc.cython + sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # needs sage.misc.cython True However, pickling and unpickling does not use the cache. This is because the factory has tried to assign an attribute to the instance that provides information on the key used to create the instance, but failed:: - sage: loads(dumps(c)) is c # optional - sage.misc.cython + sage: loads(dumps(c)) is c # needs sage.misc.cython False - sage: hasattr(c, '_factory_data') # optional - sage.misc.cython + sage: hasattr(c, '_factory_data') # needs sage.misc.cython False We have already seen that our factory will only take the requested @@ -313,17 +313,19 @@ cdef class UniqueFactory(SageObject): """ EXAMPLES:: - sage: A = FiniteField(127) # optional - sage.rings.finite_rings - sage: A is loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings + sage: A = FiniteField(127) + sage: A is loads(dumps(A)) # indirect doctest True - sage: B = FiniteField(3^3,'b') # optional - sage.rings.finite_rings - sage: B is loads(dumps(B)) # optional - sage.rings.finite_rings + + sage: # needs sage.rings.finite_rings + sage: B = FiniteField(3^3,'b') + sage: B is loads(dumps(B)) True - sage: C = FiniteField(2^16,'c') # optional - sage.rings.finite_rings - sage: C is loads(dumps(C)) # optional - sage.rings.finite_rings + sage: C = FiniteField(2^16,'c') + sage: C is loads(dumps(C)) True - sage: D = FiniteField(3^20,'d') # optional - sage.rings.finite_rings - sage: D is loads(dumps(D)) # optional - sage.rings.finite_rings + sage: D = FiniteField(3^20,'d') + sage: D is loads(dumps(D)) True TESTS:: @@ -396,10 +398,10 @@ cdef class UniqueFactory(SageObject): Check that :trac:`16317` has been fixed, i.e., caching works for unhashable objects:: - sage: K. = Qq(4) # optional - sage.rings.padics - sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: K. = Qq(4) # needs sage.rings.padics + sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # needs sage.rings.padics Making object (1 + O(2^20), 'c') - sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # needs sage.rings.padics True """ @@ -468,7 +470,7 @@ cdef class UniqueFactory(SageObject): sage: from sage.structure.test_factory import test_factory sage: test_factory.create_key_and_extra_args(1, 2, key=5) ((1, 2), {}) - sage: GF.create_key_and_extra_args(3) # optional - sage.rings.finite_rings + sage: GF.create_key_and_extra_args(3) ((3, ('x',), None, 'modn', 3, 1, True, None, None, None, True, False), {}) """ return self.create_key(*args, **kwds), {} @@ -518,15 +520,16 @@ cdef class UniqueFactory(SageObject): The ``GF`` factory used to have a custom :meth:`other_keys` method, but this was removed in :trac:`16934`:: - sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key # optional - sage.rings.finite_rings + sage: # needs sage.libs.linbox sage.ring.finite_rings + sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key (27, ('k',), x^3 + 2*x + 1, 'givaro', 3, 3, True, None, 'poly', True, True, True) - sage: K = GF.create_object(0, key); K # optional - sage.rings.finite_rings + sage: K = GF.create_object(0, key); K Finite Field in k of size 3^3 - sage: GF.other_keys(key, K) # optional - sage.rings.finite_rings + sage: GF.other_keys(key, K) [] - sage: K = GF(7^40, 'a') # optional - sage.rings.finite_rings - sage: loads(dumps(K)) is K # optional - sage.rings.finite_rings + sage: K = GF(7^40, 'a') # needs sage.rings.finite_rings + sage: loads(dumps(K)) is K # needs sage.rings.finite_rings True """ return [] @@ -540,12 +543,13 @@ cdef class UniqueFactory(SageObject): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules - sage: V = F(ZZ, 5) # optional - sage.modules - sage: factory, data = F.reduce_data(V) # optional - sage.modules - sage: factory(*data) # optional - sage.modules + sage: # needs sage.modules + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F + sage: V = F(ZZ, 5) + sage: factory, data = F.reduce_data(V) + sage: factory(*data) Ambient free module of rank 5 over the principal ideal domain Integer Ring - sage: factory(*data) is V # optional - sage.modules + sage: factory(*data) is V True sage: from sage.structure.test_factory import test_factory @@ -638,12 +642,13 @@ def generic_factory_unpickle(factory, *args): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules - sage: V = F(ZZ, 5) # optional - sage.modules - sage: func, data = F.reduce_data(V) # optional - sage.modules - sage: func is sage.structure.factory.generic_factory_unpickle # optional - sage.modules + sage: # needs sage.modules + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F + sage: V = F(ZZ, 5) + sage: func, data = F.reduce_data(V) + sage: func is sage.structure.factory.generic_factory_unpickle True - sage: sage.structure.factory.generic_factory_unpickle(*data) is V # optional - sage.modules + sage: sage.structure.factory.generic_factory_unpickle(*data) is V True TESTS: @@ -730,8 +735,8 @@ def generic_factory_reduce(self, proto): EXAMPLES:: - sage: V = QQ^6 # optional - sage.modules - sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) # optional - sage.modules + sage: V = QQ^6 # needs sage.modules + sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) # needs sage.modules True """ if self._factory_data is None: @@ -748,7 +753,7 @@ def lookup_global(name): sage: from sage.structure.factory import lookup_global sage: lookup_global('ZZ') Integer Ring - sage: lookup_global('sage.rings.all.ZZ') + sage: lookup_global('sage.rings.integer_ring.ZZ') Integer Ring """ name = bytes_to_str(name, encoding='ASCII') diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index 30b99f509c5..223ef23ce16 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -1,4 +1,3 @@ -# sage.doctest: optional - sage.modules """ Formal sums @@ -15,10 +14,11 @@ added. FormalSums now derives from UniqueRepresentation. FUNCTIONS: - - ``FormalSums(ring)`` -- create the module of formal finite sums with - coefficients in the given ring. - - ``FormalSum(list of pairs (coeff, number))`` -- create a formal sum +- ``FormalSums(ring)`` -- create the module of formal finite sums with + coefficients in the given ring. + +- ``FormalSum(list of pairs (coeff, number))`` -- create a formal sum. EXAMPLES:: @@ -104,25 +104,26 @@ def __init__(self, x, parent=None, check=True, reduce=True): sage: a.reduce() sage: a 4*2/3 - 5*7 - sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) # optional - sage.rings.finite_rings + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) 4*2/3 Notice below that the coefficient 5 doesn't get reduced modulo 5:: - sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5)), # optional - sage.rings.finite_rings + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5)), ....: check=False) 4*2/3 - 5*7 Make sure we first reduce before checking coefficient types:: - sage: x,y = var('x, y') # optional - sage.symbolic - sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x,y = var('x, y') + sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) 1/2*x + 2*y - sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic + sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic + sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) x + 2*y """ if x == 0: @@ -311,12 +312,12 @@ class FormalSums(UniqueRepresentation, Module): Abelian Group of all Formal Finite Sums over Integer Ring sage: FormalSums(ZZ) Abelian Group of all Formal Finite Sums over Integer Ring - sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings + sage: FormalSums(GF(7)) Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(ZZ[sqrt(2)]) # optional - sage.symbolic sage.rings.number_field + sage: FormalSums(ZZ[sqrt(2)]) # needs sage.rings.number_field sage.symbolic Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: FormalSums(GF(9,'a')) # optional - sage.rings.finite_rings + sage: FormalSums(GF(9,'a')) # needs sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field in a of size 3^2 TESTS:: @@ -342,9 +343,9 @@ def _repr_(self): """ EXAMPLES:: - sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings + sage: FormalSums(GF(7)) Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(GF(7))._repr_() # optional - sage.rings.finite_rings + sage: FormalSums(GF(7))._repr_() 'Abelian Group of all Formal Finite Sums over Finite Field of size 7' """ return "Abelian Group of all Formal Finite Sums over %s"%self.base_ring() @@ -404,12 +405,12 @@ def base_extend(self, R): """ EXAMPLES:: - sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 # optional - sage.rings.finite_rings + sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 Abelian Group of all Formal Finite Sums over Finite Field of size 7 The following tests against a bug that was fixed at :trac:`18795`:: - sage: isinstance(F7, F7.category().parent_class) # optional - sage.rings.finite_rings + sage: isinstance(F7, F7.category().parent_class) True """ if self.base_ring().has_coerce_map_from(R): diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index b202d7e7871..2c55464e145 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -387,7 +387,7 @@ class options(GlobalOptions): Here is an example to test the pickling of a :class:`GlobalOptions` instance:: - sage: TestSuite(Partitions.options).run() # optional - sage.combinat + sage: TestSuite(Partitions.options).run() # needs sage.combinat TESTS: @@ -526,15 +526,16 @@ class Option(): EXAMPLES:: - sage: Partitions.options.display # optional - sage.combinat + sage: # needs sage.combinat + sage: Partitions.options.display list - sage: Partitions.options.display = 'compact' # optional - sage.combinat - sage: Partitions.options.display('list') # optional - sage.combinat - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options.display = 'compact' + sage: Partitions.options.display('list') + sage: Partitions.options._reset() TESTS:: - sage: TestSuite(Partitions.options.display).run() # optional - sage.combinat + sage: TestSuite(Partitions.options.display).run() # needs sage.combinat """ __name__ = 'Option class' @@ -545,7 +546,7 @@ def __init__(self, options, name): EXAMPLES:: - sage: type(Partitions.options.display) # indirect doctest # optional - sage.combinat + sage: type(Partitions.options.display) # indirect doctest # needs sage.combinat """ self._name = name @@ -559,7 +560,7 @@ def __repr__(self): EXAMPLES:: - sage: Partitions.options.display # indirect doctest # optional - sage.combinat + sage: Partitions.options.display # indirect doctest # needs sage.combinat list """ # NOTE: we intentionally use str() instead of repr() @@ -572,7 +573,7 @@ def __add__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + ' is good' # optional - sage.combinat + sage: Tableaux.options.convention + ' is good' # needs sage.combinat 'English is good' """ return self._options[self._name] + other @@ -584,7 +585,7 @@ def __radd__(self, other): EXAMPLES:: - sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat + sage: 'Good ' + Tableaux.options.convention # needs sage.combinat 'Good English' """ return other + self._options[self._name] @@ -596,7 +597,7 @@ def __mul__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + ' is good' # optional - sage.combinat + sage: Tableaux.options.convention + ' is good' # needs sage.combinat 'English is good' """ return self._options[self._name] * other @@ -608,7 +609,7 @@ def __rmul__(self, other): EXAMPLES:: - sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat + sage: 'Good ' + Tableaux.options.convention # needs sage.combinat 'Good English' """ return other * self._options[self._name] @@ -619,14 +620,15 @@ def __bool__(self) -> bool: EXAMPLES:: - sage: RiggedConfigurations.options.half_width_boxes_type_B # optional - sage.combinat + sage: # needs sage.combinat sage.graphs sage.modules + sage: RiggedConfigurations.options.half_width_boxes_type_B True - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' 'yes' - sage: RiggedConfigurations.options.half_width_boxes_type_B = False # optional - sage.combinat - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat + sage: RiggedConfigurations.options.half_width_boxes_type_B = False + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' 'no' - sage: RiggedConfigurations.options._reset() # optional - sage.combinat + sage: RiggedConfigurations.options._reset() """ return bool(self._options[self._name]) @@ -636,12 +638,13 @@ def __call__(self, *args, **kwds): EXAMPLES:: - sage: Partitions.options.display() # indirect doctest # optional - sage.combinat + sage: # needs sage.combinat + sage: Partitions.options.display() # indirect doctest 'list' - sage: Partitions.options.display('exp') # indirect doctest # optional - sage.combinat - sage: Partitions.options.display() # indirect doctest # optional - sage.combinat + sage: Partitions.options.display('exp') # indirect doctest + sage: Partitions.options.display() # indirect doctest 'exp_low' - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options._reset() TESTS: @@ -696,11 +699,11 @@ def __eq__(self, other): EXAMPLES:: - sage: Tableaux.options.convention # optional - sage.combinat + sage: Tableaux.options.convention # needs sage.combinat English - sage: Tableaux.options.convention == "English" # optional - sage.combinat + sage: Tableaux.options.convention == "English" # needs sage.combinat True - sage: Tableaux.options.convention == "French" # optional - sage.combinat + sage: Tableaux.options.convention == "French" # needs sage.combinat False """ return self._options[self._name] == other @@ -712,11 +715,11 @@ def __ne__(self, other): EXAMPLES:: - sage: Tableaux.options.convention # optional - sage.combinat + sage: Tableaux.options.convention # needs sage.combinat English - sage: Tableaux.options.convention != "English" # optional - sage.combinat + sage: Tableaux.options.convention != "English" # needs sage.combinat False - sage: Tableaux.options.convention != "French" # optional - sage.combinat + sage: Tableaux.options.convention != "French" # needs sage.combinat True """ return self._options[self._name] != other @@ -728,7 +731,7 @@ def __hash__(self): EXAMPLES:: - sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) # optional - sage.combinat + sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) # needs sage.combinat True """ return hash(self._options[self._name]) @@ -740,7 +743,7 @@ def __str__(self): EXAMPLES:: - sage: str(Tableaux.options.convention) # optional - sage.combinat + sage: str(Tableaux.options.convention) # needs sage.combinat 'English' """ return str(self._options[self._name]) @@ -1232,7 +1235,7 @@ def _instancedoc_(self): EXAMPLES:: - sage: print(Partitions.options.__doc__) # optional - sage.combinat + sage: print(Partitions.options.__doc__) # needs sage.combinat Sets and displays the global options for elements of the partition, skew partition, and partition tuple classes. If no parameters are @@ -1273,12 +1276,12 @@ def __setattr__(self, name, value=None): EXAMPLES:: - sage: Partitions.options.display = 'exp' # optional - sage.combinat - sage: Partitions.options.dispplay = 'list' # optional - sage.combinat + sage: Partitions.options.display = 'exp' # needs sage.combinat + sage: Partitions.options.dispplay = 'list' # needs sage.combinat Traceback (most recent call last): ... ValueError: dispplay is not an option for Partitions - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options._reset() # needs sage.combinat """ # Underscore, and "special", attributes are set using type.__setattr__ if name[0] == '_' or name in ['reset', 'dispatch', 'default_value']: @@ -1298,24 +1301,25 @@ def __setstate__(self, state): EXAMPLES:: - sage: Partitions.options() # optional - sage.combinat + sage: # needs sage.combinat + sage: Partitions.options() Current options for Partitions - convention: English - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options.convention = "French" # optional - sage.combinat - sage: pickle = dumps(Partitions.options) # optional - sage.combinat - sage: Partitions.options._reset() # reset options # optional - sage.combinat - sage: loads(pickle) # indirect doctest # optional - sage.combinat + sage: Partitions.options.convention = "French" + sage: pickle = dumps(Partitions.options) + sage: Partitions.options._reset() # reset options + sage: loads(pickle) # indirect doctest Current options for Partitions - convention: French - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options._reset() """ # open the options for the corresponding "parent" and copy all of # the data from its options class into unpickle @@ -1350,8 +1354,8 @@ def __getstate__(self): EXAMPLES:: - sage: Partitions.options._reset() # optional - sage.combinat - sage: Partitions.options.__getstate__() # optional - sage.combinat + sage: Partitions.options._reset() # needs sage.combinat + sage: Partitions.options.__getstate__() # needs sage.combinat {'convention': 'English', 'option_class': 'Partitions', 'options_module': 'sage.combinat.partition'} @@ -1385,9 +1389,9 @@ def __eq__(self, other): EXAMPLES:: - sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest # optional - sage.combinat + sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest # needs sage.combinat True - sage: Partitions.options == Tableaux.options # optional - sage.combinat + sage: Partitions.options == Tableaux.options # needs sage.combinat False """ return isinstance(other, GlobalOptions) and self.__getstate__() == other.__getstate__() diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 5573ff60834..3ccff8a6706 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -174,8 +174,8 @@ def indices(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules - sage: F.indices() # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules + sage: F.indices() # needs sage.modules {'a', 'b', 'c'} """ return self._indices @@ -186,14 +186,14 @@ def prefix(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules - sage: F.prefix() # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules + sage: F.prefix() # needs sage.modules 'B' :: - sage: X = SchubertPolynomialRing(QQ) # optional - sage.combinat - sage: X.prefix() # optional - sage.combinat + sage: X = SchubertPolynomialRing(QQ) # needs sage.combinat sage.modules + sage: X.prefix() # needs sage.combinat sage.modules 'X' """ return self._print_options['prefix'] @@ -229,16 +229,17 @@ def print_options(self, **kwds): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') # optional - sage.modules - sage: F.print_options() # optional - sage.modules + sage: # needs sage.modules + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') + sage: F.print_options() {...'prefix': 'x'...} - sage: F.print_options(bracket='(') # optional - sage.modules - sage: F.print_options() # optional - sage.modules + sage: F.print_options(bracket='(') + sage: F.print_options() {...'bracket': '('...} TESTS:: - sage: sorted(F.print_options().items()) # optional - sage.modules + sage: sorted(F.print_options().items()) # needs sage.modules [('bracket', '('), ('iterate_key', False), ('latex_bracket', False), ('latex_names', None), ('latex_prefix', None), ('latex_scalar_mult', None), @@ -247,7 +248,7 @@ def print_options(self, **kwds): ('sorting_key', at ...>), ('sorting_reverse', False), ('string_quotes', True), ('tensor_symbol', None)] - sage: F.print_options(bracket='[') # reset # optional - sage.modules + sage: F.print_options(bracket='[') # reset # needs sage.modules """ # don't just use kwds.get(...) because I want to distinguish # between an argument like "option=None" and the option not @@ -270,33 +271,35 @@ def _parse_names(self, m, use_latex): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', # needs sage.modules ....: latex_names='x,y,z') - sage: F._parse_names(1, False) # optional - sage.modules + sage: F._parse_names(1, False) # needs sage.modules 'a' - sage: F._parse_names(1, True) # optional - sage.modules + sage: F._parse_names(1, True) # needs sage.modules 'x' - sage: F.print_options(latex_names=None) # optional - sage.modules - sage: F._parse_names(1, True) # optional - sage.modules + sage: F.print_options(latex_names=None) # needs sage.modules + sage: F._parse_names(1, True) # needs sage.modules 'a' - sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) # optional - sage.modules - sage: F._parse_names(1, False) is None # optional - sage.modules + sage: # needs sage.modules + sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) + sage: F._parse_names(1, False) is None True - sage: F._parse_names(1, True) # optional - sage.modules + sage: F._parse_names(1, True) 'x' - sage: F._parse_names(3, True) is None # optional - sage.modules + sage: F._parse_names(3, True) is None True - sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) # optional - sage.modules - sage: F._parse_names(1, False) # optional - sage.modules + sage: # needs sage.modules + sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) + sage: F._parse_names(1, False) 'a' - sage: F._parse_names(1, True) # optional - sage.modules + sage: F._parse_names(1, True) 'a' - sage: F._parse_names(2, False) is None # optional - sage.modules + sage: F._parse_names(2, False) is None True - sage: F._parse_names(2, True) is None # optional - sage.modules + sage: F._parse_names(2, True) is None True """ names = self._print_options.get('names', None) @@ -349,69 +352,73 @@ def _repr_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules + sage: e = F.basis() # needs sage.modules + sage: e['a'] + 2*e['b'] # indirect doctest # needs sage.modules B['a'] + 2*B['b'] - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules + sage: # needs sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") + sage: e = F.basis() + sage: e['a'] + 2*e['b'] # indirect doctest F['a'] + 2*F['b'] - sage: F.print_options(string_quotes=False) # optional - sage.modules - sage: e['a'] + 2*e['b'] # optional - sage.modules + sage: F.print_options(string_quotes=False) + sage: e['a'] + 2*e['b'] F[a] + 2*F[b] - sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: F.print_options(iterate_key=True) # optional - sage.modules - sage: e['aa'] + 2*e['bb'] # optional - sage.modules + sage: # needs sage.modules + sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") + sage: e = F.basis() + sage: F.print_options(iterate_key=True) + sage: e['aa'] + 2*e['bb'] F['a', 'a'] + 2*F['b', 'b'] - sage: F.print_options(string_quotes=False) # optional - sage.modules - sage: e['aa'] + 2*e['bb'] # optional - sage.modules + sage: F.print_options(string_quotes=False) + sage: e['aa'] + 2*e['bb'] F[a, a] + 2*F[b, b] - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") # optional - sage.combinat sage.modules - sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules - sage: a # indirect doctest # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") + sage: original_print_options = QS3.print_options() + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) + sage: a # indirect doctest 2*[[1, 2, 3]] + 4*[[3, 2, 1]] - sage: QS3.print_options(bracket = False) # optional - sage.combinat sage.modules - sage: a # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(bracket = False) # needs sage.combinat sage.modules + sage: a # indirect doctest # needs sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(prefix='') # optional - sage.combinat sage.modules - sage: a # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(prefix='') # needs sage.combinat sage.modules + sage: a # indirect doctest # needs sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") # optional - sage.combinat sage.modules - sage: a # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") # needs sage.combinat sage.modules + sage: a # indirect doctest # needs sage.combinat sage.modules 2 *@* |[1, 2, 3]| + 4 *@* |[3, 2, 1]| - sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) # optional - sage.combinat sage.modules - sage: a # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) # needs sage.combinat sage.modules + sage: a # indirect doctest # needs sage.combinat sage.modules 2*|1, 2, 3| + 4*|3, 2, 1| - sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules + sage: QS3.print_options(**original_print_options) # reset # needs sage.combinat sage.modules TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) # needs sage.modules + sage: e = F.basis() # needs sage.modules + sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest # needs sage.modules B[('a', 'b')] + 2*B[('c', 'd')] - sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules - sage: a + 2*b # optional - sage.modules + sage: F. = CombinatorialFreeModule(QQ) # needs sage.modules + sage: a + 2*b # needs sage.modules a + 2*b - sage: F = CombinatorialFreeModule(QQ, ZZ) # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: 3*e[1] + 2*e[-2] # optional - sage.modules + sage: # needs sage.modules + sage: F = CombinatorialFreeModule(QQ, ZZ) + sage: e = F.basis() + sage: 3*e[1] + 2*e[-2] 2*B[-2] + 3*B[1] - sage: F.print_options(iterate_key=True) # optional - sage.modules - sage: 3*e[1] + 2*e[-2] # optional - sage.modules + sage: F.print_options(iterate_key=True) + sage: 3*e[1] + 2*e[-2] 2*B[-2] + 3*B[1] """ ret = self._parse_names(m, False) @@ -457,24 +464,25 @@ def _ascii_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat - sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat + sage: # needs sage.combinat sage.modules + sage: R = NonCommutativeSymmetricFunctions(QQ).R() + sage: ascii_art(R[1,2,2,4]) R **** ** ** * - sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat - sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat + sage: Partitions.options(diagram_str="#", convention="french") + sage: ascii_art(R[1,2,2,4]) R # ## ## #### - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options._reset() - sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules - sage: ascii_art(a + 2*b) # optional - sage.modules + sage: F. = CombinatorialFreeModule(QQ) # needs sage.modules + sage: ascii_art(a + 2*b) # needs sage.modules a + 2*b """ from sage.typeset.ascii_art import AsciiArt, ascii_art @@ -493,26 +501,27 @@ def _unicode_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat - sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat + sage: # needs sage.combinat + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # needs sage.modules + sage: unicode_art(R[1,2,2,4]) # needs sage.modules R ┌┬┬┬┐ ┌┼┼┴┴┘ ┌┼┼┘ ├┼┘ └┘ - sage: Partitions.options.convention="french" # optional - sage.combinat - sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat + sage: Partitions.options.convention="french" + sage: unicode_art(R[1,2,2,4]) # needs sage.modules R ┌┐ ├┼┐ └┼┼┐ └┼┼┬┬┐ └┴┴┴┘ - sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options._reset() - sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules - sage: unicode_art(a + 2*b) # optional - sage.modules + sage: F. = CombinatorialFreeModule(QQ) # needs sage.modules + sage: unicode_art(a + 2*b) # needs sage.modules a + 2*b """ from sage.typeset.unicode_art import UnicodeArt, unicode_art @@ -546,49 +555,51 @@ def _latex_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules + sage: e = F.basis() # needs sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules B_{a} + 2 B_{b} - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") # needs sage.modules + sage: e = F.basis() # needs sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules C_{a} + 2 C_{b} - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), ....: prefix="", scalar_mult="*") - sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules - sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules + sage: original_print_options = QS3.print_options() + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) + sage: latex(a) # indirect doctest 2 [1, 2, 3] + 4 [3, 2, 1] - sage: QS3.print_options(latex_bracket=True) # optional - sage.combinat sage.modules - sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(latex_bracket=True) + sage: latex(a) # indirect doctest 2 \left[ [1, 2, 3] \right] + 4 \left[ [3, 2, 1] \right] - sage: QS3.print_options(latex_bracket="(") # optional - sage.combinat sage.modules - sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules + sage: QS3.print_options(latex_bracket="(") + sage: latex(a) # indirect doctest 2 \left( [1, 2, 3] \right) + 4 \left( [3, 2, 1] \right) - sage: QS3.print_options(latex_bracket=('\\myleftbracket', # optional - sage.combinat sage.modules + sage: QS3.print_options(latex_bracket=('\\myleftbracket', ....: '\\myrightbracket')) - sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest 2 \myleftbracket [1, 2, 3] \myrightbracket + 4 \myleftbracket [3, 2, 1] \myrightbracket - sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules + sage: QS3.print_options(**original_print_options) # reset TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: latex(e[('a','b')]) # indirect doctest # optional - sage.modules + sage: # needs sage.modules + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) + sage: e = F.basis() + sage: latex(e[('a','b')]) # indirect doctest B_{('a', 'b')} - sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules + sage: latex(2*e[(0,1,2)]) # indirect doctest 2 B_{\left(0, 1, 2\right)} - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") # optional - sage.modules - sage: e = F.basis() # optional - sage.modules - sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") + sage: e = F.basis() + sage: latex(2*e[(0,1,2)]) # indirect doctest 2 \left(0, 1, 2\right) - sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') # optional - sage.modules - sage: latex(a + 2*b) # optional - sage.modules + sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') # needs sage.modules + sage: latex(a + 2*b) # needs sage.modules x + 2 y """ from sage.misc.latex import latex diff --git a/src/sage/structure/nonexact.py b/src/sage/structure/nonexact.py index fa5157b3a65..ffb39e5f579 100644 --- a/src/sage/structure/nonexact.py +++ b/src/sage/structure/nonexact.py @@ -9,7 +9,7 @@ sage: R. = PowerSeriesRing(QQ) sage: R.default_prec() 20 - sage: cos(x) # needs sage.symbolic + sage: cos(x) 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 - 1/3628800*x^10 + 1/479001600*x^12 - 1/87178291200*x^14 + 1/20922789888000*x^16 - 1/6402373705728000*x^18 + O(x^20) @@ -19,7 +19,7 @@ sage: R. = PowerSeriesRing(QQ, default_prec=10) sage: R.default_prec() 10 - sage: cos(x) # needs sage.symbolic + sage: cos(x) 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 + O(x^10) .. NOTE:: diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index cae49f53aa6..895f7ae386b 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -86,7 +86,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) # optional - sage.libs.pari + sage: gp(2) + gap(3) # needs sage.libs.gap sage.libs.pari 5 """ # **************************************************************************** @@ -376,7 +376,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Category of quotients of semigroups sage: first_class == Q.__class__ False - sage: TestSuite(Q).run() # optional - sage.libs.singular + sage: TestSuite(Q).run() # needs sage.libs.singular TESTS: @@ -590,8 +590,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: k = GF(5) # optional - sage.rings.finite_rings - sage: k._set_element_constructor() # optional - sage.rings.finite_rings + sage: k = GF(5) + sage: k._set_element_constructor() """ try: _element_constructor_ = self._element_constructor_ @@ -780,7 +780,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: loads(dumps(CDF['x'])) == CDF['x'] + sage: loads(dumps(CDF['x'])) == CDF['x'] # needs sage.rings.complex_double True """ CategoryObject.__setstate__(self, d) @@ -829,7 +829,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: ZZ._repr_option('ascii_art') False - sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') # optional - sage.modules + sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') # needs sage.modules True """ if not isinstance(key, str): @@ -915,36 +915,37 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: MS = MatrixSpace(QQ, 2, 2) # needs sage.modules This matrix space is in fact an algebra, and in particular it is a ring, from the point of view of categories:: - sage: MS.category() # optional - sage.modules + sage: MS.category() # needs sage.modules Category of infinite finite dimensional algebras with basis over (number fields and quotient fields and metric spaces) - sage: MS in Rings() # optional - sage.modules + sage: MS in Rings() # needs sage.modules True However, its class does not inherit from the base class ``Ring``:: - sage: isinstance(MS, Ring) # optional - sage.modules + sage: isinstance(MS, Ring) # needs sage.modules False Its ``_mul_`` method is inherited from the category, and can be used to create a left or right ideal:: - sage: MS._mul_.__module__ # optional - sage.modules + sage: # needs sage.modules + sage: MS._mul_.__module__ 'sage.categories.rings' - sage: MS * MS.1 # indirect doctest # optional - sage.modules + sage: MS * MS.1 # indirect doctest Left Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS * [MS.1, 2] # optional - sage.modules + sage: MS * [MS.1, 2] Left Ideal ( [0 1] @@ -954,14 +955,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): [0 2] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS.1 * MS # optional - sage.modules + sage: MS.1 * MS Right Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: [MS.1, 2] * MS # optional - sage.modules + sage: [MS.1, 2] * MS Right Ideal ( [0 1] @@ -1010,22 +1011,23 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: ZZ^3 # optional - sage.modules + sage: # needs sage.modules + sage: ZZ^3 Ambient free module of rank 3 over the principal ideal domain Integer Ring - sage: QQ^3 # optional - sage.modules + sage: QQ^3 Vector space of dimension 3 over Rational Field - sage: QQ['x']^3 # optional - sage.modules + sage: QQ['x']^3 Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: IntegerModRing(6)^3 # optional - sage.modules + sage: IntegerModRing(6)^3 Ambient free module of rank 3 over Ring of integers modulo 6 sage: 3^ZZ Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for ^: 'Integer Ring' and '' - sage: Partitions(3)^3 # optional - sage.combinat sage.modules + sage: Partitions(3)^3 # needs sage.combinat sage.modules Traceback (most recent call last): ... TypeError: unsupported operand type(s) for ** or pow(): 'Partitions_n_with_category' and 'int' @@ -1081,63 +1083,65 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: 5 in QQ True - sage: I in RR + sage: I in RR # needs sage.rings.real_mpfr sage.symbolic False - sage: SR(2) in ZZ # optional - sage.symbolic + sage: RIF(1, 2) in RIF # needs sage.rings.real_interval_field True - sage: RIF(1, 2) in RIF + + sage: # needs sage.symbolic + sage: SR(2) in ZZ True - sage: pi in RIF # there is no element of RIF equal to pi # optional - sage.symbolic + sage: pi in RIF # there is no element of RIF equal to pi False - sage: sqrt(2) in CC # optional - sage.symbolic + sage: sqrt(2) in CC True - sage: pi in RR # optional - sage.symbolic + sage: pi in RR True - sage: pi in CC # optional - sage.symbolic + sage: pi in CC True - sage: pi in RDF # optional - sage.symbolic + sage: pi in RDF True - sage: pi in CDF # optional - sage.symbolic + sage: pi in CDF True Note that we have :: - sage: 3/2 in RIF + sage: 3/2 in RIF # needs sage.rings.real_interval_field True because ``3/2`` has an exact representation in ``RIF`` (i.e. can be represented as an interval that contains exactly one value):: - sage: RIF(3/2).is_exact() + sage: RIF(3/2).is_exact() # needs sage.rings.real_interval_field True On the other hand, we have :: - sage: 2/3 in RIF + sage: 2/3 in RIF # needs sage.rings.real_interval_field False because ``2/3`` has no exact representation in ``RIF``. Since ``RIF(2/3)`` is a nontrivial interval, it cannot be equal to anything (not even itself):: - sage: RIF(2/3).is_exact() + sage: RIF(2/3).is_exact() # needs sage.rings.real_interval_field False - sage: RIF(2/3).endpoints() + sage: RIF(2/3).endpoints() # needs sage.rings.real_interval_field (0.666666666666666, 0.666666666666667) - sage: RIF(2/3) == RIF(2/3) + sage: RIF(2/3) == RIF(2/3) # needs sage.rings.real_interval_field False TESTS: Check that :trac:`13824` is fixed:: - sage: 4/3 in GF(3) # optional - sage.rings.finite_rings + sage: 4/3 in GF(3) False - sage: 15/50 in GF(25, 'a') # optional - sage.rings.finite_rings + sage: 15/50 in GF(25, 'a') # needs sage.rings.finite_rings False sage: 7/4 in Integers(4) False @@ -1154,9 +1158,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`24209` is fixed:: - sage: I in QQbar # optional - sage.rings.number_field + sage: I in QQbar # needs sage.rings.number_field True - sage: sqrt(-1) in QQbar # optional - sage.rings.number_field sage.symbolic + sage: sqrt(-1) in QQbar # needs sage.rings.number_field sage.symbolic True """ P = parent(x) @@ -1200,8 +1204,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): We make an exception for zero:: - sage: V = GF(7)^7 # optional - sage.modules sage.rings.finite_rings - sage: V.coerce(0) # optional - sage.modules sage.rings.finite_rings + sage: V = GF(7)^7 # needs sage.modules + sage: V.coerce(0) # needs sage.modules (0, 0, 0, 0, 0, 0, 0) """ cdef R = parent(x) @@ -1239,7 +1243,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: VectorSpace(GF(7), 3)[:10] # optional - sage.rings.finite_rings + sage: VectorSpace(GF(7), 3)[:10] # needs sage.modules [(0, 0, 0), (1, 0, 0), (2, 0, 0), @@ -1376,30 +1380,31 @@ cdef class Parent(sage.structure.category_object.CategoryObject): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([5], GF(7)) Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: f = R.hom([3], GF(49,'a')) # optional - sage.rings.finite_rings - sage: f # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(7)) + sage: f = R.hom([3], GF(49,'a')) + sage: f Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x + 6) # optional - sage.rings.finite_rings + sage: f(x + 6) 2 - sage: f(x^2 + 1) # optional - sage.rings.finite_rings + sage: f(x^2 + 1) 3 Natural morphism:: - sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings - sage: f(7) # optional - sage.rings.finite_rings + sage: f = ZZ.hom(GF(5)) + sage: f(7) 2 - sage: f # optional - sage.rings.finite_rings + sage: f Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -1683,31 +1688,34 @@ cdef class Parent(sage.structure.category_object.CategoryObject): ....: D[tuple(nk)] = v ....: return a.parent()(D) + sage: # needs sage.groups sage: R. = QQ['x, y, z'] - sage: G = SymmetricGroup(3) # optional - sage.groups - sage: act = SymmetricGroupAction(G, R) # optional - sage.groups + sage: G = SymmetricGroup(3) + sage: act = SymmetricGroupAction(G, R) sage: t = x + 2*y + 3*z - sage: act(G((1, 2)), t) # optional - sage.groups + sage: # needs sage.groups + sage: act(G((1, 2)), t) 2*x + y + 3*z - sage: act(G((2, 3)), t) # optional - sage.groups + sage: act(G((2, 3)), t) x + 3*y + 2*z - sage: act(G((1, 2, 3)), t) # optional - sage.groups + sage: act(G((1, 2, 3)), t) 3*x + y + 2*z This should fail, since we have not registered the left action:: - sage: G((1,2)) * t # optional - sage.groups + sage: G((1,2)) * t # needs sage.groups Traceback (most recent call last): ... TypeError: ... Now let's make it work:: - sage: R._unset_coercions_used() # optional - sage.groups - sage: R.register_action(act) # optional - sage.groups - sage: G((1, 2)) * t # optional - sage.groups + sage: # needs sage.groups + sage: R._unset_coercions_used() + sage: R.register_action(act) + sage: G((1, 2)) * t 2*x + y + 3*z """ if self._coercions_used: @@ -1768,35 +1776,36 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: S3 = AlternatingGroup(3) # optional - sage.groups - sage: G = SL(3, QQ) # optional - sage.groups - sage: p = S3[2]; p.matrix() # optional - sage.groups + sage: S3 = AlternatingGroup(3) # needs sage.groups + sage: G = SL(3, QQ) # needs sage.groups + sage: p = S3[2]; p.matrix() # needs sage.groups [0 0 1] [1 0 0] [0 1 0] In general one cannot mix matrices and permutations:: - sage: G(p) # optional - sage.groups + sage: # needs sage.groups + sage: G(p) Traceback (most recent call last): ... TypeError: unable to convert (1,3,2) to a rational - sage: phi = S3.hom(lambda p: G(p.matrix()), codomain=G) # optional - sage.groups - sage: phi(p) # optional - sage.groups + sage: phi = S3.hom(lambda p: G(p.matrix()), codomain=G) + sage: phi(p) [0 0 1] [1 0 0] [0 1 0] - sage: S3._unset_coercions_used() # optional - sage.groups - sage: S3.register_embedding(phi) # optional - sage.groups + sage: S3._unset_coercions_used() + sage: S3.register_embedding(phi) By :trac:`14711`, coerce maps should be copied when using outside of the coercion system:: - sage: phi = copy(S3.coerce_embedding()); phi # optional - sage.groups + sage: phi = copy(S3.coerce_embedding()); phi # needs sage.groups Generic morphism: From: Alternating group of order 3!/2 as a permutation group To: Special Linear Group of degree 3 over Rational Field - sage: phi(p) # optional - sage.groups + sage: phi(p) # needs sage.groups [0 0 1] [1 0 0] [0 1 0] @@ -1804,43 +1813,45 @@ cdef class Parent(sage.structure.category_object.CategoryObject): This does not work since matrix groups are still old-style parents (see :trac:`14014`):: - sage: G(p) # todo: not implemented # optional - sage.groups + sage: G(p) # not implemented # needs sage.groups Though one can have a permutation act on the rows of a matrix:: - sage: G(1) * p # optional - sage.groups + sage: G(1) * p # needs sage.groups [0 0 1] [1 0 0] [0 1 0] Some more advanced examples:: + sage: # needs sage.rings.number_field sage: x = QQ['x'].0 sage: t = abs(ZZ.random_element(10^6)) - sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) # optional - sage.rings.number_field - sage: a = K.gen() # optional - sage.rings.number_field - sage: K_into_MS = K.hom([a.matrix()]) # optional - sage.rings.number_field - sage: K._unset_coercions_used() # optional - sage.rings.number_field - sage: K.register_embedding(K_into_MS) # optional - sage.rings.number_field + sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) + sage: a = K.gen() + sage: K_into_MS = K.hom([a.matrix()]) + sage: K._unset_coercions_used() + sage: K.register_embedding(K_into_MS) - sage: L = NumberField(x^2 + 2*3*7*11*19*31, # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: L = NumberField(x^2 + 2*3*7*11*19*31, ....: "b" + str(abs(ZZ.random_element(10^6)))) - sage: b = L.gen() # optional - sage.rings.number_field - sage: L_into_MS = L.hom([b.matrix()]) # optional - sage.rings.number_field - sage: L._unset_coercions_used() # optional - sage.rings.number_field - sage: L.register_embedding(L_into_MS) # optional - sage.rings.number_field + sage: b = L.gen() + sage: L_into_MS = L.hom([b.matrix()]) + sage: L._unset_coercions_used() + sage: L.register_embedding(L_into_MS) - sage: K.coerce_embedding()(a) # optional - sage.rings.number_field + sage: K.coerce_embedding()(a) # needs sage.rings.number_field [ 0 1] [-462 0] - sage: L.coerce_embedding()(b) # optional - sage.rings.number_field + sage: L.coerce_embedding()(b) # needs sage.rings.number_field [ 0 1] [-272118 0] - sage: a.matrix() * b.matrix() # optional - sage.rings.number_field + sage: a.matrix() * b.matrix() # needs sage.rings.number_field [-272118 0] [ 0 -462] - sage: a.matrix() * b.matrix() # optional - sage.rings.number_field + sage: a.matrix() * b.matrix() # needs sage.rings.number_field [-272118 0] [ 0 -462] """ @@ -1869,16 +1880,17 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 + x^2 + 1, embedding=1) # optional - sage.rings.number_field - sage: K.coerce_embedding() # optional - sage.rings.number_field + sage: K. = NumberField(x^3 + x^2 + 1, embedding=1) + sage: K.coerce_embedding() Generic morphism: From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = -1.465571231876768? To: Real Lazy Field Defn: a -> -1.465571231876768? - sage: K. = NumberField(x^3 + x^2 + 1, embedding=CC.gen()) # optional - sage.rings.number_field - sage: K.coerce_embedding() # optional - sage.rings.number_field + sage: K. = NumberField(x^3 + x^2 + 1, embedding=CC.gen()) + sage: K.coerce_embedding() Generic morphism: From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = 0.2327856159383841? + 0.7925519925154479?*I @@ -1932,11 +1944,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: QQ['x']._generic_convert_map(SR) # optional - sage.symbolic + sage: QQ['x']._generic_convert_map(SR) # needs sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in x over Rational Field - sage: GF(11)._generic_convert_map(GF(7)) # optional - sage.rings.finite_rings + sage: GF(11)._generic_convert_map(GF(7)) Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 @@ -2014,7 +2026,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): By :trac:`14711`, coerce maps should be copied for usage outside of the coercion system:: - sage: copy(CDF._coerce_map_via([ZZ, RR, CC], int)) + sage: copy(CDF._coerce_map_via([ZZ, RR, CC], int)) # needs sage.rings.complex_double Composite map: From: Set of Python objects of class 'int' To: Complex Double Field @@ -2026,7 +2038,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): From: Integer Ring To: Complex Double Field - sage: copy(CDF._coerce_map_via([ZZ, RR, CC], QQ)) + sage: copy(CDF._coerce_map_via([ZZ, RR, CC], QQ)) # needs sage.rings.complex_double Composite map: From: Rational Field To: Complex Double Field @@ -2038,7 +2050,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): From: Real Field with 53 bits of precision To: Complex Double Field - sage: copy(CDF._coerce_map_via([ZZ, RR, CC], CC)) + sage: copy(CDF._coerce_map_via([ZZ, RR, CC], CC)) # needs sage.rings.complex_double Generic map: From: Complex Field with 53 bits of precision To: Complex Double Field @@ -2108,26 +2120,27 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: import gc sage: _ = gc.collect() - sage: K = GF(1<<55,'t') # optional - sage.rings.finite_rings - sage: for i in range(50): # optional - sage.rings.finite_rings sage.schemes + sage: K = GF(1<<55,'t') # needs sage.rings.finite_rings + sage: for i in range(50): # needs sage.rings.finite_rings sage.schemes ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: b = K.has_coerce_map_from(E) sage: _ = gc.collect() - sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # optional - sage.rings.finite_rings sage.schemes + sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # needs sage.rings.finite_rings sage.schemes 1 TESTS: The following was fixed in :trac:`12969`:: + sage: # needs sage.combinat sage.modules sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat sage.modules - sage: H = Sym.macdonald().H() # optional - sage.combinat sage.modules - sage: P = Sym.macdonald().P() # optional - sage.combinat sage.modules - sage: m = Sym.monomial() # optional - sage.combinat sage.modules - sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat sage.modules - sage: phi = m.coerce_map_from(P) # optional - sage.combinat sage.modules + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) + sage: H = Sym.macdonald().H() + sage: P = Sym.macdonald().P() + sage: m = Sym.monomial() + sage: Ht = Sym.macdonald().Ht() + sage: phi = m.coerce_map_from(P) """ return copy(self._internal_coerce_map_from(S)) @@ -2157,16 +2170,17 @@ cdef class Parent(sage.structure.category_object.CategoryObject): From: Integer Ring To: Rational Field + sage: # needs sage.combinat sage.modules sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat - sage: P = Sym.macdonald().P() # optional - sage.combinat - sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat - sage: Ht._internal_coerce_map_from(P) # optional - sage.combinat + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) + sage: P = Sym.macdonald().P() + sage: Ht = Sym.macdonald().Ht() + sage: Ht._internal_coerce_map_from(P) (map internal to coercion system -- copy before use) Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis - sage: copy(Ht._internal_coerce_map_from(P)) # optional - sage.combinat + sage: copy(Ht._internal_coerce_map_from(P)) Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis @@ -2184,8 +2198,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`4740`:: - sage: F = GF(13) # optional - sage.rings.finite_rings - sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) # optional - sage.rings.finite_rings + sage: F = GF(13) + sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) True """ if not good_as_coerce_domain(S): @@ -2295,19 +2309,20 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Another test:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K = NumberField([x^2 - 2, x^2 - 3], 'a,b') # optional - sage.rings.number_field - sage: M = K.absolute_field('c') # optional - sage.rings.number_field - sage: M_to_K, K_to_M = M.structure() # optional - sage.rings.number_field - sage: M.register_coercion(K_to_M) # optional - sage.rings.number_field - sage: K.register_coercion(M_to_K) # optional - sage.rings.number_field - sage: phi = M.coerce_map_from(QQ) # optional - sage.rings.number_field - sage: p = QQ.random_element() # optional - sage.rings.number_field - sage: c = phi(p) - p; c # optional - sage.rings.number_field + sage: K = NumberField([x^2 - 2, x^2 - 3], 'a,b') + sage: M = K.absolute_field('c') + sage: M_to_K, K_to_M = M.structure() + sage: M.register_coercion(K_to_M) + sage: K.register_coercion(M_to_K) + sage: phi = M.coerce_map_from(QQ) + sage: p = QQ.random_element() + sage: c = phi(p) - p; c 0 - sage: c.parent() is M # optional - sage.rings.number_field + sage: c.parent() is M True - sage: K.coerce_map_from(QQ) # optional - sage.rings.number_field + sage: K.coerce_map_from(QQ) Coercion map: From: Rational Field To: Number Field in a with defining polynomial x^2 - 2 over its base field @@ -2329,14 +2344,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`14982` is fixed, and more generally that we discover sensible coercion paths in the presence of embeddings:: - sage: K. = NumberField(x^2 + 1/2, embedding=CC(0, 1)) # optional - sage.rings.number_field - sage: L = NumberField(x^2 + 2, 'b', embedding=1/a) # optional - sage.rings.number_field - sage: PolynomialRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 + 1/2, embedding=CC(0, 1)) + sage: L = NumberField(x^2 + 2, 'b', embedding=1/a) + sage: PolynomialRing(L, 'x').coerce_map_from(L) Polynomial base injection morphism: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PolynomialRing(K, 'x').coerce_map_from(L) # optional - sage.rings.number_field + sage: PolynomialRing(K, 'x').coerce_map_from(L) Composite map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Univariate Polynomial Ring in x over Number Field in a @@ -2350,12 +2366,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): From: Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I To: Univariate Polynomial Ring in x over Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I - sage: MatrixSpace(L, 2, 2).coerce_map_from(L) # optional - sage.rings.number_field + sage: MatrixSpace(L, 2, 2).coerce_map_from(L) Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Full MatrixSpace of 2 by 2 dense matrices over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PowerSeriesRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field + sage: PowerSeriesRing(L, 'x').coerce_map_from(L) Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Power Series Ring in x over Number Field in b @@ -2555,14 +2571,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: M = QQ['y']^3 # optional - sage.modules - sage: M.get_action(ZZ['x']['y']) # optional - sage.modules + sage: M = QQ['y']^3 # needs sage.modules + sage: M.get_action(ZZ['x']['y']) # needs sage.modules Right scalar multiplication by Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring on Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field - sage: print(M.get_action(ZZ['x'])) # optional - sage.modules + sage: print(M.get_action(ZZ['x'])) # needs sage.modules None """ action = self._get_action_(S, op, self_on_left) @@ -2581,22 +2597,24 @@ cdef class Parent(sage.structure.category_object.CategoryObject): """ TESTS:: - sage: E = EllipticCurve([1,0]) # optional - sage.schemes - sage: coercion_model.get_action(E, ZZ, operator.mul) # optional - sage.schemes + sage: # needs sage.schemes + sage: E = EllipticCurve([1,0]) + sage: coercion_model.get_action(E, ZZ, operator.mul) Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(ZZ, E, operator.mul) # optional - sage.schemes + sage: coercion_model.get_action(ZZ, E, operator.mul) Left Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(E, int, operator.mul) # optional - sage.schemes + sage: coercion_model.get_action(E, int, operator.mul) Right Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(int, E, operator.mul) # optional - sage.schemes + sage: coercion_model.get_action(int, E, operator.mul) Left Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field :: + sage: # needs sage.rings.complex_double sage: R. = CDF[] sage: coercion_model.get_action(R, ZZ, operator.pow) Right Integer Powering by Integer Ring @@ -2614,7 +2632,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): :: - sage: print(coercion_model.get_action(E, ZZ, operator.pow)) # optional - sage.schemes + sage: print(coercion_model.get_action(E, ZZ, operator.pow)) # needs sage.schemes None """ # G acts on S, G -> G', R -> S => G' acts on R (?) @@ -2710,7 +2728,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: CDF.an_element() + sage: CDF.an_element() # needs sage.rings.complex_double 1.0*I sage: ZZ[['t']].an_element() t @@ -2817,9 +2835,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: ZZ.is_exact() True - sage: Qp(7).is_exact() # optional - sage.rings.padics + sage: Qp(7).is_exact() # needs sage.rings.padics False - sage: Zp(7, type='capped-abs').is_exact() # optional - sage.rings.padics + sage: Zp(7, type='capped-abs').is_exact() # needs sage.rings.padics False """ return True @@ -2832,17 +2850,19 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: QuadraticField(-1)._is_numerical() # optional - sage.rings.number_field + sage: QuadraticField(-1)._is_numerical() # needs sage.rings.number_field + True + sage: QQ._is_numerical() True - sage: [R._is_numerical() for R in [RR, CC, QQ]] - [True, True, True] - sage: SR._is_numerical() # optional - sage.symbolic + sage: [RR._is_numerical(), CC._is_numerical()] # needs sage.rings.real_mpfr + [True, True] + sage: SR._is_numerical() # needs sage.symbolic False sage: [R._is_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_numerical() for R in [RBF, CBF]] # optional - sage.libs.flint + sage: [R._is_numerical() for R in [RBF, CBF]] # needs sage.libs.flint [False, False] - sage: [R._is_numerical() for R in [RIF, CIF]] + sage: [R._is_numerical() for R in [RIF, CIF]] # needs sage.rings.real_interval_field [False, False] """ try: @@ -2853,8 +2873,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): else: return ComplexField(mpfr_prec_min()).has_coerce_map_from(self) - from sage.rings.real_double import CDF - return CDF.has_coerce_map_from(self) + try: + from sage.rings.complex_double import CDF + except ImportError: + pass + else: + return CDF.has_coerce_map_from(self) + + from sage.rings.real_double import RDF + return RDF.has_coerce_map_from(self) @cached_method def _is_real_numerical(self): @@ -2864,21 +2891,23 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: QuadraticField(2)._is_real_numerical() # optional - sage.rings.number_field + sage: QuadraticField(2)._is_real_numerical() # needs sage.rings.number_field True - sage: [R._is_real_numerical() for R in [RR, QQ, ZZ, RLF]] - [True, True, True, True] - sage: QuadraticField(-1)._is_real_numerical() # optional - sage.rings.number_field + sage: [QQ._is_real_numerical(), ZZ._is_real_numerical()] + [True, True] + sage: [RR._is_real_numerical(), RLF._is_real_numerical()] # needs sage.rings.real_mpfr + [True, True] + sage: QuadraticField(-1)._is_real_numerical() # needs sage.rings.number_field False - sage: CC._is_real_numerical() + sage: CC._is_real_numerical() # needs sage.rings.real_mpfr False - sage: SR._is_real_numerical() # optional - sage.symbolic + sage: SR._is_real_numerical() # needs sage.symbolic False sage: [R._is_real_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_real_numerical() for R in [RBF, CBF]] # optional - sage.libs.flint + sage: [R._is_real_numerical() for R in [RBF, CBF]] # needs sage.libs.flint [False, False] - sage: [R._is_real_numerical() for R in [RIF, CIF]] # optional - sage.libs.flint + sage: [R._is_real_numerical() for R in [RIF, CIF]] # needs sage.libs.flint [False, False] """ try: @@ -2925,7 +2954,7 @@ cdef class Set_generic(Parent): sage: bool(Set(QQ)) True - sage: bool(Set(GF(3))) # optional - sage.rings.finite_rings + sage: bool(Set(GF(3))) True """ return not (self.is_finite() and len(self) == 0) @@ -2966,9 +2995,9 @@ cdef class EltPair: Verify that :trac:`16341` has been resolved:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: E = EllipticCurve_from_j(0).base_extend(K) # optional - sage.rings.padics - sage: E.get_action(ZZ) # optional - sage.rings.padics + sage: K. = Qq(9) # needs sage.rings.padics + sage: E = EllipticCurve_from_j(0).base_extend(K) # needs sage.rings.padics + sage: E.get_action(ZZ) # needs sage.rings.padics Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 diff --git a/src/sage/structure/parent_gens.pyx b/src/sage/structure/parent_gens.pyx index 43540c75254..ab531314458 100644 --- a/src/sage/structure/parent_gens.pyx +++ b/src/sage/structure/parent_gens.pyx @@ -47,14 +47,15 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) # optional - sage.modules - sage: M # optional - sage.modules + sage: # needs sage.modules + sage: M = FreeModule(ZZ, 4) + sage: M Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() # optional - sage.modules + sage: M.ngens() 4 - sage: M.gen(0) # optional - sage.modules + sage: M.gen(0) (1, 0, 0, 0) - sage: M.gens() # optional - sage.modules + sage: M.gens() ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -240,31 +241,33 @@ cdef class ParentWithGens(ParentWithBase): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([5], GF(7)) Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: f = R.hom([3], GF(49, 'a')) # optional - sage.rings.finite_rings - sage: f # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(7)) + sage: f = R.hom([3], GF(49, 'a')) + sage: f Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x + 6) # optional - sage.rings.finite_rings + sage: f(x + 6) 2 - sage: f(x^2 + 1) # optional - sage.rings.finite_rings + sage: f(x^2 + 1) 3 EXAMPLES: Natural morphism :: - sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings - sage: f(7) # optional - sage.rings.finite_rings + sage: f = ZZ.hom(GF(5)) + sage: f(7) 2 - sage: f # optional - sage.rings.finite_rings + sage: f Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -280,15 +283,17 @@ cdef class ParentWithGens(ParentWithBase): You can specify a map on the base ring:: - sage: k = GF(2) # optional - sage.rings.finite_rings - sage: R. = k[] # optional - sage.rings.finite_rings - sage: l. = k.extension(a^3 + a^2 + 1) # optional - sage.rings.finite_rings - sage: R. = l[] # optional - sage.rings.finite_rings - sage: m. = l.extension(b^2 + b + a) # optional - sage.rings.finite_rings - sage: n. = GF(2^6) # optional - sage.rings.finite_rings - sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k = GF(2) + sage: R. = k[] + sage: l. = k.extension(a^3 + a^2 + 1) + sage: R. = l[] + sage: m. = l.extension(b^2 + b + a) + sage: n. = GF(2^6) + sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) Ring morphism: - From: Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^3 with modulus b^2 + b + a + From: Univariate Quotient Polynomial Ring in b over + Finite Field in a of size 2^3 with modulus b^2 + b + a To: Finite Field in z of size 2^6 Defn: b |--> z^4 + z^3 + 1 with map of base ring diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index adb70af2b98..549afae6242 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -13,7 +13,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) # optional - sage.libs.gap sage.libs.pari + sage: gp(2) + gap(3) # needs sage.libs.gap sage.libs.pari 5 """ @@ -46,19 +46,22 @@ cdef class Parent(parent.Parent): TESTS:: - sage: V = VectorSpace(GF(2,'a'), 2) # optional - sage.modules sage.rings.finite_rings - sage: V.list() # optional - sage.modules sage.rings.finite_rings + sage: # needs sage.modules + sage: V = VectorSpace(GF(2,'a'), 2) + sage: V.list() [(0, 0), (1, 0), (0, 1), (1, 1)] - sage: MatrixSpace(GF(3), 1, 1).list() # optional - sage.modules sage.rings.finite_rings + sage: MatrixSpace(GF(3), 1, 1).list() [[0], [1], [2]] - sage: DirichletGroup(3).list() # optional - sage.groups + sage: DirichletGroup(3).list() # needs sage.modular [Dirichlet character modulo 3 of conductor 1 mapping 2 |--> 1, Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] - sage: K = GF(7^6,'a') # optional - sage.rings.finite_rings - sage: K.list()[:10] # long time # optional - sage.rings.finite_rings + + sage: # needs sage.rings.finite_rings + sage: K = GF(7^6,'a') + sage: K.list()[:10] # long time [0, 1, 2, 3, 4, 5, 6, a, a + 1, a + 2] - sage: K. = GF(4) # optional - sage.rings.finite_rings - sage: K.list() # optional - sage.rings.finite_rings + sage: K. = GF(4) + sage: K.list() [0, a, a + 1, 1] """ diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index b232225da33..49d4ecebe5a 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -201,7 +201,7 @@ class WithProof(): This would hang "forever" if attempted with ``proof=True``:: sage: proof.arithmetic(True) - sage: with proof.WithProof('arithmetic', False): # optional - sage.libs.pari + sage: with proof.WithProof('arithmetic', False): # needs sage.libs.pari ....: print((10^1000 + 453).is_prime()) ....: print(1/0) Traceback (most recent call last): diff --git a/src/sage/structure/richcmp.pxd b/src/sage/structure/richcmp.pxd index 61c0a3c4321..493af157a79 100644 --- a/src/sage/structure/richcmp.pxd +++ b/src/sage/structure/richcmp.pxd @@ -20,7 +20,7 @@ cpdef inline richcmp(x, y, int op): sage: from sage.structure.richcmp import * sage: richcmp(3, 4, op_LT) True - sage: richcmp(x, x^2, op_EQ) # optional - sage.symbolic + sage: richcmp(x, x^2, op_EQ) # needs sage.symbolic x == x^2 The two examples above are completely equivalent to ``3 < 4`` diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index dd98ea5988d..e3f636512be 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -95,9 +95,9 @@ cdef class SageObject: Real numbers are not Python classes, so rename is not supported:: sage: a = 3.14 - sage: type(a) + sage: type(a) # needs sage.rings.real_mpfr <... 'sage.rings.real_mpfr.RealLiteral'> - sage: a.rename('pi') + sage: a.rename('pi') # needs sage.rings.real_mpfr Traceback (most recent call last): ... NotImplementedError: object does not support renaming: 3.14000000000000 @@ -212,9 +212,9 @@ cdef class SageObject: You can use the :func:`~sage.typeset.ascii_art.ascii_art` function to get the ASCII art representation of any object in Sage:: - sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) + sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) # needs sage.symbolic ... - sage: result + sage: result # needs sage.symbolic / | | 2 @@ -228,6 +228,7 @@ cdef class SageObject: Alternatively, you can use the ``%display ascii_art/simple`` magic to switch all output to ASCII art and back:: + sage: # needs sage.combinat sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('tab = StandardTableaux(3)[2]; tab') @@ -277,7 +278,7 @@ cdef class SageObject: You can use the :func:`~sage.typeset.unicode_art.unicode_art` function to get the ASCII art representation of any object in Sage:: - sage: unicode_art(integral(exp(x+x^2)/(x+1), x)) + sage: unicode_art(integral(exp(x+x^2)/(x+1), x)) # needs sage.symbolic ⌠ ⎮ 2 ⎮ x + x @@ -290,6 +291,7 @@ cdef class SageObject: Alternatively, you can use the ``%display ascii_art/simple`` magic to switch all output to ASCII art and back:: + sage: # needs sage.combinat sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('tab = StandardTableaux(3)[2]; tab') @@ -318,6 +320,7 @@ cdef class SageObject: Check that breakpoints and baseline are preserved (:trac:`29202`):: + sage: # needs sage.groups sage: F = FreeAbelianMonoid(index_set=ZZ) sage: f = prod(F.gen(i) for i in range(5)) sage: s, t = ascii_art(f), unicode_art(f) @@ -355,18 +358,19 @@ cdef class SageObject: modified to return ``True`` for objects which might behave differently in some computations:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: b = a + O(3) # optional - sage.rings.padics - sage: c = a + 3 # optional - sage.rings.padics - sage: b # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K. = Qq(9) + sage: b = a + O(3) + sage: c = a + 3 + sage: b a + O(3) - sage: c # optional - sage.rings.padics + sage: c a + 3 + O(3^20) - sage: b == c # optional - sage.rings.padics + sage: b == c True - sage: b == a # optional - sage.rings.padics + sage: b == a True - sage: c == a # optional - sage.rings.padics + sage: c == a False If such objects defined a non-trivial hash function, this would break @@ -374,20 +378,20 @@ cdef class SageObject: caches. This can be achieved by defining an appropriate ``_cache_key``:: - sage: hash(b) # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: hash(b) Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' sage: @cached_method ....: def f(x): return x==a - sage: f(b) # optional - sage.rings.padics + sage: f(b) True - sage: f(c) # if b and c were hashable, this would return True # optional - sage.rings.padics + sage: f(c) # if b and c were hashable, this would return True False - - sage: b._cache_key() # optional - sage.rings.padics + sage: b._cache_key() (..., ((0, 1),), 0, 1) - sage: c._cache_key() # optional - sage.rings.padics + sage: c._cache_key() (..., ((0, 1), (1,)), 0, 20) An implementation must make sure that for elements ``a`` and ``b``, @@ -395,9 +399,9 @@ cdef class SageObject: In practice this means that the ``_cache_key`` should always include the parent as its first argument:: - sage: S. = Qq(4) # optional - sage.rings.padics - sage: d = a + O(2) # optional - sage.rings.padics - sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # optional - sage.rings.padics + sage: S. = Qq(4) # needs sage.rings.padics + sage: d = a + O(2) # needs sage.rings.padics + sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # needs sage.rings.padics False """ @@ -418,10 +422,11 @@ cdef class SageObject: EXAMPLES:: - sage: x = SR.var("x") # optional - sage.symbolic - sage: f = x^3 + 5 # optional - sage.symbolic - sage: from tempfile import NamedTemporaryFile # optional - sage.symbolic - sage: with NamedTemporaryFile(suffix=".sobj") as t: # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x = SR.var("x") + sage: f = x^3 + 5 + sage: from tempfile import NamedTemporaryFile + sage: with NamedTemporaryFile(suffix=".sobj") as t: ....: f.save(t.name) ....: load(t.name) x^3 + 5 @@ -520,10 +525,10 @@ cdef class SageObject: EXAMPLES:: - sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # optional - sage.symbolic + sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # needs sage.symbolic log(sqrt(2) + 1) + log(sqrt(2) - 1) - sage: u = t.maxima_methods() # optional - sage.symbolic - sage: u.parent() # optional - sage.symbolic + sage: u = t.maxima_methods() # needs sage.symbolic + sage: u.parent() # needs sage.symbolic """ return type(self) @@ -826,26 +831,28 @@ cdef class SageObject: Some other examples that illustrate conversion to Magma. :: + sage: # optional - magma, needs sage.symbolic sage: n = -3/7 sage: m2 = Magma() - sage: magma(n) # optional - magma + sage: magma(n) -3/7 - sage: magma(n).parent() # optional - magma + sage: magma(n).parent() Magma - sage: magma(n).parent() is m2 # optional - magma + sage: magma(n).parent() is m2 False - sage: magma(n).parent() is magma # optional - magma + sage: magma(n).parent() is magma True This example illustrates caching, which happens automatically since K is a Python object:: + sage: # optional - magma, needs sage.symbolic sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 + 2) - sage: magma(K) is magma(K) # optional - magma + sage: K. = NumberField(x^3 + 2) # needs sage.rings.number_field + sage: magma(K) is magma(K) True sage: magma2 = Magma() - sage: magma(K) is magma2(K) # optional - magma + sage: magma(K) is magma2(K) False """ return repr(self) # default @@ -925,7 +932,7 @@ cdef class SageObject: EXAMPLES:: - sage: a = 2/3 # optional - rpy2 + sage: a = 2/3 sage: a._r_init_() # optional - rpy2 '2/3' """ diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 1286d6a1114..7a8c77ad1cf 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -45,8 +45,8 @@ special parent. This is what should happen, e.g., with finite field elements of different characteristics:: - sage: v = Sequence([GF(3)(1), GF(7)(1)]) # optional - sage.rings.finite_rings - sage: v.universe() # optional - sage.rings.finite_rings + sage: v = Sequence([GF(3)(1), GF(7)(1)]) + sage: v.universe() Category of objects You can make a list immutable with ``v.freeze()``. Assignment is @@ -201,9 +201,9 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non This example illustrates how every element of a list is taken into account when constructing a sequence.:: - sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v [1, 2, 1, 3] - sage: v.universe() # optional - sage.rings.finite_rings + sage: v.universe() Finite Field of size 5 TESTS:: @@ -397,9 +397,9 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): :: - sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v [1, 2, 1, 3] - sage: v.universe() # optional - sage.rings.finite_rings + sage: v.universe() Finite Field of size 5 """ @@ -674,11 +674,11 @@ def _latex_(self): r""" TESTS:: - sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t # optional - sage.symbolic + sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t # needs sage.symbolic [sqrt(x), e^x, x^(x - 1)] - sage: t._latex_() # optional - sage.symbolic + sage: t._latex_() # needs sage.symbolic '\\left[\\sqrt{x}, e^{x}, x^{x - 1}\\right]' - sage: latex(t) # optional - sage.symbolic + sage: latex(t) # needs sage.symbolic \left[\sqrt{x}, e^{x}, x^{x - 1}\right] """ from sage.misc.latex import list_function as list_latex_function diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index c6ffa9cb739..3bbea183fc6 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -21,13 +21,13 @@ instances constructed with the same arguments share the same memory representation. For example, calling twice:: - sage: G = SymmetricGroup(6) # optional - sage.groups - sage: H = SymmetricGroup(6) # optional - sage.groups + sage: G = SymmetricGroup(6) # needs sage.groups + sage: H = SymmetricGroup(6) # needs sage.groups to create the symmetric group on six elements gives back the same object:: - sage: G is H # optional - sage.groups + sage: G is H # needs sage.groups True This is a standard design pattern. Besides saving memory, it allows for @@ -100,9 +100,9 @@ class will by default also be used as keys for the cache:: since ``C(1)`` already is in the cache, and since the unit elements in different finite fields are all equal to the integer one, we find:: - sage: GF(5)(1) == 1 == GF(3)(1) # optional - sage.rings.finite_rings + sage: GF(5)(1) == 1 == GF(3)(1) True - sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) # optional - sage.rings.finite_rings + sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) True But ``C(2)`` is not in the cache, and the number two is not equal in different @@ -112,9 +112,9 @@ class will by default also be used as keys for the cache:: when comparing elements of *distinct* algebraic structures!!). Hence, we have:: - sage: GF(5)(2) == GF(3)(2) # optional - sage.rings.finite_rings + sage: GF(5)(2) == GF(3)(2) False - sage: C(GF(3)(2)) is C(GF(5)(2)) # optional - sage.rings.finite_rings + sage: C(GF(3)(2)) is C(GF(5)(2)) False Normalising the arguments @@ -424,10 +424,10 @@ class is directly created, then the cache is not used:: Using :class:`CachedRepresentation` has the advantage that one has a class and creates cached instances of this class by the usual Python syntax:: - sage: G = SymmetricGroup(6) # optional - sage.groups - sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) # optional - sage.groups + sage: G = SymmetricGroup(6) # needs sage.groups + sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) # needs sage.groups True - sage: isinstance(G, SymmetricGroup) # optional - sage.groups + sage: isinstance(G, SymmetricGroup) # needs sage.groups True In contrast, a factory is just a callable object that returns something that @@ -436,14 +436,16 @@ class is directly created, then the cache is not used:: sage: isinstance(GF, sage.structure.factory.UniqueFactory) True - sage: K5 = GF(5) # optional - sage.rings.finite_rings - sage: type(K5) # optional - sage.rings.finite_rings + sage: K5 = GF(5) + sage: type(K5) - sage: K25 = GF(25, 'x') # optional - sage.rings.finite_rings - sage: type(K25) # optional - sage.rings.finite_rings + + sage: # needs sage.rings.finite_rings + sage: K25 = GF(25, 'x') + sage: type(K25) # needs sage.libs.linbox - sage: Kp = GF(next_prime_power(1000000)^2, 'x') # optional - sage.rings.finite_rings - sage: type(Kp) # optional - sage.rings.finite_rings + sage: Kp = GF(next_prime_power(1000000)^2, 'x') + sage: type(Kp) This can be confusing to the user. Namely, the user might determine the class @@ -498,13 +500,14 @@ class :class:`~sage.misc.fast_methods.WithEqualityById`, which provides since they are equal to groups created in a totally different way, namely to subgroups:: - sage: G = SymmetricGroup(6) # optional - sage.groups - sage: G3 = G.subgroup([G((1,2,3,4,5,6)), G((1,2))]) # optional - sage.groups - sage: G is G3 # optional - sage.groups + sage: # needs sage.groups + sage: G = SymmetricGroup(6) + sage: G3 = G.subgroup([G((1,2,3,4,5,6)), G((1,2))]) + sage: G is G3 False - sage: type(G) == type(G3) # optional - sage.groups + sage: type(G) == type(G3) False - sage: G == G3 # optional - sage.groups + sage: G == G3 True The unique representation behaviour can conveniently be implemented with a @@ -517,9 +520,9 @@ class that inherits from :class:`UniqueRepresentation`: By adding ring. Thus, it is reasonable to use :class:`UniqueRepresentation` in this case:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # needs sage.combinat True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # needs sage.combinat True :class:`UniqueRepresentation` differs from :class:`CachedRepresentation` only @@ -1188,15 +1191,15 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): the same memory representation), if and only if they were created using equal arguments. For example, calling twice:: - sage: f = SymmetricFunctions(QQ) # optional - sage.combinat sage.modules - sage: g = SymmetricFunctions(QQ) # optional - sage.combinat sage.modules + sage: f = SymmetricFunctions(QQ) # needs sage.combinat sage.modules + sage: g = SymmetricFunctions(QQ) # needs sage.combinat sage.modules to create the symmetric function algebra over `\QQ` actually gives back the same object:: - sage: f == g # optional - sage.combinat sage.modules + sage: f == g # needs sage.combinat sage.modules True - sage: f is g # optional - sage.combinat sage.modules + sage: f is g # needs sage.combinat sage.modules True This is a standard design pattern. It allows for sharing cached data (say @@ -1211,19 +1214,19 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): derive from it, or make sure some of its super classes does. Also, it groups together the class and the factory in a single gadget:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat sage.modules + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # needs sage.combinat sage.modules True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat sage.modules + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # needs sage.combinat sage.modules True This nice behaviour is not available when one just uses a factory:: - sage: isinstance(GF(7), GF) # optional - sage.rings.finite_rings + sage: isinstance(GF(7), GF) Traceback (most recent call last): ... TypeError: isinstance() arg 2 must be a type... - sage: isinstance(GF, sage.structure.factory.UniqueFactory) # optional - sage.rings.finite_rings + sage: isinstance(GF, sage.structure.factory.UniqueFactory) True In addition, :class:`~sage.structure.factory.UniqueFactory` only provides