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 b  
    1717  to GAP's MeatAxe implementation) and as_permutation_group (returns 
    1818  isomorphic PermutationGroup). 
    1919 
     20- Simon King (2010-05): Improve invariant_generators by using GAP 
     21  for the construction of the Reynolds operator in Singular. 
     22 
    2023This class is designed for computing with matrix groups defined by 
    2124a (relatively small) finite set of generating matrices. 
    2225 
     
    10561059        from sage.interfaces.singular import singular 
    10571060        gens = self.gens() 
    10581061        singular.LIB("finvar.lib") 
    1059         n = len((gens[0].matrix()).rows()) 
     1062        n = self.degree() #len((gens[0].matrix()).rows()) 
    10601063        F = self.base_ring() 
    10611064        q = F.characteristic() 
    10621065        ## test if the field is admissible 
     
    10831086        Lgens = ','.join((x.name() for x in A)) 
    10841087        PR = PolynomialRing(F,n,[VarStr+str(i) for i in range(1,n+1)]) 
    10851088        if q == 0 or (q > 0 and self.cardinality()%q != 0): 
    1086             ReyName = 't'+singular._next_var_name() 
    1087             singular.eval('list %s=group_reynolds((%s))'%(ReyName,Lgens)) 
    1088             IRName = 't'+singular._next_var_name() 
    1089             singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])'%(IRName,ReyName)) 
     1089            from sage.all import Integer, Matrix 
     1090            try: 
     1091                gapself = gap(self) 
     1092                # test whether the backwards transformation works as well: 
     1093                for i in range(self.ngens()): 
     1094                    if Matrix(gapself.gen(i+1),F) != self.gen(i).matrix(): 
     1095                        raise ValueError 
     1096            except (TypeError,ValueError): 
     1097                gapself is None 
     1098            if gapself is not None: 
     1099                ReyName = 't'+singular._next_var_name() 
     1100                singular.eval('matrix %s[%d][%d]'%(ReyName,self.cardinality(),n)) 
     1101                En = gapself.Enumerator() 
     1102                for i in range(1,self.cardinality()+1): 
     1103                    M = Matrix(En[i],F) 
     1104                    D = [{} for foobar in range(self.degree())] 
     1105                    for x,y in M.dict().items(): 
     1106                        D[x[0]][x[1]] = y 
     1107                    for row in range(self.degree()): 
     1108                        for t in D[row].items(): 
     1109                            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)) 
     1110                foobar = singular(ReyName) 
     1111                IRName = 't'+singular._next_var_name() 
     1112                singular.eval('matrix %s = invariant_algebra_reynolds(%s)'%(IRName,ReyName)) 
     1113            else: 
     1114                ReyName = 't'+singular._next_var_name() 
     1115                singular.eval('list %s=group_reynolds((%s))'%(ReyName,Lgens)) 
     1116                IRName = 't'+singular._next_var_name() 
     1117                singular.eval('matrix %s = invariant_algebra_reynolds(%s[1])'%(IRName,ReyName)) 
     1118 
    10901119            OUT = [singular.eval(IRName+'[1,%d]'%(j)) for j in range(1,1+singular('ncols('+IRName+')'))] 
    10911120            return [PR(gen) for gen in OUT] 
    10921121        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 b  
    1111 
    1212- Robert Bradshaw (2008-10): specified embeddings into ambient fields 
    1313 
     14- Simon King(2010-05): Improve coercion from GAP 
     15 
    1416.. note:: 
    1517 
    1618   Unlike in PARI/GP, class group computations *in Sage* do *not* by default 
     
    67306732            z^2 + 3 
    67316733            sage: k5(w) 
    67326734            z^2 + 3 
     6735 
     6736        It may be that GAP uses a name for the generator of the cyclotomic field. 
     6737        We can deal with this case, if this name coincides with the name in Sage:: 
     6738 
     6739            sage: F=CyclotomicField(8) 
     6740            sage: z=F.gen() 
     6741            sage: a=gap(z+1/z); a 
     6742            -zeta8^3+zeta8 
     6743            sage: F(a) 
     6744            -zeta8^3 + zeta8 
     6745 
     6746        In some cases, the string representation in GAP contains an exclamation 
     6747        mark, which used to be a problem in earlier versions of Sage. Now, we can 
     6748        deal with it as well:: 
     6749 
     6750            sage: b=gap(Matrix(F,[[z^2,1],[0,a+1]])); b 
     6751            [ [ zeta8^2, !1 ], [ !0, -zeta8^3+zeta8+1 ] ] 
     6752            sage: b[1,2] 
     6753            !1 
     6754            sage: F(b[1,2]) 
     6755            1 
     6756            sage: Matrix(b,F) 
     6757            [             zeta8^2                    1] 
     6758            [                   0 -zeta8^3 + zeta8 + 1] 
    67336759        """ 
    67346760        s = str(x) 
    67356761        i = s.find('E(') 
    67366762        if i == -1: 
    6737             return self(rational.Rational(s)) 
     6763            try: 
     6764                # it may be that a number field element's string representation 
     6765                # in GAP has an exclamation mark in it. 
     6766                return self(rational.Rational(s.replace('!',''))) 
     6767            except: 
     6768                # There is no 'E(...)' in the string representation. But it may 
     6769                # be that 'E(...)' was overwritten in GAP. We can only hope that 
     6770                # by coincidence the name in GAP is the same as the name in self 
     6771                return self._coerce_from_str(s.replace('!','')) 
    67386772        j = i + s[i:].find(')') 
    67396773        n = int(s[i+2:j]) 
    67406774        if n == self.zeta_order(): 
     
    67426776        else: 
    67436777            K = CyclotomicField(n) 
    67446778        zeta = K.gen() 
    6745         s = s.replace('E(%s)'%n,'zeta') 
    6746         s = sage.misc.all.sage_eval(s, locals={'zeta':K.gen()}) 
     6779        zeta_name = K.variable_name() 
     6780        while zeta_name in s: # could be that gap uses the generator name for a different purpose 
     6781            zeta_name = zeta_name+'_' 
     6782        s = s.replace('E(%s)'%n,zeta_name) 
     6783        s = sage.misc.all.sage_eval(s, locals={zeta_name:zeta}) 
    67476784        if K is self: 
    67486785            return s 
    67496786        else: