예제 #1
0
def eliminate(polys, elim_variables, **kwds):
    r"""
    Compute a Groebner basis with respect to an elimination order defined by
    the given variables.

    INPUT:

    - ``polys`` -- an ideal or a polynomial sequence.

    - ``elim_variables`` -- the variables to eliminate.

    - ``force_elim`` -- integer (default: `1`).

    - ``kwds`` -- same as in :func:`groebner_basis`.

    OUTPUT: a Groebner basis of the elimination ideal.

    EXAMPLES::

        sage: R.<x,y,t,s,z> = PolynomialRing(QQ,5)
        sage: I = R * [x-t,y-t^2,z-t^3,s-x+y^3]
        sage: import fgb_sage                                # optional - fgb_sage
        sage: gb = fgb_sage.eliminate(I, [t,s], verbosity=0) # optional - fgb_sage, random
        open simulation
        sage: gb                                             # optional - fgb_sage
        [x^2 - y, x*y - z, y^2 - x*z]
        sage: gb.is_groebner()                               # optional - fgb_sage
        True
        sage: gb.ideal() == I.elimination_ideal([t,s])       # optional - fgb_sage
        True

    .. NOTE::

        In some cases, this function fails to set the correct elimination
        order, see :trac:`24981`. This was fixed in Sage 8.7.
    """
    kwds.setdefault('force_elim', 1)
    polyseq = PolynomialSequence(polys)
    ring = polyseq.ring()
    elim_variables = set(elim_variables)
    block1 = [x for x in ring.gens() if x in elim_variables]
    block2 = [x for x in ring.gens() if x not in elim_variables]
    from sage.rings.polynomial.term_order import TermOrder
    if len(block1) == 0 or len(block2) == 0:
        t = TermOrder("degrevlex", ring.ngens())
    else:
        t = TermOrder("degrevlex", len(block1)) + TermOrder(
            "degrevlex", len(block2))
    if t == ring.term_order() and set(
            ring.gens()[:len(block1)]) == elim_variables:
        return groebner_basis(polyseq, **kwds)
    else:
        block_ring = ring.change_ring(names=block1 + block2, order=t)
        gb = groebner_basis(PolynomialSequence(block_ring, polyseq), **kwds)
        return PolynomialSequence(ring, gb, immutable=True)
예제 #2
0
 def __init__(self, base_ring, n, names, order):
     from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
     order = TermOrder(order, n)
     MPolynomialRing_generic.__init__(self, base_ring, n, names, order)
     # Construct the generators
     v = [0 for _ in xrange(n)]
     one = base_ring(1)
     self._gens = []
     C = self._poly_class()
     for i in xrange(n):
         v[i] = 1  # int's!
         self._gens.append(C(self, {tuple(v): one}))
         v[i] = 0
     self._gens = tuple(self._gens)
     self._zero_tuple = tuple(v)
     self._has_singular = can_convert_to_singular(self)
     # This polynomial ring should belong to Algebras(base_ring).
     # Algebras(...).parent_class, which was called from MPolynomialRing_generic.__init__,
     # tries to provide a conversion from the base ring, if it does not exist.
     # This is for algebras that only do the generic stuff in their initialisation.
     # But here, we want to use PolynomialBaseringInjection. Hence, we need to
     # wipe the memory and construct the conversion from scratch.
     if n:
         from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection
         base_inject = PolynomialBaseringInjection(base_ring, self)
         self.register_coercion(base_inject)
