Ticket #8909: 8909_gap2cyclotomic.patch

File 8909_gap2cyclotomic.patch, 6.2 KB (added by SimonKing, 10 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: