Beispiel #1
0
    def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=False):
        """
        Apply permutations to the generators of self and interreduce

        INPUT:

        - ``N`` -- (integer, default ``None``) Apply permutations in
          `Sym(N)`. If it is not given then it will be replaced by the
          maximal variable index occurring in the generators of
          ``self.interreduction().squeezed()``.
        - ``tailreduce`` -- (bool, default ``False``) If ``True``, perform
          tail reductions.
        - ``report`` -- (object, default ``None``) If not ``None``, report
          on the progress of computations.
        - ``use_full_group`` (optional) -- If True, apply *all* elements of
          `Sym(N)` to the generators of self (this is what [AB2008]_
          originally suggests). The default is to apply all elementary
          transpositions to the generators of ``self.squeezed()``,
          interreduce, and repeat until the result stabilises, which is
          often much faster than applying all of `Sym(N)`, and we are
          convinced that both methods yield the same result.

        OUTPUT:

        A symmetrically interreduced symmetric ideal with respect to
        which any `Sym(N)`-translate of a generator of self is
        symmetrically reducible, where by default ``N`` is the maximal
        variable index that occurs in the generators of
        ``self.interreduction().squeezed()``.

        NOTE:

        If ``I`` is a symmetric ideal whose generators are monomials,
        then ``I.symmetrisation()`` is its reduced Groebner basis.  It
        should be noted that without symmetrisation, monomial
        generators, in general, do not form a Groebner basis.

        EXAMPLES::

            sage: X.<x> = InfinitePolynomialRing(QQ)
            sage: I = X*(x[1]+x[2], x[1]*x[2])
            sage: I.symmetrisation()
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field
            sage: I.symmetrisation(N=3)
            Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field
            sage: I.symmetrisation(N=3, use_full_group=True)
            Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field

        """
        newOUT = self.interreduction(tailreduce=tailreduce, report=report).squeezed()
        R = self.ring()
        OUT = R*()
        if N is None:
            N = max([Y.max_index() for Y in newOUT.gens()]+[1])
        else:
            N = Integer(N)
        if hasattr(R,'_max') and R._max<N:
            R.gen()[N]
        if report is not None:
            print "Symmetrise %d polynomials at level %d"%(len(newOUT.gens()),N)
        if use_full_group:
            from sage.combinat.permutation import Permutations
            NewGens = []
            Gens = self.gens()
            for P in Permutations(N):
                NewGens.extend([p**P for p in Gens])
            return (NewGens * R).interreduction(tailreduce=tailreduce,report=report)
        from sage.combinat.permutation import Permutation
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        RStrat = SymmetricReductionStrategy(self.ring(),OUT.gens(),tailreduce=tailreduce)
        while (OUT!=newOUT):
            OUT = newOUT
            PermutedGens = list(OUT.gens())
            if not (report is None):
                print "Apply permutations"
            for i in range(1,N):
                for j in range(i+1,N+1):
                    P = Permutation(((i,j)))
                    for X in OUT.gens():
                        p = RStrat.reduce(X**P,report=report)
                        if p._p !=0:
                            PermutedGens.append(p)
                            RStrat.add_generator(p,good_input=True)
            newOUT = (PermutedGens * R).interreduction(tailreduce=tailreduce,report=report)
        return OUT
