Attachment 'S_units_for_etale_algebras.patch'

Download

   1 # HG changeset patch
   2 # User Robert L. Miller <[email protected]>
   3 # Date 1259959420 18000
   4 # Node ID 78cb8fa60207972fc9faccbe0a83af0cd30bac14
   5 # Parent  51902c8b223bc37104c31683d0456b03c13dc06d
   6 Implement S-class groups and S-units for polynomial rings over a number field.
   7 
   8 diff -r 51902c8b223b -r 78cb8fa60207 sage/rings/number_field/number_field_ideal.py
   9 --- a/sage/rings/number_field/number_field_ideal.py	Thu Dec 03 14:02:18 2009 -0500
  10 +++ b/sage/rings/number_field/number_field_ideal.py	Fri Dec 04 15:43:40 2009 -0500
  11 @@ -88,6 +88,60 @@
  12      """
  13      return field.pari_nf().getattr('zk') * hnf
  14  
  15 +def convert_from_idealprimedec_form(field, ideal):
  16 +    """
  17 +    INPUT:
  18 +    
  19 +    -  ``field`` - a number field
  20 +    
  21 +    -  ``ideal`` - a pari ideal, as output by the idealprimedec function
  22 +    
  23 +    EXAMPLE::
  24 +    
  25 +        sage: from sage.rings.number_field.number_field_ideal import convert_from_idealprimedec_form
  26 +        sage: K.<a> = NumberField(x^2 + 3)
  27 +        sage: K_bnf = gp(K.pari_bnf())
  28 +        sage: ideal = K_bnf.idealprimedec(3)[1]
  29 +        sage: convert_from_idealprimedec_form(K, ideal)
  30 +        Fractional ideal (1/2*a - 3/2)
  31 +        sage: K.factor(3)
  32 +        (Fractional ideal (1/2*a - 3/2))^2
  33 +
  34 +    """
  35 +    p = ZZ(ideal[1])
  36 +    alpha = field( field.pari_nf().getattr('zk') * ideal[2] )
  37 +    return field.ideal(p, alpha)
  38 +
  39 +def convert_to_idealprimedec_form(field, ideal):
  40 +    """
  41 +    INPUT:
  42 +    
  43 +    -  ``field`` - a number field
  44 +    
  45 +    -  ``ideal`` - a prime ideal
  46 +
  47 +    NOTE:
  48 +    
  49 +    The algorithm implemented right now is *immensely* stupid, but works. It
  50 +    should eventually be replaced with something better.
  51 +
  52 +    EXAMPLE::
  53 +    
  54 +        sage: from sage.rings.number_field.number_field_ideal import convert_to_idealprimedec_form
  55 +        sage: K.<a> = NumberField(x^2 + 3)
  56 +        sage: P = K.ideal(a/2-3/2)
  57 +        sage: convert_to_idealprimedec_form(K, P)
  58 +        [3, [1, 2]~, 2, 1, [1, -1]~]
  59 +
  60 +    """
  61 +    p = ideal.residue_field().characteristic()
  62 +    from sage.interfaces.gp import gp
  63 +    K_bnf = gp(field.pari_bnf())
  64 +    for primedecform in K_bnf.idealprimedec(p):
  65 +        if convert_from_idealprimedec_form(field, primedecform) == ideal:
  66 +            return primedecform
  67 +    raise RuntimeError
  68 +    
  69  class NumberFieldIdeal(Ideal_generic):
  70      """
  71      An ideal of a number field.
  72 diff -r 51902c8b223b -r 78cb8fa60207 sage/rings/polynomial/polynomial_quotient_ring.py
  73 --- a/sage/rings/polynomial/polynomial_quotient_ring.py	Thu Dec 03 14:02:18 2009 -0500
  74 +++ b/sage/rings/polynomial/polynomial_quotient_ring.py	Fri Dec 04 15:43:40 2009 -0500
  75 @@ -570,6 +570,163 @@
  76          return self(self.polynomial_ring().random_element(degree=self.degree()-1))
  77          
  78  
  79 +    def S_class_group(self, S, proof=True):
  80 +        """
  81 +        If this quotient ring is over a number field K, by a polynomial with
  82 +        nonzero discriminant, and S is a set of primes of K, this function
  83 +        returns the S-class group.
  84 +        """
  85 +        return self._S_class_group_and_units(S, proof=proof)[1]
  86 +    
  87 +    def class_group(self, proof=True):
  88 +        """
  89 +        If this quotient ring is over a number field K, by a polynomial of
  90 +        nonzero discriminant, returns the class group.
  91 +        """
  92 +        return self._S_class_group_and_units([], proof=proof)[1]
  93 +
  94 +    def S_units(self, S, proof=True):
  95 +        """
  96 +        If this quotient ring is over a number field K, by a polynomial with
  97 +        nonzero discriminant, and S is a set of primes of K, this function
  98 +        returns the S-units.
  99 +        """
 100 +        return self._S_class_group_and_units(S, proof=proof)[0]
 101 +    
 102 +    def units(self, proof=True):
 103 +        """
 104 +        If this quotient ring is over a number field K, by a polynomial of
 105 +        nonzero discriminant, returns the units.
 106 +        """
 107 +        return self._S_class_group_and_units([], proof=proof)[0]
 108 +
 109 +    def _S_class_group_and_units(self, S, proof=True):
 110 +        from sage.rings.number_field.all import is_NumberField
 111 +        K = self.base_ring()
 112 +        if not is_NumberField(K) or not self.__polynomial.is_squarefree():
 113 +            raise NotImplementedError
 114 +        
 115 +        from sage.rings.ideal import is_Ideal
 116 +        for p in S:
 117 +#            try:
 118 +            assert is_Ideal(p)
 119 +            assert p.ring() is K or p.ring() is K.ring_of_integers() # second check due to inconsistency over QQ - see # 7596
 120 +            assert p.is_prime()
 121 +#            except AssertionError:
 122 +#                raise TypeError("S must be a list of prime ideals of the base field.")
 123 +        
 124 +        from sage.rings.number_field.number_field import NumberField
 125 +        from sage.rings.number_field.number_field_ideal import \
 126 +            convert_to_idealprimedec_form, convert_from_idealprimedec_form
 127 +        from sage.interfaces.gp import gp
 128 +
 129 +        F = self.__polynomial.factor()
 130 +        rel_fields = []
 131 +        abs_fields = []
 132 +        isos = []
 133 +        iso_classes = []
 134 +        i = 0
 135 +        for f, _ in F:
 136 +            D = K.extension(f, 'x'+str(i))
 137 +            rel_fields.append(D)
 138 +            D_abs = D.absolute_field('y'+str(i))
 139 +            abs_fields.append(D_abs)
 140 +            i += 1
 141 +            
 142 +            seen_before = False
 143 +            j = 0
 144 +            for D_iso,_ in iso_classes:
 145 +                if D_abs.is_isomorphic(D_iso):
 146 +                    seen_before = True; break
 147 +                j += 1
 148 +            if seen_before:
 149 +                isos.append((D_iso.embeddings(D_abs)[0], j))
 150 +            else:
 151 +                S_abs = []
 152 +                for p in S:
 153 +                    abs_gens = []
 154 +                    for g in D.ideal([a for a in p.gens()]).gens(): # this line looks a bit silly, due to inconsistency over QQ - see # 7596
 155 +                        abs_gens.append(D_abs.structure()[1](g))
 156 +                    S_abs += [pp for pp,_ in D_abs.ideal(abs_gens).factor()]
 157 +                iso_classes.append((D_abs,S_abs))
 158 +                isos.append((D_abs.embeddings(D_abs)[0], j))
 159 +
 160 +        from sage.rings.all import QQ, ZZ
 161 +        component_S_units = []
 162 +        component_S_class_groups = []
 163 +        component_S_class_str = []
 164 +        for D_iso, S_iso in iso_classes:
 165 +            deg = D_iso.degree()
 166 +            D_gp = gp(D_iso.pari_bnf())
 167 +            if proof:
 168 +                assert D_gp.bnfcertify() == 1
 169 +                # if the result is not provable, may output an
 170 +                # error message, or loop indefinitely
 171 +            
 172 +            S_gp = [convert_to_idealprimedec_form(D_iso, p) for p in S_iso]
 173 +            units = []
 174 +            
 175 +            result = D_gp.bnfsunit(S_gp)
 176 +            x = D_iso.gen()
 177 +            for unit in result[1]:
 178 +                sage_unit = 0
 179 +                for i in xrange(unit.poldegree()+1):
 180 +                    sage_unit += QQ(unit.polcoeff(i))*x**i
 181 +                units.append(sage_unit)
 182 +            units += D_iso.unit_group().gens()
 183 +            component_S_units.append(units)
 184 +            
 185 +            IB = []
 186 +            for f_gp in D_gp[7][7]:
 187 +                f = 0
 188 +                for i in xrange(f_gp.length()):
 189 +                    f += QQ(f_gp.polcoeff(i))*x**i
 190 +                IB.append(f)
 191 +            clgp_gens = []
 192 +            for M in result[5][3]:
 193 +                ideal_gens = []
 194 +                for i in xrange(1, deg+1):
 195 +                    col = []
 196 +                    for j in xrange(1, deg+1):
 197 +                        col.append(ZZ(M[j,i]))
 198 +                    ideal_gens.append(sum([IB[j]*col[j] for j in xrange(deg)]))
 199 +                clgp_gens.append(D_iso.ideal(ideal_gens))
 200 +            component_S_class_groups.append(clgp_gens)
 201 +        
 202 +        from sage.rings.arith import crt
 203 +        units = []
 204 +        clgp_gens = []
 205 +        moduli = [D.relative_polynomial() for D in rel_fields]
 206 +        for i in xrange(len(rel_fields)):
 207 +            phi = isos[i][0]
 208 +            back_to_rel = phi.codomain().structure()[0]
 209 +            for unit in component_S_units[isos[i][1]]:
 210 +                rel_unit = back_to_rel(phi(unit))
 211 +                prod_unit = []
 212 +                for j in xrange(i):
 213 +                    prod_unit.append(rel_fields[j](1))
 214 +                prod_unit.append(back_to_rel(phi(unit)))
 215 +                for j in xrange(len(rel_fields) - i - 1):
 216 +                    prod_unit.append(rel_fields[j](1))
 217 +                poly_unit = crt([u_i.polynomial() for u_i in prod_unit], moduli, None, None)
 218 +                units.append(self(poly_unit))
 219 +            for clgp_gen in component_S_class_groups[isos[i][1]]:
 220 +                poly_ideal_gens = []
 221 +                for ideal_gen in clgp_gen.gens():
 222 +                    rel_ideal_gen = back_to_rel(phi(ideal_gen))
 223 +                    prod_ideal_gen = []
 224 +                    for j in xrange(i):
 225 +                        prod_ideal_gen.append(rel_fields[j](1))
 226 +                    prod_ideal_gen.append(back_to_rel(phi(ideal_gen)))
 227 +                    for j in xrange(len(rel_fields) - i - 1):
 228 +                        prod_ideal_gen.append(rel_fields[j](1))
 229 +                    poly_ideal_gen = crt([u_i.polynomial() for u_i in prod_ideal_gen], moduli, None, None)
 230 +                    poly_ideal_gens.append(poly_ideal_gen)
 231 +                clgp_gens.append(self.ideal(poly_ideal_gens))
 232 +                
 233 +        
 234 +        return units, clgp_gens
 235 +
 236  class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, sage.rings.integral_domain.IntegralDomain):
 237      """
 238      EXAMPLES::

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2009-12-04 20:45:35, 9.3 KB) [[attachment:S_units_for_etale_algebras.patch]]
  • [get | view] (2009-12-02 01:58:22, 9.1 KB) [[attachment:ThreeDescent.gp]]
  • [get | view] (2009-12-02 07:15:10, 62.0 KB) [[attachment:_jetchev-stein-congruences_and_unramified_cohomology.pdf]]
  • [get | view] (2009-12-03 01:37:44, 674.2 KB) [[attachment:gaudry-gurel-an_extension_of_Kedlayas_point-counting_algorithm_to_superelliptic_curves.pdf]]
  • [get | view] (2009-12-23 06:38:52, 5.4 KB) [[attachment:jetchev-stein.sws]]
  • [get | view] (2009-12-04 08:13:22, 8.7 KB) [[attachment:three_descent.sage]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.