예제 #1
0
    def invariant_generators(self):
        r"""
        Return invariant ring generators.

        Computes generators for the polynomial ring
        `F[x_1,\ldots,x_n]^G`, where `G` in `GL(n,F)` is a finite matrix
        group.

        In the "good characteristic" case the polynomials returned
        form a minimal generating set for the algebra of `G`-invariant
        polynomials.  In the "bad" case, the polynomials returned
        are primary and secondary invariants, forming a not
        necessarily minimal generating set for the algebra of
        `G`-invariant polynomials.

        ALGORITHM:

        Wraps Singular's ``invariant_algebra_reynolds`` and ``invariant_ring``
        in ``finvar.lib``.

        EXAMPLES::

            sage: F = GF(7); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()
            [x1^7*x2 - x1*x2^7, 
             x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12, 
             x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18]

            sage: q = 4; a = 2
            sage: MS = MatrixSpace(QQ, 2, 2)
            sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]]
            sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)])
            sage: G.cardinality()
            12
            sage: G.invariant_generators()
            [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6]

            sage: F = CyclotomicField(8)
            sage: z = F.gen()
            sage: a = z+1/z
            sage: b = z^2
            sage: MS = MatrixSpace(F,2,2)
            sage: g1 = MS([[1/a, 1/a], [1/a, -1/a]])
            sage: g2 = MS([[-b, 0], [0, b]])
            sage: G=MatrixGroup([g1,g2])
            sage: G.invariant_generators()
            [x1^4 + 2*x1^2*x2^2 + x2^4,
             x1^5*x2 - x1*x2^5,
             x1^8 + 28/9*x1^6*x2^2 + 70/9*x1^4*x2^4 + 28/9*x1^2*x2^6 + x2^8]

        AUTHORS:

        - David Joyner, Simon King and Martin Albrecht.

        REFERENCES:

        - Singular reference manual

        - [Stu1993]_

        - S. King, "Minimal Generating Sets of non-modular invariant
          rings of finite groups", :arxiv:`math/0703035`.
        """
        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
        from sage.interfaces.singular import singular
        gens = self.gens()
        singular.LIB("finvar.lib")
        n = self.degree() #len((gens[0].matrix()).rows())
        F = self.base_ring()
        q = F.characteristic()
        ## test if the field is admissible
        if F.gen()==1: # we got the rationals or GF(prime)
            FieldStr = str(F.characteristic())
        elif hasattr(F,'polynomial'): # we got an algebraic extension
            if len(F.gens())>1:
                raise NotImplementedError("can only deal with finite fields and (simple algebraic extensions of) the rationals")
            FieldStr = '(%d,%s)'%(F.characteristic(),str(F.gen()))
        else: # we have a transcendental extension
            FieldStr = '(%d,%s)'%(F.characteristic(),','.join([str(p) for p in F.gens()]))

        ## Setting Singular's variable names
        ## We need to make sure that field generator and variables get different names.
        if str(F.gen())[0]=='x':
            VarStr = 'y'
        else:
            VarStr = 'x'
        VarNames='('+','.join((VarStr+str(i+1) for i in range(n)))+')'
        R=singular.ring(FieldStr,VarNames,'dp')
        if hasattr(F,'polynomial') and F.gen()!=1: # we have to define minpoly
            singular.eval('minpoly = '+str(F.polynomial()).replace('x',str(F.gen())))
        A = [singular.matrix(n,n,str((x.matrix()).list())) for x in gens]
        Lgens = ','.join((x.name() for x in A))
        PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)])

        if q == 0 or (q > 0 and self.cardinality()%q != 0):
            from sage.all import Integer, Matrix
            try:
                elements = [ g.matrix() for g in self.list() ]
            except (TypeError,ValueError):
                elements
            if elements is not None:
                ReyName = 't'+singular._next_var_name()
                singular.eval('matrix %s[%d][%d]'%(ReyName,self.cardinality(),n))
                for i in range(1,self.cardinality()+1):
                    M = Matrix(F, elements[i-1])
                    D = [{} for foobar in range(self.degree())]
                    for x,y in M.dict().items():
                        D[x[0]][x[1]] = y
                    for row in range(self.degree()):
                        for t in D[row].items():
                            singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)'
                                          %(ReyName,i,row+1,ReyName,i,row+1, repr(t[1]),t[0]+1))
                foobar = singular(ReyName)
                IRName = 't'+singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName))
            else:
                ReyName = 't'+singular._next_var_name()
                singular.eval('list %s=group_reynolds((%s))'%(ReyName,Lgens))
                IRName = 't'+singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])'%(IRName,ReyName))

            OUT = [singular.eval(IRName+'[1,%d]'%(j))
                   for j in range(1,1+singular('ncols('+IRName+')'))]
            return [PR(gen) for gen in OUT]
        if self.cardinality()%q == 0:
            PName = 't'+singular._next_var_name()
            SName = 't'+singular._next_var_name()
            singular.eval('matrix %s,%s=invariant_ring(%s)'%(PName,SName,Lgens))
            OUT = [
                singular.eval(PName+'[1,%d]'%(j))
                for j in range(1,1+singular('ncols('+PName+')'))
                ] + [
                singular.eval(SName+'[1,%d]'%(j)) for j in range(2,1+singular('ncols('+SName+')'))
                ]
            return [PR(gen) for gen in OUT]