Beispiel #2
0
    def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None):
        """
        Return symmetrically interreduced form of self

        INPUT:

        - ``tailreduce`` -- (bool, default ``True``) If True, the
          interreduction is also performed on the non-leading monomials.
        - ``sorted`` -- (bool, default ``False``) If True, it is assumed that the
          generators of self are already increasingly sorted.
        - ``report`` -- (object, default ``None``) If not None, some information on the
          progress of computation is printed
        - ``RStrat`` -- (:class:`~sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy`,
          default ``None``) A reduction strategy to which the polynomials resulting
          from the interreduction will be added. If ``RStrat`` already contains some
          polynomials, they will be used in the interreduction. The effect is to
          compute in a quotient ring.

        OUTPUT:

        A Symmetric Ideal J (sorted list of generators) coinciding
        with self as an ideal, so that any generator is symmetrically
        reduced w.r.t. the other generators. Note that the leading
        coefficients of the result are not necessarily 1.

        EXAMPLES::

            sage: X.<x> = InfinitePolynomialRing(QQ)
            sage: I=X*(x[1]+x[2],x[1]*x[2])
            sage: I.interreduction()
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        Here, we show the ``report`` option::

            sage: I.interreduction(report=True)
            Symmetric interreduction
            [1/2]  >
            [2/2] :>
            [1/2]  >
            [2/2] T[1]>
            >
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        ``[m/n]`` indicates that polynomial number ``m`` is considered
        and the total number of polynomials under consideration is
        ``n``. '-> 0' is printed if a zero reduction occurred. The
        rest of the report is as described in
        :meth:`sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy.reduce`.

        Last, we demonstrate the use of the optional parameter ``RStrat``::

            sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
            sage: R = SymmetricReductionStrategy(X)
            sage: R
            Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field
            sage: I.interreduction(RStrat=R)
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field
            sage: R
            Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field, modulo
                x_1^2,
                x_2 + x_1
            sage: R = SymmetricReductionStrategy(X,[x[1]^2])
            sage: I.interreduction(RStrat=R)
            Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        """
        DONE = []
        j = 0
        TODO = []
        PARENT = self.ring()
        for P in self.gens():
            if P._p!=0:
                if P.is_unit(): # self generates all of self.ring()
                    if RStrat is not None:
                        RStrat.add_generator(PARENT(1))
                    return SymmetricIdeal(self.ring(),[self.ring()(1)], coerce=False)
                TODO.append(P)
        if not sorted:
            TODO = list(set(TODO))
            TODO.sort()
        if hasattr(PARENT,'_P'):
            CommonR = PARENT._P
        else:
            VarList = set([])
            for P in TODO:
                if P._p!=0:
                    if P.is_unit(): # self generates all of PARENT
                        if RStrat is not None:
                            RStrat.add_generator(PARENT(1))
                        return SymmetricIdeal(PARENT,[PARENT(1)], coerce=False)
                    VarList = VarList.union(P._p.parent().variable_names())
            VarList = list(VarList)
            if not VarList:
                return SymmetricIdeal(PARENT,[0])
            VarList.sort(cmp=PARENT.varname_cmp, reverse=True)
            from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
            CommonR = PolynomialRing(self.base_ring(), VarList, order=self.ring()._order)

        ## Now, the symmetric interreduction starts
        if not (report is None):
            print 'Symmetric interreduction'
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        if RStrat is None:
            RStrat = SymmetricReductionStrategy(self.ring(),tailreduce=tailreduce)
        GroundState = RStrat.gens()
        while (1):
            RStrat.setgens(GroundState)
            DONE = []
            for i in range(len(TODO)):
                if (not (report is None)):
                    print '[%d/%d] '%(i+1,len(TODO)),
                    sys.stdout.flush()
                p = RStrat.reduce(TODO[i], report=report)
                if p._p != 0:
                    if p.is_unit(): # self generates all of self.ring()
                        return SymmetricIdeal(self.ring(),[self.ring()(1)], coerce=False)
                    RStrat.add_generator(p, good_input=True)
                    DONE.append(p)
                else:
                    if not (report is None):
                        print "-> 0"
            DONE.sort()
            if DONE == TODO:
                break
            else:
                if len(TODO)==len(DONE):
                    import copy
                    bla = copy.copy(TODO)
                    bla.sort()
                    if bla==DONE:
                        break
                TODO = DONE
        return SymmetricIdeal(self.ring(),DONE, coerce=False)
