Changeset 7727:8915b2343245
- Timestamp:
- 12/02/07 05:13:19 (5 years ago)
- Branch:
- default
- Files:
-
- 3 edited
-
sage/rings/number_field/number_field_ideal.py (modified) (2 diffs)
-
sage/rings/residue_field.pyx (modified) (14 diffs)
-
setup.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
sage/rings/number_field/number_field_ideal.py
r7725 r7727 1021 1021 V, from_V, to_V = K.absolute_vector_space() 1022 1022 M = ZZ**(V.dimension()) 1023 C = [to_V( b) for b in B]1023 C = [to_V(K(b.list())) for b in B] 1024 1024 return M.span_of_basis(C) 1025 1025 … … 1098 1098 1099 1099 K = I.number_field() 1100 OK = K.maximal_order( p) # really only need a p-maximal order.1100 OK = K.maximal_order() # will in the long run only really need a p-maximal order. 1101 1101 M_OK = OK.free_module() 1102 1102 M_I = I.free_module() -
sage/rings/residue_field.pyx
r7726 r7727 50 50 from sage.structure.parent_base import ParentWithBase 51 51 52 from sage.modules.free_module_element import FreeModuleElement 53 52 54 from sage.rings.polynomial.polynomial_ring import PolynomialRing 53 55 … … 89 91 sage: k.0^3 - 875 90 92 2 93 94 An example where the residue class field is large but of degree 1: 95 sage: K.<a> = NumberField(x^3-875); P = K.ideal(2007).factor()[0][0]; k = K.residue_field(P); k 96 Residue field of Fractional ideal (-2/25*a^2 - 2/5*a - 3) 97 sage: k(a) 98 168 99 sage: k(a)^3 - 875 100 0 101 102 In this example, 2 is an inessential discriminant divisor, so divides 103 the index of ZZ[a] in the maximal order for all a. 104 sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8); P = K.ideal(2).factor()[0][0]; P 105 Fractional ideal (1/2*a^2 - 1/2*a + 1) 106 sage: F = K.residue_field(P); F 107 Residue field of Fractional ideal (1/2*a^2 - 1/2*a + 1) 108 sage: F(a) 109 0 110 sage: B = K.maximal_order().basis(); B 111 [1, 1/2*a^2 + 1/2*a, a^2] 112 sage: F(B[1]) 113 1 114 sage: F(B[2]) 115 0 116 sage: F 117 Residue field of Fractional ideal (1/2*a^2 - 1/2*a + 1) 118 sage: F.degree() 119 1 91 120 """ 92 121 if isinstance(names, tuple): … … 100 129 if k is not None: 101 130 return k 102 if PY_TYPE_CHECK(p, Integer): 103 if check and not p.is_prime(): 131 if check: 132 if not is_NumberFieldIdeal(p): 133 raise TypeError, "p must be a prime ideal in the ring of integers of a number field." 134 if not p.is_prime(): 104 135 raise ValueError, "p must be prime" 105 if names is None: 106 names = 'x' 107 k = ResidueFiniteField_prime_modn(p, names) 108 elif is_NumberFieldIdeal(p): 109 if names is None: 110 names = '%sbar'%(p.number_field().variable_name()) 111 if check and not p.is_prime(): 112 raise ValueError, "p must be prime" 113 # Should generalize to allowing residue fields of relative extensions to be extensions of finite fields. 114 characteristic = p.smallest_integer() 115 116 K = p.number_field() 117 OK = K.maximal_order() # should change to p.order once this works. 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 non-generators 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()) 136 137 if names is None: 138 names = '%sbar'%(p.number_field().variable_name()) 139 # Should generalize to allowing residue fields of relative extensions to be extensions of finite fields. 140 characteristic = p.smallest_integer() 141 142 K = p.number_field() 143 OK = K.maximal_order() # should change to p.order once this works. 144 145 U, to_vs, to_order = p._p_quotient(characteristic) 146 k = U.base_ring() 147 R = PolynomialRing(k, names) 148 n = p.residue_class_degree() 149 gen_ok = False 150 from sage.matrix.constructor import matrix 151 try: 152 x = K.gen() 153 M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]) 154 W = M.transpose().echelon_form() 155 if M.rank() == n: 156 PB = M.matrix_from_rows(range(n)) 157 gen_ok = True 158 f = R((-W.column(n)).list() + [1]) 159 except TypeError: 160 pass 161 if not gen_ok: 162 bad = True 163 for u in U: # using this iterator may not be optimal, we may get a long string of non-generators 164 if u: 165 x = to_order(u) 166 M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]) 167 W = M.transpose().echelon_form() 168 if W.rank() == n: 169 f = R((-W.column(n)).list() + [1]) 170 PB = M.matrix_from_rows(range(n)) 171 bad = False 172 break 173 assert not bad, "error -- didn't find a generator." 174 if n == 1: 175 k = ResidueFiniteField_prime_modn(p, names, im_gen = -f[0], intp = p.smallest_integer()) 176 else: 177 q = characteristic**(f.degree()) 178 if q < Integer(2)**Integer(16): 179 k = ResidueFiniteField_givaro(p, q, names, f, characteristic) 148 180 else: 149 q = characteristic**(f.degree()) 150 if q < Integer(2)**Integer(16): 151 k = ResidueFiniteField_givaro(p, q, names, f, characteristic) 152 else: 153 k = ResidueFiniteField_ext_pari(p, q, names, f, characteristic) 154 k.structure = (U, to_vs, to_order) 155 else: # Add support for primes in other rings later. 156 raise TypeError, "p must be a prime in the integers or a number field" 181 k = ResidueFiniteField_ext_pari(p, q, names, f, characteristic) 182 # end creating field. 183 184 # The reduction map is just x |--> k(to_vs(x) * (PB**(-1))) 185 # The lifting map is just x |--> to_order(x * PB) 186 pi = ReductionMap(K, k, to_vs, PB**(-1)) 187 lift = LiftingMap(K, k, to_order, PB) 188 k._structure = (pi, lift) 189 157 190 residue_field_cache[key] = weakref.ref(k) 158 191 return k … … 232 265 return -1 233 266 return cmp(type(self), type(x)) 267 268 class ReductionMap: 269 def __init__(self, K, F, to_vs, PBinv): 270 self.__K = K 271 self.__F = F # finite field 272 self.__to_vs = to_vs 273 self.__PBinv = PBinv 274 275 def __call__(self, x): 276 # The reduction map is just x |--> F(to_vs(x) * (PB**(-1))) 277 x = self.__K(x) 278 return self.__F(self.__to_vs(x) * self.__PBinv) 279 280 def __repr__(self): 281 return "Partially defined reduction map from %s to %s"%(self.__K, self.__F) 282 283 class LiftingMap: 284 def __init__(self, K, F, to_order, PB): 285 self.__K = K 286 self.__F = F # finite field 287 self.__to_order = to_order 288 self.__PB = PB 289 290 def __call__(self, x): 291 # The lifting map is just x |--> to_order(x * PB) 292 x = self.__F(x) 293 v = x.polynomial().padded_list(self.__F.degree()) 294 return self.__to_order(self.__PB.linear_combination_of_rows(v)) 295 296 def __repr__(self): 297 return "Lifting map from %s to %s"%(self.__F, self.__K) 234 298 235 299 cdef class NFResidueFieldHomomorphism(ResidueFieldHomomorphism): … … 276 340 """ 277 341 self.im_gen = im_gen 278 self.p = p 342 self.p = p 279 343 ResidueFieldHomomorphism.__init__(self,Hom(p.number_field().maximal_order(), k, Rings())) # should eventually change to p.order() 280 344 … … 291 355 13*abar^2 + 7*abar + 21 292 356 """ 293 y = x.polynomial().change_ring(self.codomain().base_ring())(self.im_gen) #polynomial should change to absolute_polynomial? 357 #y = x.polynomial().change_ring(self.codomain().base_ring())(self.im_gen) #polynomial should change to absolute_polynomial? 358 y = self.codomain()(x) 294 359 (<Element>y)._set_parent_c(self.codomain()) 295 360 return y … … 303 368 sage: K.<a> = NumberField(x^3-7) 304 369 sage: P = K.ideal(29).factor()[0][0] 305 sage: k = K.residue_field(P)370 sage: k = K.residue_field(P) 306 371 sage: OK = K.maximal_order() 307 372 sage: f = k.coerce_map_from(OK) … … 315 380 if self.domain() is ZZ: 316 381 return x.lift() 317 return self.domain()(x.polynomial().change_ring(self.domain().base_ring())(self.domain().ring_generators()[0])) #polynomial should change to absolute_polynomial? 382 else: 383 return self.codomain()._structure[1](x) 384 385 # return self.domain()(x.polynomial().change_ring(self.domain().base_ring())(self.domain().ring_generators()[0])) #polynomial should change to absolute_polynomial? 318 386 319 387 … … 346 414 """ 347 415 INPUT: 348 p -- A n integral prime or aprime ideal of a number field.416 p -- A prime ideal of a number field. 349 417 name -- the name of the generator of this extension 350 418 im_gen -- the image of the generator of the number field in this finite field. … … 384 452 """ 385 453 try: 386 return self.coerce_map_from(self.f.domain())(self.f.domain()(x))387 except (AttributeError, TypeError):388 454 return FiniteField_prime_modn.__call__(self, x) 455 except TypeError: 456 if isinstance(x, FreeModuleElement): 457 return FiniteField_prime_modn.__call__(self, x[0]) 458 else: 459 return self._structure[0](x) 460 #try: 461 # return self.coerce_map_from(self.f.domain())(self.f.domain()(x)) 462 #except (AttributeError, TypeError): 463 # return FiniteField_prime_modn.__call__(self, x) 389 464 390 465 class ResidueFiniteField_ext_pari(ResidueField_generic, FiniteField_ext_pari): … … 395 470 sage: K.<a> = NumberField(x^3-7) 396 471 sage: P = K.ideal(923478923).factor()[0][0] 397 sage: k = K.residue_field(P)472 sage: k = K.residue_field(P) 398 473 sage: k.degree() 399 474 2 … … 438 513 """ 439 514 try: 440 return self.coerce_map_from(self.f.domain())(self.f.domain()(x))441 except (AttributeError, TypeError):442 515 return FiniteField_ext_pari.__call__(self, x) 516 except TypeError: 517 return self._structure[0](x) 518 #try: 519 # return self.coerce_map_from(self.f.domain())(self.f.domain()(x)) 520 #except (AttributeError, TypeError): 521 # return FiniteField_ext_pari.__call__(self, x) 443 522 444 523 class ResidueFiniteField_givaro(ResidueField_generic, FiniteField_givaro): … … 474 553 sage: K.<a> = NumberField(x^4+3*x^2-17) 475 554 sage: P = K.ideal(61).factor()[0][0] 476 sage: k = K.residue_field(P)555 sage: k = K.residue_field(P) 477 556 """ 478 557 FiniteField_givaro.__init__(self, q, name, g) … … 494 573 """ 495 574 try: 496 return self.coerce_map_from(self.f.domain())(self.f.domain()(x))497 except (AttributeError, TypeError):498 575 return FiniteField_givaro.__call__(self, x) 499 576 except TypeError: 577 try: 578 return self._structure[0](x) 579 except: 580 raise TypeError 581 582 #try: 583 # return self.coerce_map_from(self.f.domain())(self.f.domain()(x)) 584 #except (AttributeError, TypeError): 585 # return FiniteField_givaro.__call__(self, x) 586 587 -
setup.py
r7678 r7727 1099 1099 if not sdist and do_cython: 1100 1100 cython(ext_modules) 1101 pass 1101 1102 1102 1103 code = setup(name = 'sage',
Note: See TracChangeset
for help on using the changeset viewer.
