Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Ring of Laurent Polynomials
If `R` is a commutative ring, then the ring of Laurent polynomials in `n` variables over `R` is `R[x_1^{\pm 1}, x_2^{\pm 1}, \ldots, x_n^{\pm 1}]`. We implement it as a quotient ring
.. MATH::
R[x_1, y_1, x_2, y_2, \ldots, x_n, y_n] / (x_1 y_1 - 1, x_2 y_2 - 1, \ldots, x_n y_n - 1).
TESTS::
sage: P.<q> = LaurentPolynomialRing(QQ) sage: qi = q^(-1) sage: qi in P True sage: P(qi) q^-1
sage: A.<Y> = QQ[] sage: R.<X> = LaurentPolynomialRing(A) sage: matrix(R,2,2,[X,0,0,1]) [X 0] [0 1]
AUTHORS:
- David Roe (2008-2-23): created - David Loeffler (2009-07-10): cleaned up docstrings """ #***************************************************************************** # Copyright (C) 2008 David Roe <roed@math.harvard.edu>, # William Stein <wstein@gmail.com>, # Mike Hansen <mhansen@gmail.com> # Vincent Delecroix <20100.delecroix@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import from six import iteritems, iterkeys, integer_types from six.moves import range
from sage.structure.category_object import normalize_names from sage.structure.element import is_Element, parent from sage.rings.ring import is_Ring from sage.rings.infinity import infinity from sage.rings.integer import Integer from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.misc.latex import latex from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair, LaurentPolynomial_univariate from sage.rings.ring import CommutativeRing from sage.structure.parent_gens import ParentWithGens
def is_LaurentPolynomialRing(R): """ Returns True if and only if R is a Laurent polynomial ring.
EXAMPLES::
sage: from sage.rings.polynomial.laurent_polynomial_ring import is_LaurentPolynomialRing sage: P = PolynomialRing(QQ,2,'x') sage: is_LaurentPolynomialRing(P) False
sage: R = LaurentPolynomialRing(QQ,3,'x') sage: is_LaurentPolynomialRing(R) True """
_cache = {} 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 """
# univariate case else:
def _split_dict_(D, indices, group_by=None): r""" Split the dictionary ``D`` by ``indices`` and ``group_by``.
INPUT:
- ``D`` -- a dictionary.
- ``indices`` -- a tuple or list of nonnegative integers.
- ``group_by`` -- a tuple or list of nonnegative integers. If this is ``None`` (default), then no grouping is done.
OUTPUT:
A dictionary.
TESTS::
sage: from sage.rings.polynomial.laurent_polynomial_ring import _split_dict_ sage: D = {(0,0,0,0): 'a', (1,0,0,0): 'b', ....: (1,0,0,2): 'c', (1,2,0,3): 'd'} sage: _split_dict_(D, [1,0,3]) {(0, 0, 0): 'a', (0, 1, 0): 'b', (0, 1, 2): 'c', (2, 1, 3): 'd'} sage: _split_dict_(D, [2,3], [0,1]) {(0, 0): {(0, 0): 'a'}, (1, 0): {(0, 0): 'b', (0, 2): 'c'}, (1, 2): {(0, 3): 'd'}} sage: _split_dict_(D, [3,1], [0]) {(0,): {(0, 0): 'a'}, (1,): {(0, 0): 'b', (2, 0): 'c', (3, 2): 'd'}}
sage: _split_dict_(D, [0,None,1,3]) {(0, 0, 0, 0): 'a', (1, 0, 0, 0): 'b', (1, 0, 0, 2): 'c', (1, 0, 2, 3): 'd'} sage: _split_dict_(D, [0,1], [None,3,None]) {(0, 0, 0): {(0, 0): 'a', (1, 0): 'b'}, (0, 2, 0): {(1, 0): 'c'}, (0, 3, 0): {(1, 2): 'd'}} sage: _split_dict_(D, [None,3,1], [0,None]) {(0, 0): {(0, 0, 0): 'a'}, (1, 0): {(0, 0, 0): 'b', (0, 2, 0): 'c', (0, 3, 2): 'd'}}
sage: _split_dict_(D, [0,1]) Traceback (most recent call last): ... SplitDictError: split not possible sage: _split_dict_(D, [0], [1]) Traceback (most recent call last): ... SplitDictError: split not possible sage: _split_dict_({}, []) {} """
- set(indices) - set(group_by)) else:
def _split_laurent_polynomial_dict_(P, M, d): r""" Helper function for splitting a multivariate Laurent polynomial during conversion.
INPUT:
- ``P`` -- the parent to which we want to convert.
- ``M`` -- the parent from which we want to convert.
- ``d`` -- a dictionary mapping tuples (representing the exponents) to their coefficients. This is the dictionary corresponding to an element of ``M``.
OUTPUT:
A dictionary corresponding to an element of ``P``.
TESTS::
sage: L.<a, b, c, d> = LaurentPolynomialRing(ZZ) sage: M = LaurentPolynomialRing(ZZ, 'c, d') sage: N = LaurentPolynomialRing(M, 'a, b') sage: M(c/d + 1/c) # indirect doctest c*d^-1 + c^-1 sage: N(a + b/c/d + 1/b) # indirect doctest a + (c^-1*d^-1)*b + b^-1 """ raise TypeError('no common variables')
class LaurentPolynomialRing_generic(CommutativeRing, ParentWithGens): """ Laurent polynomial ring (base class).
EXAMPLES:
This base class inherits from :class:`~sage.rings.ring.CommutativeRing`. Since :trac:`11900`, it is also initialised as such::
sage: R.<x1,x2> = LaurentPolynomialRing(QQ) sage: R.category() Category of commutative rings sage: TestSuite(R).run()
""" def __init__(self, R): """ EXAMPLES::
sage: R = LaurentPolynomialRing(QQ,2,'x') sage: R == loads(dumps(R)) True """
def ngens(self): """ Returns the number of generators of self.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').ngens() 2 sage: LaurentPolynomialRing(QQ,1,'x').ngens() 1 """
def gen(self, i=0): r""" Returns the `i^{th}` generator of self. If i is not specified, then the first generator will be returned.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').gen() x0 sage: LaurentPolynomialRing(QQ,2,'x').gen(0) x0 sage: LaurentPolynomialRing(QQ,2,'x').gen(1) x1
TESTS::
sage: LaurentPolynomialRing(QQ,2,'x').gen(3) Traceback (most recent call last): ... ValueError: generator not defined """
def variable_names_recursive(self, depth=infinity): r""" Return the list of variable names of this ring and its base rings, as if it were a single multi-variate Laurent polynomial.
INPUT:
- ``depth`` -- an integer or :mod:`Infinity <sage.rings.infinity>`.
OUTPUT:
A tuple of strings.
EXAMPLES::
sage: T = LaurentPolynomialRing(QQ, 'x') sage: S = LaurentPolynomialRing(T, 'y') sage: R = LaurentPolynomialRing(S, 'z') sage: R.variable_names_recursive() ('x', 'y', 'z') sage: R.variable_names_recursive(2) ('y', 'z') """ return () else:
def is_integral_domain(self, proof = True): """ Returns True if self is an integral domain.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').is_integral_domain() True
The following used to fail; see :trac:`7530`::
sage: L = LaurentPolynomialRing(ZZ, 'X') sage: L['Y'] Univariate Polynomial Ring in Y over Univariate Laurent Polynomial Ring in X over Integer Ring """
def is_noetherian(self): """ Returns True if self is Noetherian.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').is_noetherian() Traceback (most recent call last): ... NotImplementedError """
def construction(self): """ Returns the construction of self.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x,y').construction() (LaurentPolynomialFunctor, Univariate Laurent Polynomial Ring in x over Rational Field)
""" else:
def completion(self, p, prec=20, extras=None): """ EXAMPLES::
sage: P.<x>=LaurentPolynomialRing(QQ) sage: P Univariate Laurent Polynomial Ring in x over Rational Field sage: PP=P.completion(x) sage: PP Laurent Series Ring in x over Rational Field sage: f=1-1/x sage: PP(f) -x^-1 + 1 sage: 1/PP(f) -x - x^2 - x^3 - x^4 - x^5 - x^6 - x^7 - x^8 - x^9 - x^10 - x^11 - x^12 - x^13 - x^14 - x^15 - x^16 - x^17 - x^18 - x^19 - x^20 + O(x^21)
TESTS:
Check that the precision is taken into account (:trac:`24431`)::
sage: L = LaurentPolynomialRing(QQ, 'x') sage: L.completion('x', 100).default_prec() 100 sage: L.completion('x', 20).default_prec() 20 """ else: raise TypeError("Cannot complete %s with respect to %s" % (self, p))
def remove_var(self, var): """ EXAMPLES::
sage: R = LaurentPolynomialRing(QQ,'x,y,z') sage: R.remove_var('x') Multivariate Laurent Polynomial Ring in y, z over Rational Field sage: R.remove_var('x').remove_var('y') Univariate Laurent Polynomial Ring in z over Rational Field """
def _coerce_map_from_(self, R): """ EXAMPLES::
sage: L.<x,y> = LaurentPolynomialRing(QQ) sage: L.coerce_map_from(QQ) Composite map: From: Rational Field To: Multivariate Laurent Polynomial Ring in x, y over Rational Field Defn: Polynomial base injection morphism: From: Rational Field To: Multivariate Polynomial Ring in x, y over Rational Field then Call morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Multivariate Laurent Polynomial Ring in x, y over Rational Field
Let us check that coercion between Laurent Polynomials over different base rings works (:trac:`15345`)::
sage: R = LaurentPolynomialRing(ZZ, 'x') sage: T = LaurentPolynomialRing(QQ, 'x') sage: R.gen() + 3*T.gen() 4*x """ and self._R.has_coerce_map_from(R._R)): parent_as_first_arg=False) R.variable_names() == self.variable_names() and \ self.base_ring().has_coerce_map_from(R.base_ring()): return True
def __eq__(self, right): """ Check whether ``self`` is equal to ``right``.
EXAMPLES::
sage: R = LaurentPolynomialRing(QQ,'x,y,z') sage: P = LaurentPolynomialRing(ZZ,'x,y,z') sage: Q = LaurentPolynomialRing(QQ,'x,y')
sage: R == R True sage: R == Q False sage: Q == P False sage: P == R False """
def __ne__(self, other): """ Check whether ``self`` is not equal to ``other``.
EXAMPLES::
sage: R = LaurentPolynomialRing(QQ,'x,y,z') sage: P = LaurentPolynomialRing(ZZ,'x,y,z') sage: Q = LaurentPolynomialRing(QQ,'x,y')
sage: R != R False sage: R != Q True sage: Q != P True sage: P != R True """
def _latex_(self): """ EXAMPLES::
sage: latex(LaurentPolynomialRing(QQ,2,'x')) \Bold{Q}[x_{0}^{\pm 1}, x_{1}^{\pm 1}] """
def _ideal_class_(self, n=0): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x')._ideal_class_() Traceback (most recent call last): ... NotImplementedError """ # One may eventually want ideals in these guys.
def ideal(self): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').ideal() Traceback (most recent call last): ... NotImplementedError """
def _is_valid_homomorphism_(self, codomain, im_gens): """ EXAMPLES::
sage: L.<x,y> = LaurentPolynomialRing(QQ) sage: L._is_valid_homomorphism_(QQ, (1/2, 3/2)) True """ # we need that elements of the base ring # canonically coerce into codomain. return False # in addition, the image of each generator must be invertible. return False
def term_order(self): """ Returns the term order of self.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').term_order() Degree reverse lexicographic term order
"""
def is_finite(self): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').is_finite() False
"""
def is_field(self, proof = True): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').is_field() False """
def polynomial_ring(self): """ Returns the polynomial ring associated with self.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').polynomial_ring() Multivariate Polynomial Ring in x0, x1 over Rational Field sage: LaurentPolynomialRing(QQ,1,'x').polynomial_ring() Multivariate Polynomial Ring in x over Rational Field """
def characteristic(self): """ Returns the characteristic of the base ring.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').characteristic() 0 sage: LaurentPolynomialRing(GF(3),2,'x').characteristic() 3
"""
def krull_dimension(self): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').krull_dimension() Traceback (most recent call last): ... NotImplementedError """
def random_element(self, low_degree = -2, high_degree = 2, terms = 5, choose_degree=False,*args, **kwds): """ EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').random_element() Traceback (most recent call last): ... NotImplementedError """
def is_exact(self): """ Returns True if the base ring is exact.
EXAMPLES::
sage: LaurentPolynomialRing(QQ,2,'x').is_exact() True sage: LaurentPolynomialRing(RDF,2,'x').is_exact() False """
def change_ring(self, base_ring=None, names=None, sparse=False, order=None): """ EXAMPLES::
sage: R = LaurentPolynomialRing(QQ,2,'x') sage: R.change_ring(ZZ) Multivariate Laurent Polynomial Ring in x0, x1 over Integer Ring """ base_ring = self.base_ring()
def fraction_field(self): """ The fraction field is the same as the fraction field of the polynomial ring.
EXAMPLES::
sage: L.<x> = LaurentPolynomialRing(QQ) sage: L.fraction_field() Fraction Field of Univariate Polynomial Ring in x over Rational Field sage: (x^-1 + 2) / (x - 1) (2*x + 1)/(x^2 - x) """
class LaurentPolynomialRing_univariate(LaurentPolynomialRing_generic): def __init__(self, R): """ EXAMPLES::
sage: L = LaurentPolynomialRing(QQ,'x') sage: type(L) <class 'sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_univariate_with_category'> sage: L == loads(dumps(L)) True
TESTS::
sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() sage: TestSuite(LaurentPolynomialRing(ZZ, 'u')).run() sage: TestSuite(LaurentPolynomialRing(Zmod(4)['T'], 'u')).run() """ raise ValueError("must be 1 generator")
def _repr_(self): """ TESTS::
sage: LaurentPolynomialRing(QQ,'x') # indirect doctest Univariate Laurent Polynomial Ring in x over Rational Field """
def _element_constructor_(self, x): """ EXAMPLES::
sage: L = LaurentPolynomialRing(QQ, 'x') sage: L(1/2) 1/2
sage: L(x + 3/x) 3*x^-1 + x
::
sage: L(exp(x)) Traceback (most recent call last): ... TypeError: unable to convert e^x to a rational
::
sage: U = LaurentPolynomialRing(QQ, 'a') sage: V = LaurentPolynomialRing(QQ, 'c') sage: L.<a, b, c, d> = LaurentPolynomialRing(QQ) sage: M = LaurentPolynomialRing(QQ, 'c, d') sage: Mc, Md = M.gens() sage: N = LaurentPolynomialRing(M, 'a, b') sage: Na, Nb = N.gens() sage: U(Na) a sage: V(Mc) c
sage: M(L(0)) 0 sage: N(L(0)) 0 sage: L(M(0)) 0 sage: L(N(0)) 0
::
sage: A.<a> = LaurentPolynomialRing(QQ) sage: B.<b> = LaurentPolynomialRing(A) sage: B(a) a sage: C.<c> = LaurentPolynomialRing(B) sage: B(C(b)) b sage: D.<d, e> = LaurentPolynomialRing(B) sage: B(D(b)) b """
else: elif len(self.variable_names()) == len(P.variable_names()): x = x.dict()
def __reduce__(self): """ Used in pickling.
EXAMPLES::
sage: L = LaurentPolynomialRing(QQ, 'x') sage: loads(dumps(L)) == L True """
class LaurentPolynomialRing_mpair(LaurentPolynomialRing_generic): def __init__(self, R): """ EXAMPLES::
sage: L = LaurentPolynomialRing(QQ,2,'x') sage: type(L) <class 'sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair_with_category'> sage: L == loads(dumps(L)) True """ raise ValueError("n must be positive") raise ValueError("base ring must be an integral domain")
def _repr_(self): """ TESTS::
sage: LaurentPolynomialRing(QQ,2,'x').__repr__() 'Multivariate Laurent Polynomial Ring in x0, x1 over Rational Field' sage: LaurentPolynomialRing(QQ,1,'x').__repr__() 'Multivariate Laurent Polynomial Ring in x over Rational Field' """
def monomial(self, *args): r""" Return the monomial whose exponents are given in argument.
EXAMPLES::
sage: L = LaurentPolynomialRing(QQ, 'x', 2) sage: L.monomial(-3, 5) x0^-3*x1^5 sage: L.monomial(1, 1) x0*x1 sage: L.monomial(0, 0) 1 sage: L.monomial(-2, -3) x0^-2*x1^-3
sage: x0, x1 = L.gens() sage: L.monomial(-1, 2) == x0^-1 * x1^2 True
sage: L.monomial(1, 2, 3) Traceback (most recent call last): ... TypeError: tuple key must have same length as ngens """
def _element_constructor_(self, x, mon=None): """ EXAMPLES::
sage: L = LaurentPolynomialRing(QQ,2,'x') sage: L(1/2) 1/2
sage: M = LaurentPolynomialRing(QQ, 'x, y') sage: var('x, y') (x, y) sage: M(x/y + 3/x) x*y^-1 + 3*x^-1
::
sage: M(exp(x)) Traceback (most recent call last): ... TypeError: unable to convert e^x to a rational
::
sage: L.<a, b, c, d> = LaurentPolynomialRing(QQ) sage: M = LaurentPolynomialRing(QQ, 'c, d') sage: Mc, Md = M.gens() sage: N = LaurentPolynomialRing(M, 'a, b') sage: Na, Nb = N.gens() sage: M(c/d) c*d^-1 sage: N(a*b/c/d) (c^-1*d^-1)*a*b sage: N(c/d) c*d^-1 sage: L(Mc) c sage: L(Nb) b
sage: M(L(0)) 0 sage: N(L(0)) 0 sage: L(M(0)) 0 sage: L(N(0)) 0
sage: U = LaurentPolynomialRing(QQ, 'a') sage: Ua = U.gen() sage: V = LaurentPolynomialRing(QQ, 'c') sage: Vc = V.gen() sage: L(Ua) a sage: L(Vc) c sage: N(Ua) a sage: M(Vc) c
sage: P = LaurentPolynomialRing(QQ, 'a, b') sage: Q = LaurentPolynomialRing(P, 'c, d') sage: Q(P.0) a
::
sage: A.<a> = LaurentPolynomialRing(QQ) sage: B.<b> = LaurentPolynomialRing(A) sage: C = LaurentPolynomialRing(QQ, 'a, b') sage: C(B({1: a})) a*b sage: D.<d, e> = LaurentPolynomialRing(B) sage: F.<f, g> = LaurentPolynomialRing(D) sage: D(F(d*e)) d*e
::
sage: from sage.rings.polynomial.polydict import ETuple sage: R.<x,y,z> = LaurentPolynomialRing(QQ) sage: mon = ETuple({}, int(3)) sage: P = R.polynomial_ring() sage: R(sum(P.gens()), mon) x + y + z sage: R(sum(P.gens()), (-1,-1,-1)) y^-1*z^-1 + x^-1*z^-1 + x^-1*y^-1 """
# No special processing needed here; # handled by LaurentPolynomial_mpair.__init__ else: elif len(self.variable_names()) == len(P.variable_names()): x = x.dict()
def __reduce__(self): """ Used in pickling.
EXAMPLES::
sage: L = LaurentPolynomialRing(QQ,2,'x') sage: loads(dumps(L)) == L True """
|