Beispiel #3
0
    def reduce(self, I, tailreduce=False):
        """
        Symmetric reduction of self by another Symmetric Ideal or list of Infinite Polynomials,
        or symmetric reduction of a given Infinite Polynomial by self.

        INPUT:

        - ``I`` -- an Infinite Polynomial, or a Symmetric Ideal or a
          list of Infinite Polynomials.
        - ``tailreduce`` -- (bool, default ``False``) If ``True``, the
          non-leading terms will be reduced as well.

        OUTPUT:

        Symmetric reduction of ``self`` with respect to ``I``.

        THEORY:

        Reduction of an element `p` of an Infinite Polynomial Ring `X`
        by some other element `q` means the following:

        1. Let `M` and `N` be the leading terms of `p` and `q`.
        2. Test whether there is a permutation `P` that does not does
           not diminish the variable indices occurring in `N` and
           preserves their order, so that there is some term `T\in X`
           with `T N^P = M`. If there is no such permutation, return `p`
        3. Replace `p` by `p-T q^P` and continue with step 1.

        EXAMPLES::

            sage: X.<x,y> = InfinitePolynomialRing(QQ)
            sage: I = X*(y[1]^2*y[3]+y[1]*x[3]^2)
            sage: I.reduce([x[1]^2*y[2]])
            Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field

        The preceding is correct, since any permutation that turns
        ``x[1]^2*y[2]`` into a factor of ``x[3]^2*y[2]`` interchanges
        the variable indices 1 and 2 -- which is not allowed. However,
        reduction by ``x[2]^2*y[1]`` works, since one can change
        variable index 1 into 2 and 2 into 3::

            sage: I.reduce([x[2]^2*y[1]])
            Symmetric Ideal (y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field

        The next example shows that tail reduction is not done, unless
        it is explicitly advised.  The input can also be a symmetric
        ideal::

            sage: J = (y[2])*X
            sage: I.reduce(J)
            Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field
            sage: I.reduce(J, tailreduce=True)
            Symmetric Ideal (x_3^2*y_1) of Infinite polynomial ring in x, y over Rational Field

        """
        if I in self.ring(): # we want to reduce a polynomial by self
            return self.ring()(I).reduce(self)
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        if hasattr(I,'gens'):
            I = I.gens()
        if (not I):
            return self
        I = list(I)
        S = SymmetricReductionStrategy(self.ring(),I, tailreduce)
        return SymmetricIdeal(self.ring(),[S.reduce(X) for X in self.gens()], coerce=False)
Beispiel #4
0
    def symmetrisation(self,
                       N=None,
                       tailreduce=False,
                       report=None,
                       use_full_group=False):
        """
        Apply permutations to the generators of self and interreduce

        INPUT:

        - ``N`` -- (integer, default ``None``) Apply permutations in
          `Sym(N)`. If it is not given then it will be replaced by the
          maximal variable index occurring in the generators of
          ``self.interreduction().squeezed()``.
        - ``tailreduce`` -- (bool, default ``False``) If ``True``, perform
          tail reductions.
        - ``report`` -- (object, default ``None``) If not ``None``, report
          on the progress of computations.
        - ``use_full_group`` (optional) -- If True, apply *all* elements of
          `Sym(N)` to the generators of self (this is what [AB2008]_
          originally suggests). The default is to apply all elementary
          transpositions to the generators of ``self.squeezed()``,
          interreduce, and repeat until the result stabilises, which is
          often much faster than applying all of `Sym(N)`, and we are
          convinced that both methods yield the same result.

        OUTPUT:

        A symmetrically interreduced symmetric ideal with respect to
        which any `Sym(N)`-translate of a generator of self is
        symmetrically reducible, where by default ``N`` is the maximal
        variable index that occurs in the generators of
        ``self.interreduction().squeezed()``.

        NOTE:

        If ``I`` is a symmetric ideal whose generators are monomials,
        then ``I.symmetrisation()`` is its reduced Groebner basis.  It
        should be noted that without symmetrisation, monomial
        generators, in general, do not form a Groebner basis.

        EXAMPLES::

            sage: X.<x> = InfinitePolynomialRing(QQ)
            sage: I = X*(x[1]+x[2], x[1]*x[2])
            sage: I.symmetrisation()
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field
            sage: I.symmetrisation(N=3)
            Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field
            sage: I.symmetrisation(N=3, use_full_group=True)
            Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field

        """
        newOUT = self.interreduction(tailreduce=tailreduce,
                                     report=report).squeezed()
        R = self.ring()
        OUT = R * ()
        if N is None:
            N = max([Y.max_index() for Y in newOUT.gens()] + [1])
        else:
            N = Integer(N)
        if hasattr(R, '_max') and R._max < N:
            R.gen()[N]
        if report is not None:
            print("Symmetrise %d polynomials at level %d" %
                  (len(newOUT.gens()), N))
        if use_full_group:
            from sage.combinat.permutation import Permutations
            NewGens = []
            Gens = self.gens()
            for P in Permutations(N):
                NewGens.extend([p**P for p in Gens])
            return (NewGens * R).interreduction(tailreduce=tailreduce,
                                                report=report)
        from sage.combinat.permutation import Permutation
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        RStrat = SymmetricReductionStrategy(self.ring(),
                                            OUT.gens(),
                                            tailreduce=tailreduce)
        while (OUT != newOUT):
            OUT = newOUT
            PermutedGens = list(OUT.gens())
            if not (report is None):
                print("Apply permutations")
            for i in range(1, N):
                for j in range(i + 1, N + 1):
                    P = Permutation(((i, j)))
                    for X in OUT.gens():
                        p = RStrat.reduce(X**P, report=report)
                        if p._p != 0:
                            PermutedGens.append(p)
                            RStrat.add_generator(p, good_input=True)
            newOUT = (PermutedGens * R).interreduction(tailreduce=tailreduce,
                                                       report=report)
        return OUT