예제 #3
0
def _multi_variate(base_ring, names, n, sparse, order, implementation):
    #    if not sparse:
    #        raise ValueError, "A dense representation of multivariate polynomials is not supported"
    sparse = False
    # "True" would be correct, since there is no dense implementation of
    # multivariate polynomials. However, traditionally, "False" is used in the key,
    # even though it is meaningless.

    if implementation is not None:
        raise ValueError(
            "The %s implementation is not known for multivariate polynomial rings"
            % implementation)

    names = normalize_names(n, names)
    n = len(names)

    import sage.rings.polynomial.multi_polynomial_ring as m
    from sage.rings.polynomial.term_order import TermOrder

    order = TermOrder(order, n)

    key = (base_ring, names, n, sparse, order)
    R = _get_from_cache(key)
    if not R is None:
        return R

    from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
    if isinstance(base_ring, ring.IntegralDomain):
        if n < 1:
            R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order)
        else:
            try:
                R = MPolynomialRing_libsingular(base_ring, n, names, order)
            except (TypeError, NotImplementedError):
                R = m.MPolynomialRing_polydict_domain(base_ring, n, names,
                                                      order)
    else:
        if not base_ring.is_zero():
            try:
                R = MPolynomialRing_libsingular(base_ring, n, names, order)
            except (TypeError, NotImplementedError):
                R = m.MPolynomialRing_polydict(base_ring, n, names, order)
        else:
            R = m.MPolynomialRing_polydict(base_ring, n, names, order)
    _save_in_cache(key, R)
    return R
예제 #4
0
    def polynomial_ring(self, names, gens=None):
        r"""
        Return a polynomial ring of which ``self`` is a quotient.

        INPUT:

        - ``names`` -- a list or tuple of names (strings), or a comma separated string
        - ``gens`` (default: None) -- (list) a list of generator of ``self``. If ``gens`` is
          ``None`` then the generators returned by :meth:`~sage.modular.modform.find_generator.ModularFormsRing.gen_forms`
          is used instead.

        OUTPUT: A multivariate polynomial ring in the variable ``names``. Each variable of the
        polynomial ring correspond to a generator given in gens (following the ordering of the list).

        EXAMPLES::

            sage: M = ModularFormsRing(1)
            sage: gens = M.gen_forms()
            sage: M.polynomial_ring('E4, E6', gens)
            Multivariate Polynomial Ring in E4, E6 over Rational Field
            sage: M = ModularFormsRing(Gamma0(8))
            sage: gens = M.gen_forms()
            sage: M.polynomial_ring('g', gens)
            Multivariate Polynomial Ring in g0, g1, g2 over Rational Field

        The degrees of the variables are the weights of the corresponding forms::

            sage: M = ModularFormsRing(1)
            sage: P.<E4, E6> = M.polynomial_ring()
            sage: E4.degree()
            4
            sage: E6.degree()
            6
            sage: (E4*E6).degree()
            10
        """
        if gens is None:
            gens = self.gen_forms()
        degs = [f.weight() for f in gens]
        return PolynomialRing(
            self.base_ring(),
            len(gens),
            names,
            order=TermOrder(
                'wdeglex',
                degs))  # Should we remove the deg lexicographic ordering here?
예제 #5
0
    def __classcall__(cls, base_ring, num_gens, name_list,
                 order='negdeglex', default_prec=10, sparse=False):
        """
        Preprocessing of arguments: The term order can be given as string
        or as a :class:`~sage.rings.polynomial.term_order.TermOrder` instance.

        TESTS::

            sage: P1 = PowerSeriesRing(QQ, ['f0','f1','f2','f3'], order = TermOrder('degrevlex'))
            sage: P2 = PowerSeriesRing(QQ,4,'f', order='degrevlex')
            sage: P1 is P2   # indirect doctest
            True

        """
        order = TermOrder(order,num_gens)
        return super(MPowerSeriesRing_generic,cls).__classcall__(cls, base_ring, num_gens, name_list,
                 order, default_prec, sparse)
