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]
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]
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]
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]