Beispiel #5
0
    def interreduction(self,
                       tailreduce=True,
                       sorted=False,
                       report=None,
                       RStrat=None):
        """
        Return symmetrically interreduced form of self

        INPUT:

        - ``tailreduce`` -- (bool, default ``True``) If True, the
          interreduction is also performed on the non-leading monomials.
        - ``sorted`` -- (bool, default ``False``) If True, it is assumed that the
          generators of self are already increasingly sorted.
        - ``report`` -- (object, default ``None``) If not None, some information on the
          progress of computation is printed
        - ``RStrat`` -- (:class:`~sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy`,
          default ``None``) A reduction strategy to which the polynomials resulting
          from the interreduction will be added. If ``RStrat`` already contains some
          polynomials, they will be used in the interreduction. The effect is to
          compute in a quotient ring.

        OUTPUT:

        A Symmetric Ideal J (sorted list of generators) coinciding
        with self as an ideal, so that any generator is symmetrically
        reduced w.r.t. the other generators. Note that the leading
        coefficients of the result are not necessarily 1.

        EXAMPLES::

            sage: X.<x> = InfinitePolynomialRing(QQ)
            sage: I=X*(x[1]+x[2],x[1]*x[2])
            sage: I.interreduction()
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        Here, we show the ``report`` option::

            sage: I.interreduction(report=True)
            Symmetric interreduction
            [1/2]  >
            [2/2] :>
            [1/2]  >
            [2/2] T[1]>
            >
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        ``[m/n]`` indicates that polynomial number ``m`` is considered
        and the total number of polynomials under consideration is
        ``n``. '-> 0' is printed if a zero reduction occurred. The
        rest of the report is as described in
        :meth:`sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy.reduce`.

        Last, we demonstrate the use of the optional parameter ``RStrat``::

            sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
            sage: R = SymmetricReductionStrategy(X)
            sage: R
            Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field
            sage: I.interreduction(RStrat=R)
            Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field
            sage: R
            Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field, modulo
                x_1^2,
                x_2 + x_1
            sage: R = SymmetricReductionStrategy(X,[x[1]^2])
            sage: I.interreduction(RStrat=R)
            Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational Field

        """
        DONE = []
        j = 0
        TODO = []
        PARENT = self.ring()
        for P in self.gens():
            if P._p != 0:
                if P.is_unit():  # self generates all of self.ring()
                    if RStrat is not None:
                        RStrat.add_generator(PARENT(1))
                    return SymmetricIdeal(self.ring(), [self.ring()(1)],
                                          coerce=False)
                TODO.append(P)
        if not sorted:
            TODO = list(set(TODO))
            TODO.sort()
        if hasattr(PARENT, '_P'):
            CommonR = PARENT._P
        else:
            VarList = set([])
            for P in TODO:
                if P._p != 0:
                    if P.is_unit():  # self generates all of PARENT
                        if RStrat is not None:
                            RStrat.add_generator(PARENT(1))
                        return SymmetricIdeal(PARENT, [PARENT(1)],
                                              coerce=False)
                    VarList = VarList.union(P._p.parent().variable_names())
            VarList = list(VarList)
            if not VarList:
                return SymmetricIdeal(PARENT, [0])
            VarList.sort(key=PARENT.varname_key, reverse=True)
            from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
            CommonR = PolynomialRing(self.base_ring(),
                                     VarList,
                                     order=self.ring()._order)

        ## Now, the symmetric interreduction starts
        if not (report is None):
            print('Symmetric interreduction')
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        if RStrat is None:
            RStrat = SymmetricReductionStrategy(self.ring(),
                                                tailreduce=tailreduce)
        GroundState = RStrat.gens()
        while (1):
            RStrat.setgens(GroundState)
            DONE = []
            for i in range(len(TODO)):
                if report is not None:
                    print('[%d/%d] ' % (i + 1, len(TODO)), end="")
                    sys.stdout.flush()
                p = RStrat.reduce(TODO[i], report=report)
                if p._p != 0:
                    if p.is_unit():  # self generates all of self.ring()
                        return SymmetricIdeal(self.ring(), [self.ring()(1)],
                                              coerce=False)
                    RStrat.add_generator(p, good_input=True)
                    DONE.append(p)
                else:
                    if not (report is None):
                        print("-> 0")
            DONE.sort()
            if DONE == TODO:
                break
            else:
                if len(TODO) == len(DONE):
                    import copy
                    bla = copy.copy(TODO)
                    bla.sort()
                    if bla == DONE:
                        break
                TODO = DONE
        return SymmetricIdeal(self.ring(), DONE, coerce=False)