예제 #2
0
    def invariant_generators(self):
        r"""
        Return invariant ring generators.

        Computes generators for the polynomial ring
        `F[x_1,\ldots,x_n]^G`, where `G` in `GL(n,F)` is a finite matrix
        group.

        In the "good characteristic" case the polynomials returned
        form a minimal generating set for the algebra of `G`-invariant
        polynomials.  In the "bad" case, the polynomials returned
        are primary and secondary invariants, forming a not
        necessarily minimal generating set for the algebra of
        `G`-invariant polynomials.

        ALGORITHM:

        Wraps Singular's ``invariant_algebra_reynolds`` and ``invariant_ring``
        in ``finvar.lib``.

        EXAMPLES::

            sage: F = GF(7); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()
            [x1^7*x2 - x1*x2^7,
             x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12,
             x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18]

            sage: q = 4; a = 2
            sage: MS = MatrixSpace(QQ, 2, 2)
            sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]]
            sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)])
            sage: G.cardinality()
            12
            sage: G.invariant_generators()
            [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6]

            sage: F = CyclotomicField(8)
            sage: z = F.gen()
            sage: a = z+1/z
            sage: b = z^2
            sage: MS = MatrixSpace(F,2,2)
            sage: g1 = MS([[1/a, 1/a], [1/a, -1/a]])
            sage: g2 = MS([[-b, 0], [0, b]])
            sage: G=MatrixGroup([g1,g2])
            sage: G.invariant_generators()
            [x1^4 + 2*x1^2*x2^2 + x2^4,
             x1^5*x2 - x1*x2^5,
             x1^8 + 28/9*x1^6*x2^2 + 70/9*x1^4*x2^4 + 28/9*x1^2*x2^6 + x2^8]

        AUTHORS:

        - David Joyner, Simon King and Martin Albrecht.

        REFERENCES:

        - Singular reference manual

        - [Stu1993]_

        - S. King, "Minimal Generating Sets of non-modular invariant
          rings of finite groups", :arxiv:`math/0703035`.
        """
        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
        from sage.interfaces.singular import singular
        gens = self.gens()
        singular.LIB("finvar.lib")
        n = self.degree()  #len((gens[0].matrix()).rows())
        F = self.base_ring()
        q = F.characteristic()
        ## test if the field is admissible
        if F.gen() == 1:  # we got the rationals or GF(prime)
            FieldStr = str(F.characteristic())
        elif hasattr(F, 'polynomial'):  # we got an algebraic extension
            if len(F.gens()) > 1:
                raise NotImplementedError(
                    "can only deal with finite fields and (simple algebraic extensions of) the rationals"
                )
            FieldStr = '(%d,%s)' % (F.characteristic(), str(F.gen()))
        else:  # we have a transcendental extension
            FieldStr = '(%d,%s)' % (F.characteristic(), ','.join(
                [str(p) for p in F.gens()]))

        ## Setting Singular's variable names
        ## We need to make sure that field generator and variables get different names.
        if str(F.gen())[0] == 'x':
            VarStr = 'y'
        else:
            VarStr = 'x'
        VarNames = '(' + ','.join(
            (VarStr + str(i + 1) for i in range(n))) + ')'
        R = singular.ring(FieldStr, VarNames,
                          'dp')  # this does have a side-effect
        if hasattr(F,
                   'polynomial') and F.gen() != 1:  # we have to define minpoly
            singular.eval('minpoly = ' +
                          str(F.polynomial()).replace('x', str(F.gen())))
        A = [singular.matrix(n, n, str((x.matrix()).list())) for x in gens]
        Lgens = ','.join((x.name() for x in A))
        PR = PolynomialRing(F, n, [VarStr + str(i) for i in range(1, n + 1)])

        if q == 0 or (q > 0 and self.cardinality() % q != 0):
            from sage.all import Matrix
            try:
                elements = [g.matrix() for g in self.list()]
            except (TypeError, ValueError):
                elements
            if elements is not None:
                ReyName = 't' + singular._next_var_name()
                singular.eval('matrix %s[%d][%d]' %
                              (ReyName, self.cardinality(), n))
                for i in range(1, self.cardinality() + 1):
                    M = Matrix(F, elements[i - 1])
                    D = [{} for foobar in range(self.degree())]
                    for x, y in M.dict().items():
                        D[x[0]][x[1]] = y
                    for row in range(self.degree()):
                        for t in D[row].items():
                            singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)' %
                                          (ReyName, i, row + 1, ReyName, i,
                                           row + 1, repr(t[1]), t[0] + 1))
                IRName = 't' + singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s)' %
                              (IRName, ReyName))
            else:
                ReyName = 't' + singular._next_var_name()
                singular.eval('list %s=group_reynolds((%s))' %
                              (ReyName, Lgens))
                IRName = 't' + singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])' %
                              (IRName, ReyName))

            OUT = [
                singular.eval(IRName + '[1,%d]' % (j))
                for j in range(1, 1 + int(singular('ncols(' + IRName + ')')))
            ]
            return [PR(gen) for gen in OUT]
        if self.cardinality() % q == 0:
            PName = 't' + singular._next_var_name()
            SName = 't' + singular._next_var_name()
            singular.eval('matrix %s,%s=invariant_ring(%s)' %
                          (PName, SName, Lgens))
            OUT = [
                singular.eval(PName + '[1,%d]' % (j))
                for j in range(1, 1 + singular('ncols(' + PName + ')'))
            ] + [
                singular.eval(SName + '[1,%d]' % (j))
                for j in range(2, 1 + singular('ncols(' + SName + ')'))
            ]
            return [PR(gen) for gen in OUT]
