diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index 691486e03d4..ccfda512014 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -971,8 +971,8 @@ def extra_super_categories(self): [Category of unital magmas] sage: C.super_categories() - [Category of unital algebras with basis over Rational Field, - Category of additive magma algebras over Rational Field] + [Category of additive magma algebras over Rational Field, + Category of unital algebras with basis over Rational Field] """ from sage.categories.magmas import Magmas return [Magmas().Unital()] diff --git a/src/sage/categories/algebra_functor.py b/src/sage/categories/algebra_functor.py index 0d6cb19b0e1..ae5ef793296 100644 --- a/src/sage/categories/algebra_functor.py +++ b/src/sage/categories/algebra_functor.py @@ -128,7 +128,6 @@ Category of semigroup algebras over Rational Field, ... Category of unital magma algebras over Rational Field, - ... Category of magma algebras over Rational Field, ... Category of set algebras over Rational Field, diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index aaa52b56ad1..43e476847d0 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -655,9 +655,11 @@ cdef class Map(Element): sage: f = R.hom([x+y, x-y], R) sage: f.category_for() Join of Category of unique factorization domains - and Category of commutative algebras - over (number fields and quotient fields and metric spaces) - and Category of infinite sets + and Category of algebras with basis over + (number fields and quotient fields and metric spaces) + and Category of commutative algebras over + (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: f.category() Category of endsets of unital magmas and right modules over (number fields and quotient fields and metric spaces) diff --git a/src/sage/categories/modules.py b/src/sage/categories/modules.py index d6d63b4df0a..f9bc036910f 100644 --- a/src/sage/categories/modules.py +++ b/src/sage/categories/modules.py @@ -893,7 +893,7 @@ def __init_extra__(self): (Vector space of dimension 2 over Rational Field, Univariate Polynomial Ring in x over Rational Field) sage: A.category() # needs sage.modules - Category of Cartesian products of vector spaces + Category of Cartesian products of vector spaces with basis over (number fields and quotient fields and metric spaces) sage: A.base_ring() # needs sage.modules Rational Field diff --git a/src/sage/interfaces/tab_completion.py b/src/sage/interfaces/tab_completion.py index fdbe51ffd8e..d0e8bc11309 100644 --- a/src/sage/interfaces/tab_completion.py +++ b/src/sage/interfaces/tab_completion.py @@ -71,7 +71,7 @@ def completions(s, globs): sage: import sage.interfaces.tab_completion as s sage: p = x**2 + 1 sage: s.completions('p.co',globals()) # indirect doctest - ['p.coefficients',...] + ['p.coefficient',...] sage: s.completions('dic',globals()) # indirect doctest ['dickman_rho', 'dict'] diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 2e54ce22cd0..ee3e463e988 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1488,10 +1488,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() # needs sage.libs.singular sage: L.category() Category of infinite commutative no zero divisors algebras over - (unique factorization domains and commutative algebras over + (unique factorization domains and algebras with basis over (Dedekind domains and euclidean domains - and noetherian rings - and infinite enumerated sets and metric spaces) + and noetherian rings + and infinite enumerated sets and metric spaces) + and commutative algebras over + (Dedekind domains and euclidean domains + and noetherian rings + and infinite enumerated sets and metric spaces) and infinite sets) sage: L = LazyLaurentSeriesRing(GF(5), 't') diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index c17819a1b2c..40b09bbfb6e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -445,6 +445,8 @@ def __init__(self, R): if R.ngens() != 1: raise ValueError("must be 1 generator") LaurentPolynomialRing_generic.__init__(self, R) + from sage.rings.integer_ring import IntegerRing + self._indices = IntegerRing() Element = LaurentPolynomial_univariate @@ -561,6 +563,12 @@ def _element_constructor_(self, x): return self.element_class(self, x) + def monomial(self, arg): + r""" + Return the monomial with the given exponent. + """ + return self.element_class(self, {arg: self.base_ring().one()}) + def __reduce__(self): """ Used in pickling. @@ -591,6 +599,9 @@ def __init__(self, R): if not R.base_ring().is_integral_domain(): raise ValueError("base ring must be an integral domain") LaurentPolynomialRing_generic.__init__(self, R) + from sage.modules.free_module import FreeModule + from sage.rings.integer_ring import IntegerRing + self._indices = FreeModule(IntegerRing(), R.ngens()) Element = LazyImport('sage.rings.polynomial.laurent_polynomial_mpair', 'LaurentPolynomial_mpair') @@ -605,7 +616,7 @@ def _repr_(self): """ return "Multivariate Laurent Polynomial Ring in %s over %s" % (", ".join(self._R.variable_names()), self._R.base_ring()) - def monomial(self, *args): + def monomial(self, *exponents): r""" Return the monomial whose exponents are given in argument. @@ -629,14 +640,27 @@ def monomial(self, *args): sage: L.monomial(1, 2, 3) # needs sage.modules Traceback (most recent call last): ... - TypeError: tuple key must have same length as ngens - """ - if len(args) != self.ngens(): - raise TypeError("tuple key must have same length as ngens") + TypeError: tuple key (1, 2, 3) must have same length as ngens (= 2) + + We also allow to specify the exponents in a single tuple:: + + sage: L.monomial((-1, 2)) # needs sage.modules + x0^-1*x1^2 + sage: L.monomial((-1, 2, 3)) # needs sage.modules + Traceback (most recent call last): + ... + TypeError: tuple key (-1, 2, 3) must have same length as ngens (= 2) + """ from sage.rings.polynomial.polydict import ETuple - m = ETuple(args, int(self.ngens())) - return self.element_class(self, self.polynomial_ring().one(), m) + if len(exponents) == 1 and isinstance((e := exponents[0]), (tuple, ETuple)): + exponents = e + + if len(exponents) != self.ngens(): + raise TypeError(f"tuple key {exponents} must have same length as ngens (= {self.ngens()})") + + m = ETuple(exponents, int(self.ngens())) + return self.element_class(self, self.polynomial_ring().base_ring().one(), m) def _element_constructor_(self, x, mon=None): """ diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 71eb20cd701..b4f4f13289e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -42,6 +42,8 @@ class LaurentPolynomialRing_generic(CommutativeRing, Parent): sage: R. = LaurentPolynomialRing(QQ) sage: R.category() Join of Category of unique factorization domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd index 4ce9033dadb..322e25e363b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd @@ -4,6 +4,7 @@ from sage.structure.parent cimport Parent cdef class MPolynomialRing_base(CommutativeRing): cdef object _ngens cdef object _term_order + cdef public object _indices cdef public object _has_singular cdef public object _magma_gens cdef public dict _magma_cache diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index dffe6cb80c1..dedacde49a6 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -99,6 +99,8 @@ cdef class MPolynomialRing_base(CommutativeRing): else: category = polynomial_default_category(base_ring.category(), n) Ring.__init__(self, base_ring, names, category=category) + from sage.combinat.integer_vector import IntegerVectors + self._indices = IntegerVectors(self._ngens) def is_integral_domain(self, proof=True): """ diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 165c7fb72a4..2bda9f6f9c3 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -256,15 +256,25 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: category(ZZ['x']) Join of Category of unique factorization domains + and Category of algebras with basis over + (Dedekind domains and euclidean domains + and noetherian rings and infinite enumerated sets + and metric spaces) and Category of commutative algebras over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) and Category of infinite sets + sage: category(GF(7)['x']) Join of Category of euclidean domains - and Category of commutative algebras over - (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets + and Category of algebras with basis over + (finite enumerated fields and subquotients of monoids + and quotients of semigroups) + and Category of commutative algebras over + (finite enumerated fields and subquotients of monoids + and quotients of semigroups) + and Category of infinite sets TESTS: @@ -314,6 +324,8 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, self.__cyclopoly_cache = {} self._has_singular = False Ring.__init__(self, base_ring, names=name, normalize=True, category=category) + from sage.rings.semirings.non_negative_integer_semiring import NonNegativeIntegerSemiring + self._indices = NonNegativeIntegerSemiring() self._populate_coercion_lists_(convert_method_name='_polynomial_') def __reduce__(self): diff --git a/src/sage/rings/polynomial/polynomial_ring_constructor.py b/src/sage/rings/polynomial/polynomial_ring_constructor.py index a135fe8de6c..5cbc74dd1d5 100644 --- a/src/sage/rings/polynomial/polynomial_ring_constructor.py +++ b/src/sage/rings/polynomial/polynomial_ring_constructor.py @@ -916,23 +916,30 @@ def polynomial_default_category(base_ring_category, n_variables): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category - sage: polynomial_default_category(Rings(),1) is Algebras(Rings()).Infinite() + sage: polynomial_default_category(Rings(), 1) + Category of infinite algebras with basis over rings + sage: polynomial_default_category(Rings().Commutative(), 1) + Category of infinite commutative algebras with basis + over commutative rings + sage: polynomial_default_category(Fields(), 1) + Join of Category of euclidean domains + and Category of algebras with basis over fields + and Category of commutative algebras over fields + and Category of infinite sets + sage: polynomial_default_category(Fields(), 2) + Join of Category of unique factorization domains + and Category of algebras with basis over fields + and Category of commutative algebras over fields + and Category of infinite sets + + sage: QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite() True - sage: polynomial_default_category(Rings().Commutative(),1) is Algebras(Rings().Commutative()).Commutative().Infinite() + sage: QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite() True - sage: polynomial_default_category(Fields(),1) is EuclideanDomains() & Algebras(Fields()).Infinite() - True - sage: polynomial_default_category(Fields(),2) is UniqueFactorizationDomains() & CommutativeAlgebras(Fields()).Infinite() - True - - sage: QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).Infinite() - True - sage: QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).Infinite() - True - sage: QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).Infinite() + sage: QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).WithBasis().Infinite() True """ - category = Algebras(base_ring_category) + category = Algebras(base_ring_category).WithBasis() if n_variables: # here we assume the base ring to be nonzero @@ -1034,4 +1041,4 @@ def BooleanPolynomialRing_constructor(n=None, names=None, order='lex'): ############################################################################ # END (Factory function for making polynomial rings) -############################################################################ \ No newline at end of file +############################################################################ diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 59cf58e3513..d139c1449c5 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -155,6 +155,7 @@ cdef class Ring(ParentWithGens): Running the test suite of self.an_element() running ._test_category() . . . pass running ._test_eq() . . . pass + running ._test_monomial_coefficients() . . . pass running ._test_new() . . . pass running ._test_nonzero_equal() . . . pass running ._test_not_implemented_methods() . . . pass @@ -184,20 +185,29 @@ cdef class Ring(ParentWithGens): Test against another bug fixed in :issue:`9944`:: sage: QQ['x'].category() - Join of Category of euclidean domains and Category of commutative algebras over - (number fields and quotient fields and metric spaces) and Category of infinite sets + Join of Category of euclidean domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) + and Category of commutative algebras + over (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: QQ['x','y'].category() Join of Category of unique factorization domains + and Category of algebras with basis + over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: PolynomialRing(MatrixSpace(QQ, 2),'x').category() # needs sage.modules - Category of infinite algebras over (finite dimensional algebras with basis over - (number fields and quotient fields and metric spaces) and infinite sets) + Category of infinite algebras with basis + over (finite dimensional algebras with basis + over (number fields and quotient fields and metric spaces) + and infinite sets) sage: PolynomialRing(SteenrodAlgebra(2),'x').category() # needs sage.combinat sage.modules - Category of infinite algebras over (super Hopf algebras with basis - over Finite Field of size 2 and supercocommutative super coalgebras - over Finite Field of size 2) + Category of infinite algebras with basis + over (super Hopf algebras with basis over Finite Field of size 2 + and supercocommutative super coalgebras + over Finite Field of size 2) TESTS::