def __eq__(self, other): """ Check whether ``self`` is equal to ``other``. EXAMPLES:: sage: R = PolynomialRing(Integers(10), 'x', 4) sage: loads(R.dumps()) == R True """ if not is_MPolynomialRing(other): return False return ((self.base_ring(), self.ngens(), self.variable_names(), self.term_order()) == (other.base_ring(), other.ngens(), other.variable_names(), other.term_order()))
def __eq__(left, right): """ Check whether ``left`` is equal to ``right``. EXAMPLES:: sage: R = PolynomialRing(Integers(10), 'x', 4) sage: loads(R.dumps()) == R True """ if not is_MPolynomialRing(right): return False return ((left.base_ring(), left.ngens(), left.variable_names(), left.term_order()) == (right.base_ring(), right.ngens(), right.variable_names(), right.term_order()))
def parent_to_repr_short(P): r""" Helper method which generates a short(er) representation string out of a parent. INPUT: - ``P`` -- a parent. OUTPUT: A string. EXAMPLES:: sage: from sage.rings.asymptotic.misc import parent_to_repr_short sage: parent_to_repr_short(ZZ) 'ZZ' sage: parent_to_repr_short(QQ) 'QQ' sage: parent_to_repr_short(SR) 'SR' sage: parent_to_repr_short(ZZ['x']) 'ZZ[x]' sage: parent_to_repr_short(QQ['d, k']) 'QQ[d, k]' sage: parent_to_repr_short(QQ['e']) 'QQ[e]' sage: parent_to_repr_short(SR[['a, r']]) 'SR[[a, r]]' sage: parent_to_repr_short(Zmod(3)) 'Ring of integers modulo 3' sage: parent_to_repr_short(Zmod(3)['g']) 'Univariate Polynomial Ring in g over Ring of integers modulo 3' """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.symbolic.ring import SR from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing from sage.rings.power_series_ring import is_PowerSeriesRing def abbreviate(P): if P is ZZ: return 'ZZ' elif P is QQ: return 'QQ' elif P is SR: return 'SR' raise ValueError('Cannot abbreviate %s.' % (P, )) poly = is_PolynomialRing(P) or is_MPolynomialRing(P) from sage.rings import multi_power_series_ring power = is_PowerSeriesRing(P) or \ multi_power_series_ring.is_MPowerSeriesRing(P) if poly or power: if poly: op, cl = ('[', ']') else: op, cl = ('[[', ']]') try: s = abbreviate(P.base_ring()) + op + ', '.join( P.variable_names()) + cl except ValueError: s = str(P) else: try: s = abbreviate(P) except ValueError: s = str(P) return s
def LaurentPolynomialRing(base_ring, *args, **kwds): r""" Return the globally unique univariate or multivariate Laurent polynomial ring with given properties and variable name or names. There are four ways to call the Laurent polynomial ring constructor: 1. ``LaurentPolynomialRing(base_ring, name, sparse=False)`` 2. ``LaurentPolynomialRing(base_ring, names, order='degrevlex')`` 3. ``LaurentPolynomialRing(base_ring, name, n, order='degrevlex')`` 4. ``LaurentPolynomialRing(base_ring, n, name, order='degrevlex')`` The optional arguments sparse and order *must* be explicitly named, and the other arguments must be given positionally. INPUT: - ``base_ring`` -- a commutative ring - ``name`` -- a string - ``names`` -- a list or tuple of names, or a comma separated string - ``n`` -- a positive integer - ``sparse`` -- bool (default: False), whether or not elements are sparse - ``order`` -- string or :class:`~sage.rings.polynomial.term_order.TermOrder`, e.g., - ``'degrevlex'`` (default) -- degree reverse lexicographic - ``'lex'`` -- lexicographic - ``'deglex'`` -- degree lexicographic - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering OUTPUT: ``LaurentPolynomialRing(base_ring, name, sparse=False)`` returns a univariate Laurent polynomial ring; all other input formats return a multivariate Laurent polynomial ring. UNIQUENESS and IMMUTABILITY: In Sage there is exactly one single-variate Laurent polynomial ring over each base ring in each choice of variable and sparseness. There is also exactly one multivariate Laurent polynomial ring over each base ring for each choice of names of variables and term order. :: sage: R.<x,y> = LaurentPolynomialRing(QQ,2); R Multivariate Laurent Polynomial Ring in x, y over Rational Field sage: f = x^2 - 2*y^-2 You can't just globally change the names of those variables. This is because objects all over Sage could have pointers to that polynomial ring. :: sage: R._assign_names(['z','w']) Traceback (most recent call last): ... ValueError: variable names cannot be changed after object creation. EXAMPLES: 1. ``LaurentPolynomialRing(base_ring, name, sparse=False)`` :: sage: LaurentPolynomialRing(QQ, 'w') Univariate Laurent Polynomial Ring in w over Rational Field Use the diamond brackets notation to make the variable ready for use after you define the ring:: sage: R.<w> = LaurentPolynomialRing(QQ) sage: (1 + w)^3 1 + 3*w + 3*w^2 + w^3 You must specify a name:: sage: LaurentPolynomialRing(QQ) Traceback (most recent call last): ... TypeError: you must specify the names of the variables sage: R.<abc> = LaurentPolynomialRing(QQ, sparse=True); R Univariate Laurent Polynomial Ring in abc over Rational Field sage: R.<w> = LaurentPolynomialRing(PolynomialRing(GF(7),'k')); R Univariate Laurent Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 Rings with different variables are different:: sage: LaurentPolynomialRing(QQ, 'x') == LaurentPolynomialRing(QQ, 'y') False 2. ``LaurentPolynomialRing(base_ring, names, order='degrevlex')`` :: sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R Multivariate Laurent Polynomial Ring in a, b, c over Rational Field sage: S = LaurentPolynomialRing(QQ, ['a','b','c']); S Multivariate Laurent Polynomial Ring in a, b, c over Rational Field sage: T = LaurentPolynomialRing(QQ, ('a','b','c')); T Multivariate Laurent Polynomial Ring in a, b, c over Rational Field All three rings are identical. :: sage: (R is S) and (S is T) True There is a unique Laurent polynomial ring with each term order:: sage: R = LaurentPolynomialRing(QQ, 'x,y,z', order='degrevlex'); R Multivariate Laurent Polynomial Ring in x, y, z over Rational Field sage: S = LaurentPolynomialRing(QQ, 'x,y,z', order='invlex'); S Multivariate Laurent Polynomial Ring in x, y, z over Rational Field sage: S is LaurentPolynomialRing(QQ, 'x,y,z', order='invlex') True sage: R == S False 3. ``LaurentPolynomialRing(base_ring, name, n, order='degrevlex')`` If you specify a single name as a string and a number of variables, then variables labeled with numbers are created. :: sage: LaurentPolynomialRing(QQ, 'x', 10) Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field sage: LaurentPolynomialRing(GF(7), 'y', 5) Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 sage: LaurentPolynomialRing(QQ, 'y', 3, sparse=True) Multivariate Laurent Polynomial Ring in y0, y1, y2 over Rational Field By calling the :meth:`~sage.structure.category_object.CategoryObject.inject_variables` method, all those variable names are available for interactive use:: sage: R = LaurentPolynomialRing(GF(7),15,'w'); R Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7 sage: R.inject_variables() Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 sage: (w0 + 2*w8 + w13)^2 w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2 """ from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing R = PolynomialRing(base_ring, *args, **kwds) if R in _cache: return _cache[R] # put () here to re-enable weakrefs if is_PolynomialRing(R): # univariate case P = LaurentPolynomialRing_univariate(R) else: assert is_MPolynomialRing(R) P = LaurentPolynomialRing_mpair(R) _cache[R] = P return P
def __init__(self, base_ring, name=None, default_prec=None, sparse=False, implementation=None, category=None): """ Initializes a power series ring. INPUT: - ``base_ring`` - a commutative ring - ``name`` - name of the indeterminate - ``default_prec`` - the default precision - ``sparse`` - whether or not power series are sparse - ``implementation`` -- either ``'poly'``, ``'mpoly'``, or ``'pari'``. Other values (for example ``'NTL'``) are passed to the attached polynomial ring. The default is ``'pari'`` if the base field is a PARI finite field, and ``'poly'`` otherwise. If the base ring is a polynomial ring, then the option ``implementation='mpoly'`` causes computations to be done with multivariate polynomials instead of a univariate polynomial ring over the base ring. Only use this for dense power series where you won't do too much arithmetic, but the arithmetic you do must be fast. You must explicitly call ``f.do_truncation()`` on an element for it to truncate away higher order terms (this is called automatically before printing). EXAMPLES: This base class inherits from :class:`~sage.rings.ring.CommutativeRing`. Since :trac:`11900`, it is also initialised as such, and since :trac:`14084` it is actually initialised as an integral domain:: sage: R.<x> = ZZ[[]] sage: R.category() Category of integral domains sage: TestSuite(R).run() When the base ring `k` is a field, the ring `k[[x]]` is not only a commutative ring, but also a complete discrete valuation ring (CDVR). The appropriate (sub)category is automatically set in this case:: sage: k = GF(11) sage: R.<x> = k[[]] sage: R.category() Category of complete discrete valuation rings sage: TestSuite(R).run() It is checked that the default precision is non-negative (see :trac:`19409`):: sage: PowerSeriesRing(ZZ, 'x', default_prec=-5) Traceback (most recent call last): ... ValueError: default_prec (= -5) must be non-negative """ from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt if implementation is None: if isinstance(base_ring, FiniteField_pari_ffelt): implementation = 'pari' else: implementation = 'poly' R = PolynomialRing(base_ring, name, sparse=sparse) elif implementation not in ['pari', 'mpoly']: # see :trac:`28996` R = PolynomialRing(base_ring, name, sparse=sparse, implementation=implementation) implementation = 'poly' else: R = PolynomialRing(base_ring, name, sparse=sparse) self.__poly_ring = R self.__is_sparse = sparse if default_prec is None: from sage.misc.defaults import series_precision default_prec = series_precision() elif default_prec < 0: raise ValueError("default_prec (= %s) must be non-negative" % default_prec) if implementation == 'poly': self.Element = power_series_poly.PowerSeries_poly elif implementation == 'mpoly': K = base_ring names = K.variable_names() + (name, ) self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names) assert is_MPolynomialRing(self.__mpoly_ring) self.Element = power_series_mpoly.PowerSeries_mpoly elif implementation == 'pari': self.Element = PowerSeries_pari else: raise ValueError('unknown power series implementation: %r' % implementation) ring.CommutativeRing.__init__(self, base_ring, names=name, category=getattr(self, '_default_category', _CommutativeRings)) Nonexact.__init__(self, default_prec) if self.Element is PowerSeries_pari: self.__generator = self.element_class(self, R.gen().__pari__()) else: self.__generator = self.element_class(self, R.gen(), is_gen=True)