예제 #6
0
def _multi_variate(base_ring,
                   names,
                   sparse=None,
                   order="degrevlex",
                   implementation=None):
    #    if not sparse:
    #        raise ValueError("a dense representation of multivariate polynomials is not supported")
    sparse = False

    if implementation is None:
        force_singular = False
    elif implementation == "singular":
        force_singular = True
    else:
        raise ValueError(
            "unknown implementation %r for multivariate polynomial rings" %
            (implementation, ))

    n = len(names)

    from sage.rings.polynomial.term_order import TermOrder
    order = TermOrder(order, n)

    key = (base_ring, names, n, sparse, order)
    R = _get_from_cache(key)
    if not R is None:
        return R

    from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
    try:
        R = MPolynomialRing_libsingular(base_ring, n, names, order)
    except (TypeError, NotImplementedError):
        if force_singular:
            raise
        import sage.rings.polynomial.multi_polynomial_ring as m
        if isinstance(base_ring, ring.IntegralDomain):
            R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order)
        else:
            R = m.MPolynomialRing_polydict(base_ring, n, names, order)

    _save_in_cache(key, R)
    return R
 def __init__(self, base_ring, n, names, order):
     from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
     order = TermOrder(order, n)
     # MPolynomialRing_base.__init__() normally initialises the base ring,
     # but it also needs the generators to construct a coercion map from the
     # base ring, and the base ring must be set to initialise the generators.
     # We set the base ring manually to break this circular dependency.
     self._base = base_ring
     # Construct the generators
     v = [0] * n
     one = base_ring.one()
     self._gens = []
     for i in range(n):
         v[i] = 1  # int's!
         self._gens.append(self.Element_hidden(self, {tuple(v): one}))
         v[i] = 0
     self._gens = tuple(self._gens)
     self._zero_tuple = tuple(v)
     MPolynomialRing_base.__init__(self, base_ring, n, names, order)
     self._has_singular = can_convert_to_singular(self)
예제 #8
0
    def polynomial_ring(self, names='E2, E4, E6'):
        r"""
        Return a multivariate polynomial ring isomorphic to the given graded
        quasimodular forms ring.

        In the case of the full modular group, this
        ring is `R[E_2, E_4, E_6]` where `E_2`, `E_4` and `E_6` have degrees 2,
        4 and 6 respectively.

        INPUT:

        - ``names`` (str, default: ``'E2, E4, E6'``) -- a list or tuple of names
          (strings), or a comma separated string. Correspond to the names of the
          variables.

        OUTPUT: A multivariate polynomial ring in the variables ``names``

        EXAMPLES:

            sage: QM = QuasiModularForms(1)
            sage: P.<E2, E4, E6> = QM.polynomial_ring(); P
            Multivariate Polynomial Ring in E2, E4, E6 over Rational Field
            sage: E2.degree()
            2
            sage: E4.degree()
            4
            sage: E6.degree()
            6
            sage: P.<x, y, z, w> = QQ[]
            sage: QM.from_polynomial(x+y+z+w)
            Traceback (most recent call last):
            ...
            ValueError: the number of variables (4) of the given polynomial cannot exceed the number of generators (3) of the quasimodular forms ring
        """
        return PolynomialRing(
            self.base_ring(),
            3,
            names,
            order=TermOrder('wdeglex', [ZZ(2), ZZ(4), ZZ(6)]))
