# Ticket #8909: 8909_gap2cyclotomic.patch

File 8909_gap2cyclotomic.patch, 6.2 KB (added by SimonKing, 3 years ago)

Improve coercion from GAP into cyclotomic fields; use GAP to compute Reynolds operators for Singular

• ## sage/groups/matrix_gps/matrix_group.py

```# HG changeset patch
# User Simon King <simon.king@nuigalway.ie>
# Date 1273227447 -3600
# Node ID 4665ebe92fa1d9754a2fe929e9a4842e9ea90b7d
# Parent  b863b0bd2d339b2740caf20783aabf3832531de8
Improved: 1. Coercion from GAP into number fields, 2. Invariant rings (by using GAP to construct the Reynolds operator in Singular).

diff -r b863b0bd2d33 -r 4665ebe92fa1 sage/groups/matrix_gps/matrix_group.py```
 a to GAP's MeatAxe implementation) and as_permutation_group (returns isomorphic PermutationGroup). - Simon King (2010-05): Improve invariant_generators by using GAP for the construction of the Reynolds operator in Singular. This class is designed for computing with matrix groups defined by a (relatively small) finite set of generating matrices. from sage.interfaces.singular import singular gens = self.gens() singular.LIB("finvar.lib") n = len((gens[0].matrix()).rows()) n = self.degree() #len((gens[0].matrix()).rows()) F = self.base_ring() q = F.characteristic() ## test if the field is admissible 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): 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)) 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:
• ## sage/rings/number_field/number_field.py

`diff -r b863b0bd2d33 -r 4665ebe92fa1 sage/rings/number_field/number_field.py`
 a - Robert Bradshaw (2008-10): specified embeddings into ambient fields - Simon King(2010-05): Improve coercion from GAP .. note:: Unlike in PARI/GP, class group computations *in Sage* do *not* by default z^2 + 3 sage: k5(w) z^2 + 3 It may be that GAP uses a name for the generator of the cyclotomic field. We can deal with this case, if this name coincides with the name in Sage:: sage: F=CyclotomicField(8) sage: z=F.gen() sage: a=gap(z+1/z); a -zeta8^3+zeta8 sage: F(a) -zeta8^3 + zeta8 In some cases, the string representation in GAP contains an exclamation mark, which used to be a problem in earlier versions of Sage. Now, we can deal with it as well:: sage: b=gap(Matrix(F,[[z^2,1],[0,a+1]])); b [ [ zeta8^2, !1 ], [ !0, -zeta8^3+zeta8+1 ] ] sage: b[1,2] !1 sage: F(b[1,2]) 1 sage: Matrix(b,F) [             zeta8^2                    1] [                   0 -zeta8^3 + zeta8 + 1] """ s = str(x) i = s.find('E(') if i == -1: return self(rational.Rational(s)) try: # it may be that a number field element's string representation # in GAP has an exclamation mark in it. return self(rational.Rational(s.replace('!',''))) except: # There is no 'E(...)' in the string representation. But it may # be that 'E(...)' was overwritten in GAP. We can only hope that # by coincidence the name in GAP is the same as the name in self return self._coerce_from_str(s.replace('!','')) j = i + s[i:].find(')') n = int(s[i+2:j]) if n == self.zeta_order(): else: K = CyclotomicField(n) zeta = K.gen() s = s.replace('E(%s)'%n,'zeta') s = sage.misc.all.sage_eval(s, locals={'zeta':K.gen()}) zeta_name = K.variable_name() while zeta_name in s: # could be that gap uses the generator name for a different purpose zeta_name = zeta_name+'_' s = s.replace('E(%s)'%n,zeta_name) s = sage.misc.all.sage_eval(s, locals={zeta_name:zeta}) if K is self: return s else: