def __add__(self, other):
        r"""
        Return the subgroup of `\QQ` generated by this group and ``other``.

        INPUT:

        - ``other`` -- a discrete value group or a rational number

        EXAMPLES::

            sage: D = DiscreteValueGroup(1/2)
            sage: D + 1/3
            DiscreteValueGroup(1/6)
            sage: D + D
            DiscreteValueGroup(1/2)
            sage: D + 1
            DiscreteValueGroup(1/2)
            sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9)
            DiscreteValueGroup(2/63)

        """
        if not isinstance(other, DiscreteValueGroup):
            from sage.structure.element import is_Element
            if is_Element(other) and QQ.has_coerce_map_from(other.parent()):
                return self + DiscreteValueGroup(other, category=self.category())
            raise ValueError("`other` must be a DiscreteValueGroup or a rational number")
        if self.category() is not other.category():
            raise ValueError("`other` must be in the same category")
        return DiscreteValueGroup(self._generator.gcd(other._generator), category=self.category())
    def __add__(self, other):
        r"""
        Return the subgroup of \QQ generated by this group and ``other``.

        INPUT:

        - ``other`` -- a discrete value group or a rational number

        EXAMPLES::

            sage: D = DiscreteValueGroup(1/2)
            sage: D + 1/3
            DiscreteValueGroup(1/6)
            sage: D + D
            DiscreteValueGroup(1/2)
            sage: D + 1
            DiscreteValueGroup(1/2)
            sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9)
            DiscreteValueGroup(2/63)

        """
        if not isinstance(other, DiscreteValueGroup):
            from sage.structure.element import is_Element
            if is_Element(other) and QQ.has_coerce_map_from(other.parent()):
                return self + DiscreteValueGroup(other,
                                                 category=self.category())
            raise ValueError(
                "`other` must be a DiscreteValueGroup or a rational number")
        if self.category() is not other.category():
            raise ValueError("`other` must be in the same category")
        return DiscreteValueGroup(self._generator.gcd(other._generator),
                                  category=self.category())
Exemple #3
0
    def __add__(self, other):
        r"""
        Return the subsemigroup of `\QQ` generated by this semigroup and ``other``.

        INPUT:

        - ``other`` -- a discrete value (semi-)group or a rational number

        EXAMPLES::

            sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup, DiscreteValueGroup
            sage: D = DiscreteValueSemigroup(1/2)
            sage: D + 1/3
            Additive Abelian Semigroup generated by 1/3, 1/2
            sage: D + D
            Additive Abelian Semigroup generated by 1/2
            sage: D + 1
            Additive Abelian Semigroup generated by 1/2
            sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9)
            Additive Abelian Semigroup generated by -2/7, 2/7, 4/9

        """
        if isinstance(other, DiscreteValueSemigroup):
            return DiscreteValueSemigroup(self._generators + other._generators)
        if isinstance(other, DiscreteValueGroup):
            return DiscreteValueSemigroup(self._generators + (other._generator, -other._generator))
        from sage.structure.element import is_Element
        if is_Element(other) and QQ.has_coerce_map_from(other.parent()):
            return self + DiscreteValueSemigroup(other)
        raise ValueError("`other` must be a DiscreteValueGroup, a DiscreteValueSemigroup or a rational number")
Exemple #4
0
    def __add__(self, other):
        r"""
        Return the subsemigroup of \QQ generated by this semigroup and ``other``.

        INPUT:

        - ``other`` -- a discrete value (semi-)group or a rational number

        EXAMPLES::

            sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone
            sage: D = DiscreteValueSemigroup(1/2)
            sage: D + 1/3
            Additive Abelian Semigroup generated by 1/3, 1/2
            sage: D + D
            Additive Abelian Semigroup generated by 1/2
            sage: D + 1
            Additive Abelian Semigroup generated by 1/2
            sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9)
            Additive Abelian Semigroup generated by -2/7, 2/7, 4/9

        """
        if isinstance(other, DiscreteValueSemigroup):
            return DiscreteValueSemigroup(self._generators + other._generators)
        if isinstance(other, DiscreteValueGroup):
            return DiscreteValueSemigroup(self._generators +
                                          (other._generator,
                                           -other._generator))
        from sage.structure.element import is_Element
        if is_Element(other) and QQ.has_coerce_map_from(other.parent()):
            return self + DiscreteValueSemigroup(other)
        raise ValueError(
            "`other` must be a DiscreteValueGroup, a DiscreteValueSemigroup or a rational number"
        )