예제 #9
0
    def __init__(self,
                 base_ring,
                 num_gens,
                 name_list,
                 order='negdeglex',
                 default_prec=10,
                 sparse=False):
        """
        Initializes a multivariate power series ring.  See PowerSeriesRing
        for complete documentation.

        INPUT

            - ``base_ring`` - a commutative ring

            - ``num_gens`` - number of generators

            - ``name_list`` - List of indeterminate names or a single name.
                If a single name is given, indeterminates will be this name
                followed by a number from 0 to num_gens - 1.  If a list is
                given, these will be the indeterminate names and the length
                of the list must be equal to num_gens.

            - ``order`` - ordering of variables; default is
              negative degree lexicographic

            - ``default_prec`` - The default total-degree precision for
              elements.  The default value of default_prec is 10.

            - ``sparse`` - whether or not power series are sparse

        EXAMPLES::

            sage: R.<t,u,v> = PowerSeriesRing(QQ)
            sage: g = 1 + v + 3*u*t^2 - 2*v^2*t^2
            sage: g = g.add_bigoh(5); g
            1 + v + 3*t^2*u - 2*t^2*v^2 + O(t, u, v)^5
            sage: g in R
            True

        TESTS:

        By :trac:`14084`, the multi-variate power series ring belongs to the
        category of integral domains, if the base ring does::

            sage: P = ZZ[['x','y']]
            sage: P.category()
            Category of integral domains
            sage: TestSuite(P).run()

        Otherwise, it belongs to the category of commutative rings::

            sage: P = Integers(15)[['x','y']]
            sage: P.category()
            Category of commutative rings
            sage: TestSuite(P).run()

        """
        order = TermOrder(order, num_gens)
        self._term_order = order
        if not base_ring.is_commutative():
            raise TypeError("Base ring must be a commutative ring.")
        n = int(num_gens)
        if n < 0:
            raise ValueError(
                "Multivariate Polynomial Rings must have more than 0 variables."
            )
        self._ngens = n
        self._has_singular = False  #cannot convert to Singular by default
        # Multivariate power series rings inherit from power series rings. But
        # apparently we can not call their initialisation. Instead, initialise
        # CommutativeRing and Nonexact:
        CommutativeRing.__init__(self,
                                 base_ring,
                                 name_list,
                                 category=_IntegralDomains if base_ring
                                 in _IntegralDomains else _CommutativeRings)
        Nonexact.__init__(self, default_prec)

        # underlying polynomial ring in which to represent elements
        self._poly_ring_ = PolynomialRing(base_ring,
                                          self.variable_names(),
                                          sparse=sparse,
                                          order=order)
        # because sometimes PowerSeriesRing_generic calls self.__poly_ring
        self._PowerSeriesRing_generic__poly_ring = self._poly_ring()

        # background univariate power series ring
        self._bg_power_series_ring = PowerSeriesRing(self._poly_ring_,
                                                     'Tbg',
                                                     sparse=sparse,
                                                     default_prec=default_prec)
        self._bg_indeterminate = self._bg_power_series_ring.gen()

        self._is_sparse = sparse
        self._params = (base_ring, num_gens, name_list, order, default_prec,
                        sparse)
        self._populate_coercion_lists_()
예제 #10
0
def BooleanPolynomialRing_constructor(n=None, names=None, order="lex"):
    """
    Construct a boolean polynomial ring with the following
    parameters:

    INPUT:

    - ``n`` -- number of variables (an integer > 1)
    - ``names`` -- names of ring variables, may be a string or list/tuple of strings
    - ``order`` -- term order (default: lex)

    EXAMPLES::

        sage: R.<x, y, z> = BooleanPolynomialRing() # indirect doctest
        sage: R
        Boolean PolynomialRing in x, y, z

        sage: p = x*y + x*z + y*z
        sage: x*p
        x*y*z + x*y + x*z

        sage: R.term_order()
        Lexicographic term order

        sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)')
        sage: R.term_order()
        Block term order with blocks:
        (Degree lexicographic term order of length 3,
         Degree lexicographic term order of length 2)

        sage: R = BooleanPolynomialRing(3,'x',order='degneglex')
        sage: R.term_order()
        Degree negative lexicographic term order

        sage: BooleanPolynomialRing(names=('x','y'))
        Boolean PolynomialRing in x, y

        sage: BooleanPolynomialRing(names='x,y')
        Boolean PolynomialRing in x, y

    TESTS::

        sage: P.<x,y> = BooleanPolynomialRing(2,order='deglex')
        sage: x > y
        True

        sage: P.<x0, x1, x2, x3> = BooleanPolynomialRing(4,order='deglex(2),deglex(2)')
        sage: x0 > x1
        True
        sage: x2 > x3
        True
    """

    if isinstance(n, str):
        names = n
        n = -1
    elif n is None:
        n = -1

    names = normalize_names(n, names)
    n = len(names)

    from sage.rings.polynomial.term_order import TermOrder

    order = TermOrder(order, n)

    key = ("pbori", names, n, order)
    R = _get_from_cache(key)
    if not R is None:
        return R

    from sage.rings.polynomial.pbori import BooleanPolynomialRing
    R = BooleanPolynomialRing(n, names, order)

    _save_in_cache(key, R)
    return R