예제 #3
0
    def invariant_generators(self):
        """
        Wraps Singular's invariant_algebra_reynolds and invariant_ring
        in finvar.lib, with help from Simon King and Martin Albrecht.
        Computes generators for the polynomial ring
        `F[x_1,\ldots,x_n]^G`, where G in GL(n,F) is a finite
        matrix group.

        In the "good characteristic" case the polynomials returned form a
        minimal generating set for the algebra of G-invariant polynomials.
        In the "bad" case, the polynomials returned are primary and
        secondary invariants, forming a not necessarily minimal generating
        set for the algebra of G-invariant polynomials.

        EXAMPLES::

            sage: F = GF(7); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()
            [x1^7*x2 - x1*x2^7, x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12, x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18]
            sage: q = 4; a = 2
            sage: MS = MatrixSpace(QQ, 2, 2)
            sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]]
            sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)])
            sage: G.cardinality()
            12
            sage: G.invariant_generators()
            [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6]
            sage: F = GF(5); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[1,2],[-1,1]]),MS([[1,1],[-1,1]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()  # long time (67s on sage.math, 2012)
            [x1^20 + x1^16*x2^4 + x1^12*x2^8 + x1^8*x2^12 + x1^4*x2^16 + x2^20, x1^20*x2^4 + x1^16*x2^8 + x1^12*x2^12 + x1^8*x2^16 + x1^4*x2^20]
            sage: F=CyclotomicField(8)
            sage: z=F.gen()
            sage: a=z+1/z
            sage: b=z^2
            sage: MS=MatrixSpace(F,2,2)
            sage: g1=MS([[1/a,1/a],[1/a,-1/a]])
            sage: g2=MS([[1,0],[0,b]])
            sage: g3=MS([[b,0],[0,1]])
            sage: G=MatrixGroup([g1,g2,g3])
            sage: G.invariant_generators()  # long time (12s on sage.math, 2011)
            [x1^8 + 14*x1^4*x2^4 + x2^8,
             x1^24 + 10626/1025*x1^20*x2^4 + 735471/1025*x1^16*x2^8 + 2704156/1025*x1^12*x2^12 + 735471/1025*x1^8*x2^16 + 10626/1025*x1^4*x2^20 + x2^24]

        AUTHORS:

        - David Joyner, Simon King and Martin Albrecht.

        REFERENCES:

        - Singular reference manual

        - B. Sturmfels, "Algorithms in invariant theory", Springer-Verlag, 1993.

        - S. King, "Minimal Generating Sets of non-modular invariant rings of
          finite groups", arXiv:math.AC/0703035
        """
        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
        from sage.interfaces.singular import singular
        gens = self.gens()
        singular.LIB("finvar.lib")
        n = self.degree()  #len((gens[0].matrix()).rows())
        F = self.base_ring()
        q = F.characteristic()
        ## test if the field is admissible
        if F.gen() == 1:  # we got the rationals or GF(prime)
            FieldStr = str(F.characteristic())
        elif hasattr(F, 'polynomial'):  # we got an algebraic extension
            if len(F.gens()) > 1:
                raise NotImplementedError, "can only deal with finite fields and (simple algebraic extensions of) the rationals"
            FieldStr = '(%d,%s)' % (F.characteristic(), str(F.gen()))
        else:  # we have a transcendental extension
            FieldStr = '(%d,%s)' % (F.characteristic(), ','.join(
                [str(p) for p in F.gens()]))

        ## Setting Singular's variable names
        ## We need to make sure that field generator and variables get different names.
        if str(F.gen())[0] == 'x':
            VarStr = 'y'
        else:
            VarStr = 'x'
        VarNames = '(' + ','.join(
            (VarStr + str(i + 1) for i in range(n))) + ')'
        R = singular.ring(FieldStr, VarNames, 'dp')
        if hasattr(F,
                   'polynomial') and F.gen() != 1:  # we have to define minpoly
            singular.eval('minpoly = ' +
                          str(F.polynomial()).replace('x', str(F.gen())))
        A = [singular.matrix(n, n, str((x.matrix()).list())) for x in gens]
        Lgens = ','.join((x.name() for x in A))
        PR = PolynomialRing(F, n, [VarStr + str(i) for i in range(1, n + 1)])
        if q == 0 or (q > 0 and self.cardinality() % q != 0):
            from sage.all import Integer, Matrix
            try:
                gapself = gap(self)
                # test whether the backwards transformation works as well:
                for i in range(self.ngens()):
                    if Matrix(gapself.gen(i + 1), F) != self.gen(i).matrix():
                        raise ValueError
            except (TypeError, ValueError):
                gapself is None
            if gapself is not None:
                ReyName = 't' + singular._next_var_name()
                singular.eval('matrix %s[%d][%d]' %
                              (ReyName, self.cardinality(), n))
                En = gapself.Enumerator()
                for i in range(1, self.cardinality() + 1):
                    M = Matrix(En[i], F)
                    D = [{} for foobar in range(self.degree())]
                    for x, y in M.dict().items():
                        D[x[0]][x[1]] = y
                    for row in range(self.degree()):
                        for t in D[row].items():
                            singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)' %
                                          (ReyName, i, row + 1, ReyName, i,
                                           row + 1, repr(t[1]), t[0] + 1))
                foobar = singular(ReyName)
                IRName = 't' + singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s)' %
                              (IRName, ReyName))
            else:
                ReyName = 't' + singular._next_var_name()
                singular.eval('list %s=group_reynolds((%s))' %
                              (ReyName, Lgens))
                IRName = 't' + singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])' %
                              (IRName, ReyName))

            OUT = [
                singular.eval(IRName + '[1,%d]' % (j))
                for j in range(1, 1 + singular('ncols(' + IRName + ')'))
            ]
            return [PR(gen) for gen in OUT]
        if self.cardinality() % q == 0:
            PName = 't' + singular._next_var_name()
            SName = 't' + singular._next_var_name()
            singular.eval('matrix %s,%s=invariant_ring(%s)' %
                          (PName, SName, Lgens))
            OUT = [
                singular.eval(PName + '[1,%d]' % (j))
                for j in range(1, 1 + singular('ncols(' + PName + ')'))
            ] + [
                singular.eval(SName + '[1,%d]' % (j))
                for j in range(2, 1 + singular('ncols(' + SName + ')'))
            ]
            return [PR(gen) for gen in OUT]