Exemple #5
0
    def __add__(self, other):
        r"""
        Return the subgroup of `\QQ` generated by this group and ``other``.

        INPUT:

        - ``other`` -- a discrete value group or a rational number

        EXAMPLES::

            sage: from sage.rings.valuation.value_group import DiscreteValueGroup
            sage: D = DiscreteValueGroup(1/2)
            sage: D + 1/3
            Additive Abelian Group generated by 1/6
            sage: D + D
            Additive Abelian Group generated by 1/2
            sage: D + 1
            Additive Abelian Group generated by 1/2
            sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9)
            Additive Abelian Group generated by 2/63

        """
        if isinstance(other, DiscreteValueGroup):
            return DiscreteValueGroup(self._generator.gcd(other._generator))
        if isinstance(other, DiscreteValueSemigroup):
            return other + self
        from sage.structure.element import is_Element
        if is_Element(other) and QQ.has_coerce_map_from(other.parent()):
            return self + DiscreteValueGroup(other)
        raise ValueError("`other` must be a DiscreteValueGroup or a rational number")
Exemple #6
0
def PolynomialRing(base_ring, arg1=None, arg2=None,
                   sparse=False, order='degrevlex',
                   names=None, name=None,
                   var_array=None,
                   implementation=None):
    r"""
    Return the globally unique univariate or multivariate polynomial
    ring with given properties and variable name or names.

    There are five ways to call the polynomial ring constructor:

    1. ``PolynomialRing(base_ring, name,    sparse=False)``
    2. ``PolynomialRing(base_ring, names,   order='degrevlex')``
    3. ``PolynomialRing(base_ring, name, n, order='degrevlex')``
    4. ``PolynomialRing(base_ring, n, name, order='degrevlex')``
    5. ``PolynomialRing(base_ring, n, var_array=var_array, order='degrevlex')``

    The optional arguments sparse and order *must* be explicitly
    named, and the other arguments must be given positionally.

    INPUT:

    - ``base_ring`` -- a ring
    - ``name`` -- a string
    - ``names`` -- a list or tuple of names, or a comma separated string
    - ``var_array`` -- a list or tuple of names, or a comma separated string
    - ``n`` -- an integer
    - ``sparse`` -- bool (default: False), whether or not elements are sparse
    - ``order`` -- string or
      :class:`~sage.rings.polynomial.term_order.TermOrder` object, e.g.,

      - ``'degrevlex'`` (default) -- degree reverse lexicographic
      - ``'lex'``  -- lexicographic
      - ``'deglex'`` -- degree lexicographic
      - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering

    - ``implementation`` -- string or None; selects an implementation in cases
      where Sage includes multiple choices (currently `\ZZ[x]` can be
      implemented with 'NTL' or 'FLINT'; default is 'FLINT')

    .. NOTE::

        The following rules were introduced in :trac:`9944`, in order
        to preserve the "unique parent assumption" in Sage (i.e., if two
        parents evaluate equal then they should actually be identical).

        - In the multivariate case, a dense representation is not supported.
          Hence, the argument ``sparse=False`` is silently ignored in that case.
        - If the given implementation does not exist for rings with the given
          number of generators and the given sparsity, then an error results.

    OUTPUT:

    ``PolynomialRing(base_ring, name, sparse=False)`` returns a univariate
    polynomial ring; also, PolynomialRing(base_ring, names, sparse=False)
    yields a univariate polynomial ring, if names is a list or tuple
    providing exactly one name. All other input formats return a
    multivariate polynomial ring.

    UNIQUENESS and IMMUTABILITY: In Sage there is exactly one
    single-variate polynomial ring over each base ring in each choice
    of variable, sparseness, and implementation.  There is also exactly
    one multivariate polynomial ring over each base ring for each
    choice of names of variables and term order.  The names of the
    generators can only be temporarily changed after the ring has been
    created.  Do this using the localvars context:

        EXAMPLES of VARIABLE NAME CONTEXT::

            sage: R.<x,y> = PolynomialRing(QQ,2); R
            Multivariate 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.

        However, you can very easily change the names within a ``with`` block::

            sage: with localvars(R, ['z','w']):
            ...     print f
            ...
            z^2 - 2*w^2

        After the ``with`` block the names revert to what they were before.
        ::

            sage: print f
            x^2 - 2*y^2

    SQUARE BRACKETS NOTATION: You can alternatively create a single or
    multivariate polynomial ring over a ring `R` by writing ``R['varname']`` or
    ``R['var1,var2,var3,...']``.  This square brackets notation doesn't allow
    for setting any of the optional arguments.

    EXAMPLES:

    1. ``PolynomialRing(base_ring, name, sparse=False)``

       ::

        sage: PolynomialRing(QQ, 'w')
        Univariate 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> = PolynomialRing(QQ)
        sage: (1 + w)^3
        w^3 + 3*w^2 + 3*w + 1

       You must specify a name::

        sage: PolynomialRing(QQ)
        Traceback (most recent call last):
        ...
        TypeError: You must specify the names of the variables.

        sage: R.<abc> = PolynomialRing(QQ, sparse=True); R
        Sparse Univariate Polynomial Ring in abc over Rational Field

        sage: R.<w> = PolynomialRing(PolynomialRing(GF(7),'k')); R
        Univariate Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7

       The square bracket notation::

        sage: R.<y> = QQ['y']; R
        Univariate Polynomial Ring in y over Rational Field
        sage: y^2 + y
        y^2 + y

       In fact, since the diamond brackets on the left determine the
       variable name, you can omit the variable from the square brackets::

        sage: R.<zz> = QQ[]; R
        Univariate Polynomial Ring in zz over Rational Field
        sage: (zz + 1)^2
        zz^2 + 2*zz + 1

       This is exactly the same ring as what PolynomialRing returns::

        sage: R is PolynomialRing(QQ,'zz')
        True

       However, rings with different variables are different::

        sage: QQ['x'] == QQ['y']
        False

       Sage has two implementations of univariate polynomials over the
       integers, one based on NTL and one based on FLINT.  The default
       is FLINT. Note that FLINT uses a "more dense" representation for
       its polynomials than NTL, so in particular, creating a polynomial
       like 2^1000000 * x^1000000 in FLINT may be unwise.
       ::

        sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL
        Univariate Polynomial Ring in x over Integer Ring (using NTL)
        sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT
        Univariate Polynomial Ring in x over Integer Ring
        sage: ZxFLINT is ZZ['x']
        True
        sage: ZxFLINT is PolynomialRing(ZZ, 'x')
        True
        sage: xNTL = ZxNTL.gen()
        sage: xFLINT = ZxFLINT.gen()
        sage: xNTL.parent()
        Univariate Polynomial Ring in x over Integer Ring (using NTL)
        sage: xFLINT.parent()
        Univariate Polynomial Ring in x over Integer Ring

       There is a coercion from the non-default to the default
       implementation, so the values can be mixed in a single
       expression::

        sage: (xNTL + xFLINT^2)
        x^2 + x

       The result of such an expression will use the default, i.e.,
       the FLINT implementation::

        sage: (xNTL + xFLINT^2).parent()
        Univariate Polynomial Ring in x over Integer Ring

    2. ``PolynomialRing(base_ring, names,   order='degrevlex')``

       ::

        sage: R = PolynomialRing(QQ, 'a,b,c'); R
        Multivariate Polynomial Ring in a, b, c over Rational Field

        sage: S = PolynomialRing(QQ, ['a','b','c']); S
        Multivariate Polynomial Ring in a, b, c over Rational Field

        sage: T = PolynomialRing(QQ, ('a','b','c')); T
        Multivariate 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 polynomial ring with each term order::

        sage: R = PolynomialRing(QQ, 'x,y,z', order='degrevlex'); R
        Multivariate Polynomial Ring in x, y, z over Rational Field
        sage: S = PolynomialRing(QQ, 'x,y,z', order='invlex'); S
        Multivariate Polynomial Ring in x, y, z over Rational Field
        sage: S is PolynomialRing(QQ, 'x,y,z', order='invlex')
        True
        sage: R == S
        False

       Note that a univariate polynomial ring is returned, if the list
       of names is of length one. If it is of length zero, a multivariate
       polynomial ring with no variables is returned.

       ::

        sage: PolynomialRing(QQ,["x"])
        Univariate Polynomial Ring in x over Rational Field
        sage: PolynomialRing(QQ,[])
        Multivariate Polynomial Ring in no variables over Rational Field

    3. ``PolynomialRing(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: PolynomialRing(QQ, 'x', 10)
        Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field

        sage: PolynomialRing(QQ, 2, 'alpha0')
        Multivariate Polynomial Ring in alpha00, alpha01 over Rational Field

        sage: PolynomialRing(GF(7), 'y', 5)
        Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7

        sage: PolynomialRing(QQ, 'y', 3, sparse=True)
        Multivariate Polynomial Ring in y0, y1, y2 over Rational Field

       Note that a multivariate polynomial ring is returned when an
       explicit number is given.

       ::

        sage: PolynomialRing(QQ,"x",1)
        Multivariate Polynomial Ring in x over Rational Field
        sage: PolynomialRing(QQ,"x",0)
        Multivariate Polynomial Ring in no variables over Rational Field

       It is easy in Python to create fairly arbitrary variable names.  For
       example, here is a ring with generators labeled by the first 100
       primes::

        sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R
        Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 over Integer Ring

       By calling the
       :meth:`~sage.structure.category_object.CategoryObject.inject_variables`
       method, all those variable names are available for interactive use::

        sage: R.inject_variables()
        Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97
        sage: (x2 + x41 + x71)^2
        x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2

    5. ``PolynomialRing(base_ring, n, m, var_array=var_array, order='degrevlex')``

       This creates an array of variables where each variables begins with an
       entry in ``var_array`` and is indexed from 0 to ``n-1``.

        sage: PolynomialRing(ZZ, 3, var_array=['x','y'])
        Multivariate Polynomial Ring in x0, y0, x1, y1, x2, y2 over Integer Ring
        sage: PolynomialRing(ZZ, 3, var_array='a,b')
        Multivariate Polynomial Ring in a0, b0, a1, b1, a2, b2 over Integer Ring

       If ``var_array`` is a single string, this creates an `m \times n`
       array of variables::

        sage: PolynomialRing(ZZ, 2, 3, var_array='m')
        Multivariate Polynomial Ring in m00, m01, m02, m10, m11, m12 over Integer Ring

       If ``var_array`` is a single string and `m` is not specified, this
       creates an `n \times n` array of variables::

        sage: PolynomialRing(ZZ, 2, var_array='m')
        Multivariate Polynomial Ring in m00, m01, m10, m11 over Integer Ring

    TESTS:

    We test here some changes introduced in :trac:`9944`.

    If there is no dense implementation for the given number of
    variables, then requesting a dense ring results yields the
    corresponding sparse ring::

        sage: R.<x,y> = QQ[]
        sage: S.<x,y> = PolynomialRing(QQ, sparse=False)
        sage: R is S
        True

    If the requested implementation is not known or not supported for
    the given number of variables and the given sparsity, then an
    error results::

        sage: R.<x> = PolynomialRing(ZZ, implementation='Foo')
        Traceback (most recent call last):
        ...
        ValueError: Unknown implementation Foo for ZZ[x]
        sage: R.<x,y> = PolynomialRing(ZZ, implementation='FLINT')
        Traceback (most recent call last):
        ...
        ValueError: The FLINT implementation is not known for multivariate polynomial rings

    The following corner case used to result in a warning message from
    ``libSingular``, and the generators of the resulting polynomial
    ring were not zero::

        sage: R = Integers(1)['x','y']
        sage: R.0 == 0
        True

    We verify that :trac:`13187` is fixed::

        sage: var('t')
        t
        sage: PolynomialRing(ZZ, name=t) == PolynomialRing(ZZ, name='t')
        True

    We verify that polynomials with interval coefficients from
    :trac:`7712` and :trac:`13760` are fixed::

        sage: P.<y,z> = PolynomialRing(RealIntervalField(2))
        sage: Q.<x> = PolynomialRing(P)
        sage: C = (y-x)^3
        sage: C(y/2)
        1.?*y^3
        sage: R.<x,y> = PolynomialRing(RIF,2)
        sage: RIF(-2,1)*x
        0.?e1*x

    """
    import sage.rings.polynomial.polynomial_ring as m

    if not var_array is None:
        # Make sure arg1 always corresponds to n and arg2 to m
        if arg2 is not None:
            arg1, arg2 = arg2, arg1
        if isinstance(var_array, str):
            if not ',' in var_array:
                if arg2 is None:
                    arg2 = arg1
                arg1 = ['%s%s%s'%(var_array, i, j) for i in range(arg2) for j in range(arg1)]
            else:
                var_array = var_array.split(',')
                if arg2 is not None and len(var_array) != arg2:
                    raise IndexError('the number of names must equal the number of base generators')
                arg1 = ['%s%s'%(x, i) for i in range(arg1) for x in var_array]
        elif isinstance(var_array, (list,tuple)):
            if arg2 is not None and len(var_array) != arg2:
                raise IndexError('the number of names must equal the number of base generators')
            arg1 = ['%s%s'%(x, i) for i in range(arg1) for x in var_array]
        else:
            raise TypeError("invalid input to PolynomialRing function; please see the docstring for that function")
        arg2 = len(arg1)
    else:
        if isinstance(arg1, (int, long, Integer)):
            arg1, arg2 = arg2, arg1
        if not names is None:
            arg1 = names
        elif not name is None:
            arg1 = name

    if is_Element(arg1) and not isinstance(arg1, (int, long, Integer)):
        arg1 = repr(arg1)
    if is_Element(arg2) and not isinstance(arg2, (int, long, Integer)):
        arg2 = repr(arg2)

    if not m.ring.is_Ring(base_ring):
        raise TypeError('base_ring must be a ring')

    if arg1 is None:
        raise TypeError("You must specify the names of the variables.")

    R = None
    if isinstance(arg1, (list, tuple)):
        arg1 = [str(x) for x in arg1]
    if isinstance(arg2, (list, tuple)):
        arg2 = [str(x) for x in arg2]
    if isinstance(arg2, (int, long, Integer)):
        # 3. PolynomialRing(base_ring, names, n, order='degrevlex'):
        if not isinstance(arg1, (list, tuple, str)):
            raise TypeError("You *must* specify the names of the variables.")
        n = int(arg2)
        names = arg1
        R = _multi_variate(base_ring, names, n, sparse, order, implementation)

    elif isinstance(arg1, str) or (isinstance(arg1, (list,tuple)) and len(arg1) == 1):
        if not ',' in arg1:
            # 1. PolynomialRing(base_ring, name, sparse=False):
            if not arg2 is None:
                raise TypeError("if second arguments is a string with no commas, then there must be no other non-optional arguments")
            name = arg1
            R = _single_variate(base_ring, name, sparse, implementation)
        else:
            # 2-4. PolynomialRing(base_ring, names, order='degrevlex'):
            if not arg2 is None:
                raise TypeError("invalid input to PolynomialRing function; please see the docstring for that function")
            names = arg1.split(',')
            R = _multi_variate(base_ring, names, -1, sparse, order, implementation)
    elif isinstance(arg1, (list, tuple)):
            # PolynomialRing(base_ring, names (list or tuple), order='degrevlex'):
            names = arg1
            R = _multi_variate(base_ring, names, -1, sparse, order, implementation)

    if arg1 is None and arg2 is None:
        raise TypeError("you *must* specify the indeterminates (as not None).")
    if R is None:
        raise TypeError("invalid input (%s, %s, %s) to PolynomialRing function; please see the docstring for that function"%(
            base_ring, arg1, arg2))

    return R