예제 #11
0
    def create_key(self,
                   base,
                   prec=None,
                   log_radii=ZZ(0),
                   names=None,
                   order='degrevlex'):
        """
        Create a key from the input paramaters.

        INPUT:

        - ``base`` -- a `p`-adic ring or field

        - ``prec`` -- an integer or ``None`` (default: ``None``)

        - ``log_radii`` -- an integer or a list or a tuple of integers 
          (default: ``0``)

        - ``names`` -- names of the indeterminates

        - ``order`` - a monomial ordering (default: ``degrevlex``)

        EXAMPLES::

            sage: TateAlgebra.create_key(Zp(2), names=['x','y'])
            (2-adic Field with capped relative precision 20,
             20,
             (0, 0),
             ('x', 'y'),
             Degree reverse lexicographic term order)

        TESTS::

            sage: TateAlgebra.create_key(Zp(2))
            Traceback (most recent call last):
            ...
            ValueError: you must specify the names of the variables
            sage: TateAlgebra.create_key(ZZ)
            Traceback (most recent call last):
            ...
            TypeError: the base ring must be a p-adic ring or a p-adic field
            sage: TateAlgebra.create_key(Zp(2), names=['x','y'], log_radii=[1])
            Traceback (most recent call last):
            ...
            ValueError: the number of radii does not match the number of variables
            sage: TateAlgebra.create_key(Zp(2), names=['x','y'], log_radii=[0, 1/2])
            Traceback (most recent call last):
            ...
            NotImplementedError: only integral log_radii are implemented
            sage: TateAlgebra.create_key(Zp(2), names=['x','y'], order='myorder')
            Traceback (most recent call last):
            ...
            ValueError: unknown term order 'myorder'

        """
        if not isinstance(base, pAdicGeneric):
            raise TypeError(
                "the base ring must be a p-adic ring or a p-adic field")
        # TODO: allow for arbitrary CDVF
        base = base.fraction_field()
        if names is None:
            raise ValueError("you must specify the names of the variables")
        names = normalize_names(-1, names)
        ngens = len(names)
        if not isinstance(log_radii, (list, tuple)):
            try:
                log_radii = [ZZ(log_radii)] * ngens
            except TypeError:
                raise NotImplementedError(
                    "only integral log_radii are implemented")
        elif len(log_radii) != ngens:
            raise ValueError(
                "the number of radii does not match the number of variables")
        else:
            try:
                log_radii = [ZZ(r) for r in log_radii]
            except TypeError:
                raise NotImplementedError(
                    "only integral log_radii are implemented")
        order = TermOrder(order, ngens)
        if prec is None:
            prec = base.precision_cap()
        key = (base, prec, tuple(log_radii), names, order)
        return key
