# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1196591888 28800
# Node ID 6a7a05ed7b705b22c1e1589fe8263cfc03bb28b1
# Parent 54cdaf20dc6ff93f16ba63be50a62efe38ea2476
Work in progress on trac #1183.
diff r 54cdaf20dc6f r 6a7a05ed7b70 sage/rings/residue_field.pyx
a

b

from sage.rings.finite_field_ext_pari im 
49  49  from sage.rings.finite_field_ext_pari import FiniteField_ext_pari 
50  50  from sage.structure.parent_base import ParentWithBase 
51  51  
 52  from sage.rings.polynomial.polynomial_ring import PolynomialRing 
 53  
52  54  residue_field_cache = {} 
53  55  
54  56  def ResidueField(p, names = None, check = True): 
… 
… 
def ResidueField(p, names = None, check 
76  78  Residue field in abar of Fractional ideal (2*a^2 + 3*a  10) 
77  79  sage: k.order() 
78  80  841 
 81  
 82  An example where the generator of the number field doesn't 
 83  generate the residue class field. 
 84  sage: K.<a> = NumberField(x^3875) 
 85  sage: P = K.ideal(5).factor()[0][0]; k = K.residue_field(P); k 
 86  Residue field in abar of Fractional ideal (5, 2/25*a^2  1/5*a + 2) 
 87  sage: k.polynomial() 
 88  abar^2 + 3*abar + 4 
 89  sage: k.0^3  875 
 90  2 
79  91  """ 
80  92  if isinstance(names, tuple): 
81  93  if len(names) > 0: 
… 
… 
def ResidueField(p, names = None, check 
100  112  raise ValueError, "p must be prime" 
101  113  # Should generalize to allowing residue fields of relative extensions to be extensions of finite fields. 
102  114  characteristic = p.smallest_integer() 
 115  
103  116  K = p.number_field() 
104  117  OK = K.maximal_order() # should change to p.order once this works. 
105   f = OK.number_field().polynomial().change_ring(Integers(characteristic)) #polynomial() should change to absolute_polynomial() 
106   L = f.factor() 
107   for i in range(len(L)): 
108   g = L[i][0] 
109   a = K(g.change_ring(QQ)) 
110   if a in p: 
111   break 
 118  
 119  U, to_vs, to_order = p._p_quotient(characteristic) 
 120  k = U.base_ring() 
 121  R = PolynomialRing(k, names) 
 122  n = p.residue_class_degree() 
 123  gen_ok = False 
 124  from sage.matrix.constructor import matrix 
 125  try: 
 126  x = K.gen() 
 127  M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]).transpose() 
 128  M.echelonize() 
 129  if M.rank() == n: 
 130  gen_ok = True 
 131  f = R((M.column(n)).list() + [1]) 
 132  except TypeError: 
 133  pass 
 134  if not gen_ok: 
 135  bad = True 
 136  for u in U: # using this iterator may not be optimal, we may get a long string of nongenerators 
 137  if u: 
 138  x = to_order(u) 
 139  M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]).transpose() 
 140  M.echelonize() 
 141  if M.rank() == n: 
 142  f = R((M.column(n)).list() + [1]) 
 143  bad = False 
 144  break 
 145  assert not bad, "error  didn't find a generator." 
 146  if n == 1: 
 147  k = ResidueFiniteField_prime_modn(p, names, im_gen = f[0], intp = p.smallest_integer()) 
112  148  else: 
113   raise RuntimeError, "should have found a prime" 
114   if g.degree() == 1: 
115   k = ResidueFiniteField_prime_modn(p, names, im_gen = g[0], intp = p.smallest_integer()) 
116   else: 
117   q = characteristic**(g.degree()) 
 149  q = characteristic**(f.degree()) 
118  150  if q < Integer(2)**Integer(16): 
119   k = ResidueFiniteField_givaro(p, q, names, g, characteristic) 
 151  k = ResidueFiniteField_givaro(p, q, names, f, characteristic) 
120  152  else: 
121   k = ResidueFiniteField_ext_pari(p, q, names, g, characteristic) 
 153  k = ResidueFiniteField_ext_pari(p, q, names, f, characteristic) 
 154  k.structure = (U, to_vs, to_order) 
122  155  else: # Add support for primes in other rings later. 
123  156  raise TypeError, "p must be a prime in the integers or a number field" 
124  157  residue_field_cache[key] = weakref.ref(k) 