def LaurentPolynomialRing(base_ring,
                          arg1=None,
                          arg2=None,
                          sparse=False,
                          order='degrevlex',
                          names=None,
                          name=None):
    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
    """
    if is_Element(arg1) and not isinstance(arg1, integer_types + (Integer, )):
        arg1 = repr(arg1)
    if is_Element(arg2) and not isinstance(arg2, integer_types + (Integer, )):
        arg2 = repr(arg2)

    if isinstance(arg1, integer_types + (Integer, )):
        arg1, arg2 = arg2, arg1

    if not names is None:
        arg1 = names
    elif not name is None:
        arg1 = name

    if not is_Ring(base_ring):
        raise TypeError('base_ring must be a ring')

    if arg1 is None:
        raise TypeError("You must specify the names of the variables.")

    R = None
    if isinstance(arg1, (list, tuple)):
        arg1 = [str(x) for x in arg1]
    if isinstance(arg2, (list, tuple)):
        arg2 = [str(x) for x in arg2]
    if isinstance(arg2, integer_types + (Integer, )):
        # 3. LaurentPolynomialRing(base_ring, names, n, order='degrevlex'):
        if not isinstance(arg1, (list, tuple, str)):
            raise TypeError("You *must* specify the names of the variables.")
        n = int(arg2)
        names = arg1
        R = _multi_variate(base_ring, names, n, sparse, order)

    elif isinstance(arg1,
                    str) or (isinstance(arg1, (list, tuple))
                             and len(arg1) == 1) and isinstance(arg1[0], str):
        if isinstance(arg1, (list, tuple)):
            arg1 = arg1[0]
        if not ',' in arg1:
            # 1. LaurentPolynomialRing(base_ring, name, sparse=False):
            if not arg2 is None:
                raise TypeError(
                    "if second arguments is a string with no commas, then there must be no other non-optional arguments"
                )
            name = arg1
            R = _single_variate(base_ring, name, sparse)
        else:
            # 2-4. LaurentPolynomialRing(base_ring, names, order='degrevlex'):
            if not arg2 is None:
                raise TypeError(
                    "invalid input to LaurentPolynomialRing function; please see the docstring for that function"
                )
            names = arg1.split(',')
            n = len(names)
            R = _multi_variate(base_ring, names, n, sparse, order)
    elif isinstance(arg1, (list, tuple)):
        # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'):
        names = arg1
        n = len(names)
        R = _multi_variate(base_ring, names, n, sparse, order)

    if arg1 is None and arg2 is None:
        raise TypeError("you *must* specify the indeterminates (as not None).")
    if R is None:
        raise TypeError(
            "invalid input (%s, %s, %s) to PolynomialRing function; please see the docstring for that function"
            % (base_ring, arg1, arg2))

    return R
def LaurentPolynomialRing(base_ring, arg1=None, arg2=None, sparse = False, order='degrevlex', names = None, name=None):
    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
    """
    if is_Element(arg1) and not isinstance(arg1, (int, long, Integer)):
        arg1 = repr(arg1)
    if is_Element(arg2) and not isinstance(arg2, (int, long, Integer)):
        arg2 = repr(arg2)

    if isinstance(arg1, (int, long, Integer)):
        arg1, arg2 = arg2, arg1

    if not names is None:
        arg1 = names
    elif not name is None:
        arg1 = name

    if not is_Ring(base_ring):
        raise TypeError('base_ring must be a ring')

    if arg1 is None:
        raise TypeError("You must specify the names of the variables.")

    R = None
    if isinstance(arg1, (list, tuple)):
        arg1 = [str(x) for x in arg1]
    if isinstance(arg2, (list, tuple)):
        arg2 = [str(x) for x in arg2]
    if isinstance(arg2, (int, long, Integer)):
        # 3. LaurentPolynomialRing(base_ring, names, n, order='degrevlex'):
        if not isinstance(arg1, (list, tuple, str)):
            raise TypeError("You *must* specify the names of the variables.")
        n = int(arg2)
        names = arg1
        R = _multi_variate(base_ring, names, n, sparse, order)

    elif isinstance(arg1, str) or (isinstance(arg1, (list,tuple)) and len(arg1) == 1) and isinstance(arg1[0], str):
        if isinstance(arg1, (list,tuple)):
            arg1 = arg1[0]
        if not ',' in arg1:
            # 1. LaurentPolynomialRing(base_ring, name, sparse=False):
            if not arg2 is None:
                raise TypeError("if second arguments is a string with no commas, then there must be no other non-optional arguments")
            name = arg1
            R = _single_variate(base_ring, name, sparse)
        else:
            # 2-4. LaurentPolynomialRing(base_ring, names, order='degrevlex'):
            if not arg2 is None:
                raise TypeError("invalid input to LaurentPolynomialRing function; please see the docstring for that function")
            names = arg1.split(',')
            n = len(names)
            R = _multi_variate(base_ring, names, n, sparse, order)
    elif isinstance(arg1, (list, tuple)):
        # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'):
        names = arg1
        n = len(names)
        R = _multi_variate(base_ring, names, n, sparse, order)

    if arg1 is None and arg2 is None:
        raise TypeError("you *must* specify the indeterminates (as not None).")
    if R is None:
        raise TypeError("invalid input (%s, %s, %s) to PolynomialRing function; please see the docstring for that function"%(base_ring, arg1, arg2))

    return R