예제 #12
0
def _multi_variate(base_ring,
                   names,
                   sparse=None,
                   order="degrevlex",
                   implementation=None):
    if sparse is None:
        sparse = True
    if not sparse:
        raise NotImplementedError(
            "a dense representation of multivariate polynomials is not supported"
        )

    from sage.rings.polynomial.term_order import TermOrder
    n = len(names)
    order = TermOrder(order, n)

    # "implementation" must be last
    key = [base_ring, names, n, order, implementation]
    R = _get_from_cache(key)
    if R is not None:
        return R

    # Multiple arguments for the "implementation" keyword which actually
    # yield the same implementation. We need this for caching.
    implementation_names = set([implementation])

    if implementation is None or implementation == "singular":
        from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
        try:
            R = MPolynomialRing_libsingular(base_ring, n, names, order)
        except (TypeError, NotImplementedError):
            if implementation is not None:
                raise
        else:
            implementation_names.update([None, "singular"])

    if R is None and implementation is None:
        # Interpret implementation=None as implementation="generic"
        implementation = "generic"
        implementation_names.add(implementation)
        key[-1] = implementation
        R = _get_from_cache(key)

    if R is None and implementation == "generic":
        from . import multi_polynomial_ring
        if isinstance(base_ring, ring.IntegralDomain):
            constructor = multi_polynomial_ring.MPolynomialRing_polydict_domain
        else:
            constructor = multi_polynomial_ring.MPolynomialRing_polydict
        R = constructor(base_ring, n, names, order)

    if R is None:
        raise ValueError(
            "unknown implementation %r for multivariate polynomial rings" %
            (implementation, ))

    for impl in implementation_names:
        key[-1] = impl
        _save_in_cache(key, R)

    return R
예제 #13
0
 def __init__(self, base_ring, n, names, order):
     order = TermOrder(order, n)
     MPolynomialRing_polydict.__init__(self, base_ring, n, names, order)
예제 #14
0
    def __init__(self,
                 base_ring,
                 num_gens,
                 name_list,
                 order='negdeglex',
                 default_prec=10,
                 sparse=False):
        """
        Initializes a multivariate power series ring.  See PowerSeriesRing
        for complete documentation.

        INPUT

            - ``base_ring`` - a commutative ring

            - ``num_gens`` - number of generators
        
            - ``name_list`` - List of indeterminate names or a single name.
                If a single name is given, indeterminates will be this name
                followed by a number from 0 to num_gens - 1.  If a list is
                given, these will be the indeterminate names and the length
                of the list must be equal to num_gens.

            - ``order`` - ordering of variables; default is
              negative degree lexicographic
            
            - ``default_prec`` - The default total-degree precision for
              elements.  The default value of default_prec is 10.
            
            - ``sparse`` - whether or not power series are sparse

        EXAMPLES::

                sage: R.<t,u,v> = PowerSeriesRing(QQ)
                sage: g = 1 + v + 3*u*t^2 - 2*v^2*t^2
                sage: g = g.add_bigoh(5); g
                1 + v + 3*t^2*u - 2*t^2*v^2 + O(t, u, v)^5
                sage: g in R
                True
        """
        order = TermOrder(order, num_gens)
        self._term_order = order
        if not base_ring.is_commutative():
            raise TypeError("Base ring must be a commutative ring.")
        n = int(num_gens)
        if n < 0:
            raise ValueError(
                "Multivariate Polynomial Rings must have more than 0 variables."
            )
        self._ngens = n
        self._has_singular = False  #cannot convert to Singular by default
        ParentWithGens.__init__(self, base_ring, name_list)
        Nonexact.__init__(self, default_prec)

        # underlying polynomial ring in which to represent elements
        self._poly_ring_ = PolynomialRing(base_ring,
                                          self.variable_names(),
                                          sparse=sparse,
                                          order=order)
        # because sometimes PowerSeriesRing_generic calls self.__poly_ring
        self._PowerSeriesRing_generic__poly_ring = self._poly_ring()

        # background univariate power series ring
        self._bg_power_series_ring = PowerSeriesRing(self._poly_ring_,
                                                     'Tbg',
                                                     sparse=sparse,
                                                     default_prec=default_prec)
        self._bg_indeterminate = self._bg_power_series_ring.gen()

        ## use the following in PowerSeriesRing_generic.__call__
        self._PowerSeriesRing_generic__power_series_class = MPowerSeries

        self._is_sparse = sparse
        self._params = (base_ring, num_gens, name_list, order, default_prec,
                        sparse)
        self._populate_coercion_lists_()