예제 #4
0
    def invariant_generators(self):
        """
        Wraps Singular's invariant_algebra_reynolds and invariant_ring
        in finvar.lib, with help from Simon King and Martin Albrecht.
        Computes generators for the polynomial ring
        `F[x_1,\ldots,x_n]^G`, where G in GL(n,F) is a finite
        matrix group.
        
        In the "good characteristic" case the polynomials returned form a
        minimal generating set for the algebra of G-invariant polynomials.
        In the "bad" case, the polynomials returned are primary and
        secondary invariants, forming a not necessarily minimal generating
        set for the algebra of G-invariant polynomials.
        
        EXAMPLES::
        
            sage: F = GF(7); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()
            [x1^7*x2 - x1*x2^7, x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12, x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18]
            sage: q = 4; a = 2
            sage: MS = MatrixSpace(QQ, 2, 2)
            sage: gen1 = [[1/a,(q-1)/a],[1/a, -1/a]]; gen2 = [[1,0],[0,-1]]; gen3 = [[-1,0],[0,1]]
            sage: G = MatrixGroup([MS(gen1),MS(gen2),MS(gen3)])
            sage: G.cardinality()
            12
            sage: G.invariant_generators()
            [x1^2 + 3*x2^2, x1^6 + 15*x1^4*x2^2 + 15*x1^2*x2^4 + 33*x2^6]
            sage: F = GF(5); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[1,2],[-1,1]]),MS([[1,1],[-1,1]])]
            sage: G = MatrixGroup(gens)
            sage: G.invariant_generators()  # long time (64s on sage.math, 2011)
            [x1^20 + x1^16*x2^4 + x1^12*x2^8 + x1^8*x2^12 + x1^4*x2^16 + x2^20, x1^20*x2^4 + x1^16*x2^8 + x1^12*x2^12 + x1^8*x2^16 + x1^4*x2^20]
            sage: F=CyclotomicField(8)
            sage: z=F.gen()
            sage: a=z+1/z
            sage: b=z^2
            sage: MS=MatrixSpace(F,2,2)
            sage: g1=MS([[1/a,1/a],[1/a,-1/a]])
            sage: g2=MS([[1,0],[0,b]])
            sage: g3=MS([[b,0],[0,1]])
            sage: G=MatrixGroup([g1,g2,g3])
            sage: G.invariant_generators()  # long time (12s on sage.math, 2011)
            [x1^8 + 14*x1^4*x2^4 + x2^8,
             x1^24 + 10626/1025*x1^20*x2^4 + 735471/1025*x1^16*x2^8 + 2704156/1025*x1^12*x2^12 + 735471/1025*x1^8*x2^16 + 10626/1025*x1^4*x2^20 + x2^24]
        
        AUTHORS:

        - David Joyner, Simon King and Martin Albrecht.
        
        REFERENCES:

        - Singular reference manual

        - B. Sturmfels, "Algorithms in invariant theory", Springer-Verlag, 1993.

        - S. King, "Minimal Generating Sets of non-modular invariant rings of
          finite groups", arXiv:math.AC/0703035
        """
        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
        from sage.interfaces.singular import singular
        gens = self.gens()
        singular.LIB("finvar.lib")
        n = self.degree() #len((gens[0].matrix()).rows())
        F = self.base_ring()
        q = F.characteristic()
        ## test if the field is admissible
        if F.gen()==1: # we got the rationals or GF(prime)
            FieldStr = str(F.characteristic())
        elif hasattr(F,'polynomial'): # we got an algebraic extension
            if len(F.gens())>1:
                raise NotImplementedError, "can only deal with finite fields and (simple algebraic extensions of) the rationals"
            FieldStr = '(%d,%s)'%(F.characteristic(),str(F.gen()))
        else: # we have a transcendental extension
            FieldStr = '(%d,%s)'%(F.characteristic(),','.join([str(p) for p in F.gens()]))
        
        ## Setting Singular's variable names
        ## We need to make sure that field generator and variables get different names.
        if str(F.gen())[0]=='x': 
            VarStr = 'y'
        else:
            VarStr = 'x'
        VarNames='('+','.join((VarStr+str(i+1) for i in range(n)))+')'
        R=singular.ring(FieldStr,VarNames,'dp')
        if hasattr(F,'polynomial') and F.gen()!=1: # we have to define minpoly
            singular.eval('minpoly = '+str(F.polynomial()).replace('x',str(F.gen())))
        A = [singular.matrix(n,n,str((x.matrix()).list())) for x in gens]
        Lgens = ','.join((x.name() for x in A))
        PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)])
        if q == 0 or (q > 0 and self.cardinality()%q != 0):
            from sage.all import Integer, Matrix
            try:
                gapself = gap(self)
                # test whether the backwards transformation works as well:
                for i in range(self.ngens()):
                    if Matrix(gapself.gen(i+1),F) != self.gen(i).matrix():
                        raise ValueError
            except (TypeError,ValueError):
                gapself is None
            if gapself is not None:
                ReyName = 't'+singular._next_var_name()
                singular.eval('matrix %s[%d][%d]'%(ReyName,self.cardinality(),n))
                En = gapself.Enumerator()
                for i in range(1,self.cardinality()+1):
                    M = Matrix(En[i],F)
                    D = [{} for foobar in range(self.degree())]
                    for x,y in M.dict().items():
                        D[x[0]][x[1]] = y
                    for row in range(self.degree()):
                        for t in D[row].items():
                            singular.eval('%s[%d,%d]=%s[%d,%d]+(%s)*var(%d)'%(ReyName,i,row+1,ReyName,i,row+1, repr(t[1]),t[0]+1))
                foobar = singular(ReyName)
                IRName = 't'+singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName))
            else:
                ReyName = 't'+singular._next_var_name()
                singular.eval('list %s=group_reynolds((%s))'%(ReyName,Lgens))
                IRName = 't'+singular._next_var_name()
                singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])'%(IRName,ReyName))

            OUT = [singular.eval(IRName+'[1,%d]'%(j)) for j in range(1,1+singular('ncols('+IRName+')'))]
            return [PR(gen) for gen in OUT]
        if self.cardinality()%q == 0:
            PName = 't'+singular._next_var_name()
            SName = 't'+singular._next_var_name()
            singular.eval('matrix %s,%s=invariant_ring(%s)'%(PName,SName,Lgens))
            OUT = [singular.eval(PName+'[1,%d]'%(j)) for j in range(1,1+singular('ncols('+PName+')'))] + [singular.eval(SName+'[1,%d]'%(j)) for j in range(2,1+singular('ncols('+SName+')'))]
            return [PR(gen) for gen in OUT]