# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1197713024 28800
# Node ID 1099ef89b418560ff29c107c4292c0a1d929ed10
# Parent 77b659019e2f7a7c940012f278683c0214ab3806
Trac #1183 -- residue class fields (finish).
diff -r 77b659019e2f -r 1099ef89b418 sage/modules/free_module_element.pyx
a
|
b
|
cdef class FreeModuleElement_generic_den |
908 | 908 | raise TypeError, "entries (=%s) must be a list"%(entries, ) |
909 | 909 | |
910 | 910 | if len(entries) != self.degree(): |
911 | | raise ArithmeticError, "entries must be a list of length %s"%\ |
| 911 | raise TypeError, "entries must be a list of length %s"%\ |
912 | 912 | self.degree() |
913 | 913 | if coerce: |
914 | 914 | try: |
diff -r 77b659019e2f -r 1099ef89b418 sage/rings/finite_field.py
a
|
b
|
class FiniteField_prime_modn(FiniteField |
418 | 418 | return self.__char |
419 | 419 | |
420 | 420 | def gen(self, n=0): |
| 421 | """ |
| 422 | Return generator of this finite field. |
| 423 | |
| 424 | EXAMPLES: |
| 425 | sage: k = GF(13) |
| 426 | sage: k.gen() |
| 427 | 1 |
| 428 | sage: k.gen(1) |
| 429 | Traceback (most recent call last): |
| 430 | ... |
| 431 | IndexError: only one generator |
| 432 | """ |
| 433 | if n != 0: |
| 434 | raise IndexError, "only one generator" |
421 | 435 | return self.__gen |
422 | 436 | |
423 | 437 | def __iter__(self): |
diff -r 77b659019e2f -r 1099ef89b418 sage/rings/finite_field_givaro.pyx
a
|
b
|
cdef class FiniteField_givaro(FiniteFiel |
595 | 595 | |
596 | 596 | EXAMPLES: |
597 | 597 | sage: k = GF(3^4, 'b'); k.gen() |
598 | | b |
| 598 | b |
| 599 | sage: k.gen(1) |
| 600 | Traceback (most recent call last): |
| 601 | ... |
| 602 | IndexError: only one generator |
599 | 603 | """ |
600 | 604 | cdef int r |
601 | 605 | from sage.rings.arith import primitive_root |
diff -r 77b659019e2f -r 1099ef89b418 sage/rings/number_field/number_field.py
a
|
b
|
class NumberField_cyclotomic(NumberField |
4161 | 4161 | sage: O = K.maximal_order() |
4162 | 4162 | sage: K(O.1) |
4163 | 4163 | z |
4164 | | sage: sage: K(O.1^2 + O.1 - 2) |
| 4164 | sage: K(O.1^2 + O.1 - 2) |
4165 | 4165 | z^2 + z - 2 |
4166 | 4166 | """ |
4167 | 4167 | if isinstance(x, number_field_element.NumberFieldElement): |
diff -r 77b659019e2f -r 1099ef89b418 sage/rings/number_field/number_field_ideal.py
a
|
b
|
class NumberFieldIdeal(Ideal_fractional) |
848 | 848 | sage: quo |
849 | 849 | Partially defined quotient map from Number Field in i with defining polynomial x^2 + 1 to an explicit vector space representation for the quotient of the ring of integers by (p,I) for the ideal I=Fractional ideal (-i - 2). |
850 | 850 | sage: lift |
851 | | Lifting map to Order in Number Field in i with defining polynomial x^2 + 1 from quotient of integers by Fractional ideal (-i - 2) |
| 851 | Lifting map to Maximal Order in Number Field in i with defining polynomial x^2 + 1 from quotient of integers by Fractional ideal (-i - 2) |
852 | 852 | """ |
853 | 853 | return quotient_char_p(self, p) |
854 | 854 | |
… |
… |
def basis_to_module(B, K): |
1020 | 1020 | """ |
1021 | 1021 | V, from_V, to_V = K.absolute_vector_space() |
1022 | 1022 | M = ZZ**(V.dimension()) |
1023 | | C = [to_V(K(b.list())) for b in B] |
| 1023 | C = [to_V(K(b)) for b in B] |
1024 | 1024 | return M.span_of_basis(C) |
1025 | 1025 | |
1026 | 1026 | |
diff -r 77b659019e2f -r 1099ef89b418 sage/rings/residue_field.pyx
a
|
b
|
EXAMPLES: |
12 | 12 | sage: k.order() |
13 | 13 | 841 |
14 | 14 | |
| 15 | We reduce mod a prime for which the ring of integers is not |
| 16 | monogenic (i.e., 2 is an essential discriminant divisor): |
| 17 | sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8) |
| 18 | sage: F = K.factor_integer(2); F |
| 19 | (Fractional ideal (1/2*a^2 - 1/2*a + 1)) * (Fractional ideal (a^2 - 2*a + 3)) * (Fractional ideal (3/2*a^2 - 5/2*a + 4)) |
| 20 | sage: F[0][0].residue_field() |
| 21 | Residue field of Fractional ideal (1/2*a^2 - 1/2*a + 1) |
| 22 | sage: F[1][0].residue_field() |
| 23 | Residue field of Fractional ideal (a^2 - 2*a + 3) |
| 24 | sage: F[2][0].residue_field() |
| 25 | Residue field of Fractional ideal (3/2*a^2 - 5/2*a + 4) |
| 26 | |
15 | 27 | AUTHORS: |
16 | 28 | -- David Roe (2007-10-3): initial version |
17 | 29 | -- William Stein (2007-12): bug fixes |
… |
… |
TESTS: |
23 | 35 | sage: a = ff(z) |
24 | 36 | sage: parent(a*a) |
25 | 37 | Residue field in zbar of Fractional ideal (17) |
| 38 | |
| 39 | Reducing a curve modulo a prime: |
| 40 | sage: K.<s> = NumberField(x^2+23) |
| 41 | sage: OK = K.ring_of_integers() |
| 42 | sage: E = EllipticCurve([0,0,0,K(1),K(5)]) |
| 43 | sage: pp = K.factor_integer(13)[0][0] |
| 44 | sage: Fpp = OK.residue_field(pp) |
| 45 | sage: E.base_extend(Fpp) |
| 46 | Elliptic Curve defined by y^2 = x^3 + x + 5 over Residue field of Fractional ideal (13, s - 4) |
26 | 47 | """ |
27 | 48 | |
28 | 49 | #***************************************************************************** |
… |
… |
from sage.rings.polynomial.polynomial_ri |
55 | 76 | |
56 | 77 | residue_field_cache = {} |
57 | 78 | |
58 | | def ResidueField(p, names = None, check = True, trygen=False): |
| 79 | def ResidueField(p, names = None, check = True): |
59 | 80 | """ |
60 | 81 | A function that returns the residue class field of a prime ideal p |
61 | 82 | of the ring of integers of a number field. |
… |
… |
def ResidueField(p, names = None, check |
126 | 147 | names = str(names[0]) |
127 | 148 | else: |
128 | 149 | names = None |
129 | | key = (p, names, trygen) |
| 150 | key = (p, names) |
130 | 151 | if residue_field_cache.has_key(key): |
131 | 152 | k = residue_field_cache[key]() |
132 | 153 | if k is not None: |
… |
… |
def ResidueField(p, names = None, check |
151 | 172 | n = p.residue_class_degree() |
152 | 173 | gen_ok = False |
153 | 174 | from sage.matrix.constructor import matrix |
154 | | if trygen: |
155 | | # This optimization not ready yet. |
156 | | try: |
157 | | x = K.gen() |
158 | | M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]) |
159 | | print M |
160 | | W = M.transpose().echelon_form() |
161 | | if M.rank() == n: |
162 | | PB = M.matrix_from_rows(range(n)) |
163 | | gen_ok = True |
164 | | f = R((-W.column(n)).list() + [1]) |
165 | | except (TypeError, ZeroDivisionError): |
166 | | pass |
| 175 | try: |
| 176 | x = K.gen() |
| 177 | M = matrix(k, n+1, n, [to_vs(x**i).list() for i in range(n+1)]) |
| 178 | W = M.transpose().echelon_form() |
| 179 | if M.rank() == n: |
| 180 | PB = M.matrix_from_rows(range(n)) |
| 181 | gen_ok = True |
| 182 | f = R((-W.column(n)).list() + [1]) |
| 183 | except (TypeError, ZeroDivisionError): |
| 184 | pass |
167 | 185 | if not gen_ok: |
168 | 186 | bad = True |
169 | 187 | for u in U: # using this iterator may not be optimal, we may get a long string of non-generators |
… |
… |
class ResidueField_generic(Field): |
199 | 217 | class ResidueField_generic(Field): |
200 | 218 | """ |
201 | 219 | The class representing a generic residue field. |
| 220 | |
| 221 | EXAMPLES: |
| 222 | sage: I = QQ[i].factor_integer(2)[0][0]; I |
| 223 | Fractional ideal (I + 1) |
| 224 | sage: k = I.residue_field(); k |
| 225 | Residue field of Fractional ideal (I + 1) |
| 226 | sage: type(k) |
| 227 | <class 'sage.rings.residue_field.ResidueFiniteField_prime_modn'> |
202 | 228 | """ |
203 | 229 | def __init__(self, p, f, intp): |
204 | 230 | """ |
… |
… |
class ResidueField_generic(Field): |
232 | 258 | |
233 | 259 | def lift(self, x): |
234 | 260 | """ |
235 | | Returns a lift of x to the Order, returning a "polynomial" in the generator with coefficients between 0 and p-1. |
236 | | |
| 261 | Returns a lift of x to the Order, returning a "polynomial" in the |
| 262 | generator with coefficients between 0 and $p-1$. |
| 263 | |
237 | 264 | EXAMPLES: |
238 | 265 | sage: K.<a> = NumberField(x^3-7) |
239 | 266 | sage: P = K.ideal(29).factor()[0][0] |
… |
… |
class ResidueField_generic(Field): |
251 | 278 | else: |
252 | 279 | return self.f.lift(x) |
253 | 280 | |
| 281 | def reduction_map(self): |
| 282 | """ |
| 283 | Return the partially defined reduction map from the number |
| 284 | field to this residue class field. |
| 285 | |
| 286 | EXAMPLES: |
| 287 | sage: I = QQ[2^(1/3)].factor_integer(2)[0][0]; I |
| 288 | Fractional ideal (-a) |
| 289 | sage: k = I.residue_field(); k |
| 290 | Residue field of Fractional ideal (-a) |
| 291 | sage: pi = k.reduction_map(); pi |
| 292 | Partially defined reduction map from Number Field in a with defining polynomial x^3 - 2 to Residue field of Fractional ideal (-a) |
| 293 | sage: pi.domain() |
| 294 | Number Field in a with defining polynomial x^3 - 2 |
| 295 | sage: pi.codomain() |
| 296 | Residue field of Fractional ideal (-a) |
| 297 | """ |
| 298 | return self._structure[0] |
| 299 | |
| 300 | def lift_map(self): |
| 301 | """ |
| 302 | EXAMPLES: |
| 303 | sage: I = QQ[3^(1/3)].factor_integer(5)[1][0]; I |
| 304 | Fractional ideal (-a + 2) |
| 305 | sage: k = I.residue_field(); k |
| 306 | Residue field of Fractional ideal (-a + 2) |
| 307 | sage: f = k.lift_map(); f |
| 308 | Lifting map from Residue field of Fractional ideal (-a + 2) to Number Field in a with defining polynomial x^3 - 3 |
| 309 | sage: f.domain() |
| 310 | Residue field of Fractional ideal (-a + 2) |
| 311 | sage: f.codomain() |
| 312 | Number Field in a with defining polynomial x^3 - 3 |
| 313 | sage: f(k.0) |
| 314 | 1 |
| 315 | """ |
| 316 | return self._structure[1] |
| 317 | |
254 | 318 | def __cmp__(self, x): |
255 | 319 | """ |
256 | | Compares two residue fields: they are equal iff the primes defining them are equal. |
| 320 | Compares two residue fields: they are equal iff the primes |
| 321 | defining them are equal. |
257 | 322 | |
258 | 323 | EXAMPLES: |
259 | 324 | sage: K.<a> = NumberField(x^3-11) |
… |
… |
class ResidueField_generic(Field): |
272 | 337 | return cmp(type(self), type(x)) |
273 | 338 | |
274 | 339 | class ReductionMap: |
| 340 | """ |
| 341 | A reduction map from a (subset) of a number field to this residue |
| 342 | class field. |
| 343 | |
| 344 | EXAMPLES: |
| 345 | sage: I = QQ[sqrt(17)].factor_integer(5)[0][0]; I |
| 346 | Fractional ideal (5) |
| 347 | sage: k = I.residue_field(); k |
| 348 | Residue field in sqrt17bar of Fractional ideal (5) |
| 349 | sage: R = k.reduction_map(); R |
| 350 | Partially defined reduction map from Number Field in sqrt17 with defining polynomial x^2 - 17 to Residue field in sqrt17bar of Fractional ideal (5) |
| 351 | """ |
275 | 352 | def __init__(self, K, F, to_vs, PBinv): |
| 353 | """ |
| 354 | Create a reduction map. |
| 355 | |
| 356 | EXAMPLES: |
| 357 | sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8) |
| 358 | sage: F = K.factor_integer(2)[0][0].residue_field() |
| 359 | sage: F.reduction_map() |
| 360 | Partially defined reduction map from Number Field in a with defining polynomial x^3 + x^2 - 2*x + 8 to Residue field of Fractional ideal (1/2*a^2 - 1/2*a + 1) |
| 361 | """ |
276 | 362 | self.__K = K |
277 | 363 | self.__F = F # finite field |
278 | 364 | self.__to_vs = to_vs |
279 | 365 | self.__PBinv = PBinv |
280 | 366 | |
| 367 | def domain(self): |
| 368 | """ |
| 369 | Return the domain of this reduction map. |
| 370 | |
| 371 | EXAMPLES: |
| 372 | sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 32) |
| 373 | sage: F = K.factor_integer(2)[0][0].residue_field() |
| 374 | sage: F.reduction_map().domain() |
| 375 | Number Field in a with defining polynomial x^3 + x^2 - 2*x + 32 |
| 376 | """ |
| 377 | return self.__K |
| 378 | |
| 379 | def codomain(self): |
| 380 | """ |
| 381 | Return the codomain of this reduction map. |
| 382 | |
| 383 | EXAMPLES: |
| 384 | sage: K.<a> = NumberField(x^3 + 128) |
| 385 | sage: F = K.factor_integer(2)[0][0].residue_field() |
| 386 | sage: F.reduction_map().codomain() |
| 387 | Residue field of Fractional ideal (-1/4*a) |
| 388 | """ |
| 389 | return self.__F |
| 390 | |
281 | 391 | def __call__(self, x): |
| 392 | """ |
| 393 | Apply this reduction map to an element that coerces into the number field. |
| 394 | |
| 395 | If x doesn't map because the denominator is not coprime to the |
| 396 | prime ideal, then a ZeroDivisionError exception is raised. |
| 397 | |
| 398 | EXAMPLES: |
| 399 | sage: K.<a> = NumberField(x^2 + 1) |
| 400 | sage: F = K.factor_integer(2)[0][0].residue_field() |
| 401 | sage: r = F.reduction_map(); r |
| 402 | Partially defined reduction map from Number Field in a with defining polynomial x^2 + 1 to Residue field of Fractional ideal (a + 1) |
| 403 | sage: r(2 + a) |
| 404 | 1 |
| 405 | sage: r(a/2) |
| 406 | Traceback (most recent call last): |
| 407 | ... |
| 408 | ZeroDivisionError: Inverse does not exist. |
| 409 | """ |
282 | 410 | # The reduction map is just x |--> F(to_vs(x) * (PB**(-1))) |
283 | 411 | x = self.__K(x) |
284 | 412 | return self.__F(self.__to_vs(x) * self.__PBinv) |
285 | 413 | |
286 | 414 | def __repr__(self): |
| 415 | """ |
| 416 | EXAMPLES: |
| 417 | sage: K.<theta_5> = CyclotomicField(5) |
| 418 | sage: F = K.factor_integer(7)[0][0].residue_field() |
| 419 | sage: F.reduction_map().__repr__() |
| 420 | 'Partially defined reduction map from Cyclotomic Field of order 5 and degree 4 to Residue field in theta_5bar of Fractional ideal (7)' |
| 421 | """ |
287 | 422 | return "Partially defined reduction map from %s to %s"%(self.__K, self.__F) |
288 | 423 | |
289 | 424 | class LiftingMap: |
| 425 | """ |
| 426 | Lifting map from residue class field to number field. |
| 427 | |
| 428 | EXAMPLES: |
| 429 | sage: K.<a> = NumberField(x^3 + 2) |
| 430 | sage: F = K.factor_integer(5)[0][0].residue_field() |
| 431 | sage: F.degree() |
| 432 | 2 |
| 433 | sage: L = F.lift_map(); L |
| 434 | Lifting map from Residue field in abar of Fractional ideal (a^2 + 2*a - 1) to Number Field in a with defining polynomial x^3 + 2 |
| 435 | sage: L(F.0^2) |
| 436 | 3*a + 1 |
| 437 | sage: L(3*a + 1) == F.0^2 |
| 438 | True |
| 439 | """ |
290 | 440 | def __init__(self, K, F, to_order, PB): |
| 441 | """ |
| 442 | Create a lifting map. |
| 443 | |
| 444 | EXAMPLES: |
| 445 | sage: K.<theta_5> = CyclotomicField(5) |
| 446 | sage: F = K.factor_integer(7)[0][0].residue_field() |
| 447 | sage: F.lift_map() |
| 448 | Lifting map from Residue field in theta_5bar of Fractional ideal (7) to Cyclotomic Field of order 5 and degree 4 |
| 449 | """ |
291 | 450 | self.__K = K |
292 | 451 | self.__F = F # finite field |
293 | 452 | self.__to_order = to_order |
294 | 453 | self.__PB = PB |
295 | 454 | |
| 455 | def domain(self): |
| 456 | """ |
| 457 | Return the domain of this lifting map. |
| 458 | |
| 459 | EXAMPLES: |
| 460 | sage: K.<a> = NumberField(x^5 + 2) |
| 461 | sage: F = K.factor_integer(7)[0][0].residue_field() |
| 462 | sage: L = F.lift_map(); L |
| 463 | Lifting map from Residue field in abar of Fractional ideal (-2*a^4 + a^3 - 4*a^2 + 2*a - 1) to Number Field in a with defining polynomial x^5 + 2 |
| 464 | sage: L.domain() |
| 465 | Residue field in abar of Fractional ideal (-2*a^4 + a^3 - 4*a^2 + 2*a - 1) |
| 466 | """ |
| 467 | return self.__F |
| 468 | |
| 469 | def codomain(self): |
| 470 | """ |
| 471 | Return the codomain of this lifting map. |
| 472 | |
| 473 | EXAMPLES: |
| 474 | sage: K.<a> = CyclotomicField(7) |
| 475 | sage: F = K.factor_integer(5)[0][0].residue_field() |
| 476 | sage: L = F.lift_map(); L |
| 477 | Lifting map from Residue field in abar of Fractional ideal (5) to Cyclotomic Field of order 7 and degree 6 |
| 478 | sage: L.codomain() |
| 479 | Cyclotomic Field of order 7 and degree 6 |
| 480 | """ |
| 481 | return self.__K |
| 482 | |
296 | 483 | def __call__(self, x): |
| 484 | """ |
| 485 | Lift from this residue class field to the number field. |
| 486 | |
| 487 | EXAMPLES: |
| 488 | sage: K.<a> = CyclotomicField(7) |
| 489 | sage: F = K.factor_integer(5)[0][0].residue_field() |
| 490 | sage: L = F.lift_map(); L |
| 491 | Lifting map from Residue field in abar of Fractional ideal (5) to Cyclotomic Field of order 7 and degree 6 |
| 492 | sage: L(F.0) |
| 493 | a |
| 494 | sage: F(a) |
| 495 | abar |
| 496 | """ |
297 | 497 | # The lifting map is just x |--> to_order(x * PB) |
298 | 498 | x = self.__F(x) |
299 | 499 | v = x.polynomial().padded_list(self.__F.degree()) |
300 | 500 | return self.__to_order(self.__PB.linear_combination_of_rows(v)) |
301 | 501 | |
302 | 502 | def __repr__(self): |
| 503 | """ |
| 504 | EXAMPLES: |
| 505 | sage: K.<theta_12> = CyclotomicField(12) |
| 506 | sage: F.<tmod> = K.factor_integer(7)[0][0].residue_field() |
| 507 | sage: F.lift_map().__repr__() |
| 508 | 'Lifting map from Residue field in tmod of Fractional ideal (-3*theta_12^2 + 1) to Cyclotomic Field of order 12 and degree 4' |
| 509 | """ |
303 | 510 | return "Lifting map from %s to %s"%(self.__F, self.__K) |
304 | 511 | |
305 | 512 | cdef class NFResidueFieldHomomorphism(ResidueFieldHomomorphism): |
… |
… |
class ResidueFiniteField_givaro(ResidueF |
585 | 792 | except: |
586 | 793 | raise TypeError |
587 | 794 | |
588 | | #try: |
589 | | # return self.coerce_map_from(self.f.domain())(self.f.domain()(x)) |
590 | | #except (AttributeError, TypeError): |
591 | | # return FiniteField_givaro.__call__(self, x) |
592 | 795 | |
593 | 796 | |