Beispiel #6
0
    def reduce(self, I, tailreduce=False):
        """
        Symmetric reduction of self by another Symmetric Ideal or list of Infinite Polynomials,
        or symmetric reduction of a given Infinite Polynomial by self.

        INPUT:

        - ``I`` -- an Infinite Polynomial, or a Symmetric Ideal or a
          list of Infinite Polynomials.
        - ``tailreduce`` -- (bool, default ``False``) If ``True``, the
          non-leading terms will be reduced as well.

        OUTPUT:

        Symmetric reduction of ``self`` with respect to ``I``.

        THEORY:

        Reduction of an element `p` of an Infinite Polynomial Ring `X`
        by some other element `q` means the following:

        1. Let `M` and `N` be the leading terms of `p` and `q`.
        2. Test whether there is a permutation `P` that does not does
           not diminish the variable indices occurring in `N` and
           preserves their order, so that there is some term `T\in X`
           with `T N^P = M`. If there is no such permutation, return `p`
        3. Replace `p` by `p-T q^P` and continue with step 1.

        EXAMPLES::

            sage: X.<x,y> = InfinitePolynomialRing(QQ)
            sage: I = X*(y[1]^2*y[3]+y[1]*x[3]^2)
            sage: I.reduce([x[1]^2*y[2]])
            Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field

        The preceding is correct, since any permutation that turns
        ``x[1]^2*y[2]`` into a factor of ``x[3]^2*y[2]`` interchanges
        the variable indices 1 and 2 -- which is not allowed. However,
        reduction by ``x[2]^2*y[1]`` works, since one can change
        variable index 1 into 2 and 2 into 3::

            sage: I.reduce([x[2]^2*y[1]])
            Symmetric Ideal (y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field

        The next example shows that tail reduction is not done, unless
        it is explicitly advised.  The input can also be a symmetric
        ideal::

            sage: J = (y[2])*X
            sage: I.reduce(J)
            Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field
            sage: I.reduce(J, tailreduce=True)
            Symmetric Ideal (x_3^2*y_1) of Infinite polynomial ring in x, y over Rational Field

        """
        if I in self.ring():  # we want to reduce a polynomial by self
            return self.ring()(I).reduce(self)
        from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
        if hasattr(I, 'gens'):
            I = I.gens()
        if (not I):
            return self
        I = list(I)
        S = SymmetricReductionStrategy(self.ring(), I, tailreduce)
        return SymmetricIdeal(self.ring(), [S.reduce(X) for X in self.gens()],
                              coerce=False)