Changeset 7725:d38173145837
- Timestamp:
- 12/02/07 01:46:33 (5 years ago)
- Branch:
- default
- Location:
- sage/rings/number_field
- Files:
-
- 3 edited
-
number_field_ideal.py (modified) (6 diffs)
-
number_field_ideal_rel.py (modified) (2 diffs)
-
order.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
sage/rings/number_field/number_field_ideal.py
r7479 r7725 42 42 import sage.rings.arith as arith 43 43 import sage.misc.misc as misc 44 from sage.rings.finite_field import FiniteField 44 45 45 46 import number_field … … 51 52 from sage.structure.element import generic_power 52 53 from sage.structure.factorization import Factorization 54 from sage.structure.sequence import Sequence 53 55 54 56 QQ = rational_field.RationalField() … … 200 202 Number Field in a with defining polynomial x^3 + 389 201 203 sage: I = K.factor_integer(17)[0][0]; I 202 Fractional ideal ( -100*a^2 + 730*a -5329)204 Fractional ideal (100*a^2 - 730*a + 5329) 203 205 sage: hnf = I.pari_hnf(); hnf 204 206 [17, 0, 13; 0, 17, 8; 0, 0, 1] … … 327 329 self.__pari_hnf = nf.idealadd(self.__pari_hnf, ideal) 328 330 return self.__pari_hnf 331 332 def basis(self): 333 """ 334 Return an immutable sequence of elements of this ideal (note: 335 their parent is the number field) that form a basis for this 336 ideal viewed as a ZZ-module. 337 338 OUTPUT: 339 basis -- an immutable sequence. 340 341 EXAMPLES: 342 sage: K.<z> = CyclotomicField(7) 343 sage: I = K.factor_integer(11)[0][0] 344 sage: I.basis() 345 [11, 11*z, 11*z^2, z^3 + 5*z^2 + 4*z + 10, z^4 + z^2 + z + 5, z^5 + z^4 + z^3 + 2*z^2 + 6*z + 5] 346 347 An example of a non-integral ideal. 348 sage: J = 1/I; J 349 Fractional ideal (2/11*z^5 + 2/11*z^4 + 3/11*z^3 + 2/11) 350 sage: J.basis() 351 [1, z, z^2, 1/11*z^3 + 7/11*z^2 + 6/11*z + 10/11, 1/11*z^4 + 1/11*z^2 + 1/11*z + 7/11, 1/11*z^5 + 1/11*z^4 + 1/11*z^3 + 2/11*z^2 + 8/11*z + 7/11] 352 """ 353 try: 354 return self.__basis 355 except AttributeError: 356 pass 357 hnf = self.pari_hnf() 358 v = self.__elements_from_hnf(hnf) 359 O = self.number_field().maximal_order() 360 self.__basis = Sequence(v, immutable=True) 361 return self.__basis 362 363 def free_module(self): 364 """ 365 Return the free ZZ-module contained in the vector space 366 associated to the ambient number field, that corresponds 367 to this ideal. 368 369 EXAMPLES: 370 sage: K.<z> = CyclotomicField(7) 371 sage: I = K.factor_integer(11)[0][0]; I 372 Fractional ideal (-2*z^4 - 2*z^2 - 2*z + 1) 373 sage: A = I.free_module(); A 374 Free module of degree 6 and rank 6 over Integer Ring 375 User basis matrix: 376 [11 0 0 0 0 0] 377 [ 0 11 0 0 0 0] 378 [ 0 0 11 0 0 0] 379 [10 4 5 1 0 0] 380 [ 5 1 1 0 1 0] 381 [ 5 6 2 1 1 1] 382 383 The ideal doesn't have to be integral: 384 sage: J = I^(-1) 385 sage: B = J.free_module(); B 386 Free module of degree 6 and rank 6 over Integer Ring 387 User basis matrix: 388 [ 1 0 0 0 0 0] 389 [ 0 1 0 0 0 0] 390 [ 0 0 1 0 0 0] 391 [10/11 6/11 7/11 1/11 0 0] 392 [ 7/11 1/11 1/11 0 1/11 0] 393 [ 7/11 8/11 2/11 1/11 1/11 1/11] 394 395 This also works for relative extensions: 396 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2]) 397 sage: I = K.fractional_ideal(4) 398 sage: I.free_module() 399 Free module of degree 4 and rank 4 over Integer Ring 400 User basis matrix: 401 [ 4 0 0 0] 402 [ -3 7 -1 1] 403 [ 3 7 1 1] 404 [ 0 -10 0 -2] 405 sage: J = I^(-1); J.free_module() 406 Free module of degree 4 and rank 4 over Integer Ring 407 User basis matrix: 408 [ 1/4 0 0 0] 409 [-3/16 7/16 -1/16 1/16] 410 [ 3/16 7/16 1/16 1/16] 411 [ 0 -5/8 0 -1/8] 412 413 An example of intersecting ideals by intersecting free modules. 414 sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8) 415 sage: I = K.factor_integer(2) 416 sage: p1 = I[0][0]; p2 = I[1][0] 417 sage: N = p1.free_module().intersection(p2.free_module()); N 418 Free module of degree 3 and rank 3 over Integer Ring 419 Echelon basis matrix: 420 [ 1 1/2 1/2] 421 [ 0 1 1] 422 [ 0 0 2] 423 sage: N.index_in(p1.free_module()).abs() 424 2 425 """ 426 try: 427 return self.__free_module 428 except AttributeError: 429 pass 430 M = basis_to_module(self.basis(), self.number_field()) 431 self.__free_module = M 432 return M 329 433 330 434 def divides(self, other): … … 699 803 return ZZ(self._pari_prime.getattr('e')) 700 804 raise ValueError, "the ideal (= %s) is not prime"%self 805 806 def _p_quotient(self, p): 807 """ 808 This is an internal technical function that is used for example for 809 computing the quotient of the ring of integers by a prime ideal. 810 811 INPUT: 812 p -- a prime number contained in self. 813 814 OUTPUT: 815 V -- a vector space of characteristic p 816 quo -- a partially defined quotient homomorphism from the 817 ambient number field to V 818 lift -- a section of quo. 819 820 EXAMPLES: 821 sage: K.<i> = NumberField(x^2 + 1); O = K.maximal_order() 822 sage: I = K.factor_integer(3)[0][0] 823 sage: Q, quo, lift = I._p_quotient(3); Q 824 Vector space quotient V/W of dimension 2 over Finite Field of size 3 where 825 V: Vector space of dimension 2 over Finite Field of size 3 826 W: Vector space of degree 2 and dimension 0 over Finite Field of size 3 827 Basis matrix: 828 [] 829 830 We do an example with a split prime and show byother the quo and lift maps: 831 sage: K.<i> = NumberField(x^2 + 1); O = K.maximal_order() 832 sage: I = K.factor_integer(5)[0][0] 833 sage: Q,quo,lift = I._p_quotient(5) 834 sage: lift(quo(i)) 835 3 836 sage: lift(quo(i)) - i in I 837 True 838 sage: quo(lift(Q.0)) 839 (1) 840 sage: Q.0 841 (1) 842 sage: Q 843 Vector space quotient V/W of dimension 1 over Finite Field of size 5 where 844 V: Vector space of dimension 2 over Finite Field of size 5 845 W: Vector space of degree 2 and dimension 1 over Finite Field of size 5 846 Basis matrix: 847 [1 3] 848 sage: quo 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 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) 852 """ 853 return quotient_char_p(self, p) 701 854 702 855 def residue_field(self, names=None): … … 849 1002 return False 850 1003 return True 1004 1005 1006 1007 def basis_to_module(B, K): 1008 """ 1009 Given a basis B of elements for a ZZ-submodule of a number field K, return 1010 the corresponding ZZ-submodule. 1011 1012 EXAMPLES: 1013 sage: K.<w> = NumberField(x^4 + 1) 1014 sage: from sage.rings.number_field.number_field_ideal import basis_to_module 1015 sage: basis_to_module([K.0, K.0^2 + 3], K) 1016 Free module of degree 4 and rank 2 over Integer Ring 1017 User basis matrix: 1018 [0 1 0 0] 1019 [3 0 1 0] 1020 """ 1021 V, from_V, to_V = K.absolute_vector_space() 1022 M = ZZ**(V.dimension()) 1023 C = [to_V(b) for b in B] 1024 return M.span_of_basis(C) 1025 1026 1027 class QuotientMap: 1028 def __init__(self, K, M_OK_change, Q, I): 1029 self.__M_OK_change = M_OK_change 1030 self.__Q = Q 1031 self.__K = K 1032 self.__I = I 1033 self.__L, self.__from_L, self.__to_L = K.absolute_vector_space() 1034 1035 def __call__(self, x): 1036 v = self.__to_L(x) 1037 w = v * self.__M_OK_change 1038 return self.__Q( list(w) ) 1039 1040 def __repr__(self): 1041 return "Partially defined quotient map from %s to an explicit vector space representation for the quotient of the ring of integers by (p,I) for the ideal I=%s."%(self.__K, self.__I) 1042 1043 class LiftMap: 1044 def __init__(self, OK, M_OK_map, Q, I): 1045 self.__I = I 1046 self.__OK = OK 1047 self.__Q = Q 1048 self.__M_OK_map = M_OK_map 1049 1050 def __call__(self, x): 1051 # This lifts to OK tensor F_p 1052 v = self.__Q.lift(x) 1053 # This lifts to ZZ^n (= OK) 1054 w = v.lift() 1055 # Write back in terms of K 1056 z = w * self.__M_OK_map 1057 return self.__OK(z.list()) 1058 1059 def __repr__(self): 1060 return "Lifting map to %s from quotient of integers by %s"%(self.__OK, self.__I) 1061 1062 def quotient_char_p(I, p): 1063 """ 1064 Given an integral ideal I that contains a prime number p, compute 1065 a vector space V = (OK mod p) / (I mod p), along with a 1066 homomorphism OK --> V and a section V --> OK. 1067 1068 EXAMPLES: 1069 sage: from sage.rings.number_field.number_field_ideal import quotient_char_p 1070 1071 sage: K.<i> = NumberField(x^2 + 1); O = K.maximal_order(); I = K.fractional_ideal(15) 1072 sage: quotient_char_p(I, 5)[0] 1073 Vector space quotient V/W of dimension 2 over Finite Field of size 5 where 1074 V: Vector space of dimension 2 over Finite Field of size 5 1075 W: Vector space of degree 2 and dimension 0 over Finite Field of size 5 1076 Basis matrix: 1077 [] 1078 sage: quotient_char_p(I, 3)[0] 1079 Vector space quotient V/W of dimension 2 over Finite Field of size 3 where 1080 V: Vector space of dimension 2 over Finite Field of size 3 1081 W: Vector space of degree 2 and dimension 0 over Finite Field of size 3 1082 Basis matrix: 1083 [] 1084 1085 sage: I = K.factor_integer(13)[0][0]; I 1086 Fractional ideal (-3*i - 2) 1087 sage: I.residue_class_degree() 1088 1 1089 sage: quotient_char_p(I, 13)[0] 1090 Vector space quotient V/W of dimension 1 over Finite Field of size 13 where 1091 V: Vector space of dimension 2 over Finite Field of size 13 1092 W: Vector space of degree 2 and dimension 1 over Finite Field of size 13 1093 Basis matrix: 1094 [1 8] 1095 """ 1096 if not I.is_integral(): 1097 raise ValueError, "I must be an integral ideal." 1098 1099 K = I.number_field() 1100 OK = K.maximal_order(p) # really only need a p-maximal order. 1101 M_OK = OK.free_module() 1102 M_I = I.free_module() 1103 1104 # Now we have to quite explicitly find a way to compute 1105 # with OK / I viewed as a quotient of two F_p vector space, 1106 # and itself viewed as an F_p vector space. 1107 1108 # Step 1. Write each basis vector for I (as a ZZ-module) 1109 # in terms of the basis for OK. 1110 B_I = M_I.basis() 1111 M_OK_mat = M_OK.basis_matrix() 1112 M_OK_change = M_OK_mat**(-1) 1113 B_I_in_terms_of_M = M_I.basis_matrix() * M_OK_change 1114 1115 # Step 2. Define "M_OK mod p" to just be (F_p)^n and 1116 # "M_I mod p" to be the reduction mod p of the elements 1117 # compute in step 1. 1118 n = K.degree() 1119 k = FiniteField(p) 1120 M_OK_modp = k**n 1121 B_mod = B_I_in_terms_of_M.change_ring(k) 1122 M_I_modp = M_OK_modp.span(B_mod.row_space()) 1123 1124 # Step 3. Compute the quotient of these two F_p vector space. 1125 Q = M_OK_modp.quotient(M_I_modp) 1126 1127 # Step 4. Now we get the maps we need from the above data. 1128 K_to_Q = QuotientMap(K, M_OK_change, Q, I) 1129 Q_to_OK = LiftMap(OK, M_OK_mat, Q, I) 1130 return Q, K_to_Q, Q_to_OK 1131 1132 1133 -
sage/rings/number_field/number_field_ideal_rel.py
r6990 r7725 23 23 24 24 from number_field_ideal import NumberFieldIdeal, convert_from_zk_basis 25 26 import sage.rings.rational_field as rational_field 27 QQ = rational_field.RationalField() 25 28 26 29 class NumberFieldIdeal_rel(NumberFieldIdeal): … … 99 102 """ 100 103 Return the multiplicative inverse of self. Call with ~self. 104 105 EXAMPLES: 106 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2]) 107 sage: I = K.fractional_ideal(4) 108 sage: I^(-1) 109 Fractional ideal (1/4) 110 sage: I * I^(-1) 111 Fractional ideal (1) 101 112 """ 102 113 if self.is_zero(): -
sage/rings/number_field/order.py
r7715 r7725 364 364 """ 365 365 raise NotImplementedError 366 367 def free_module(self): 368 """ 369 Return the free ZZ-module contained in the vector space 370 associated to the ambient number field, that corresponds 371 to this ideal. 372 373 EXAMPLES: 374 sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8) 375 sage: O = K.maximal_order(); O.basis() 376 [1, 1/2*a^2 + 1/2*a, a^2] 377 sage: O.free_module() 378 Free module of degree 3 and rank 3 over Integer Ring 379 User basis matrix: 380 [ 1 0 0] 381 [ 0 1/2 1/2] 382 [ 0 0 1] 383 384 An example in a relative extension. Notice that the module is a ZZ-module in the 385 absolute_field associated to the relative field: 386 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2]) 387 sage: O = K.maximal_order(); O.basis() 388 [(-3/2*b - 5)*a + 7/2*b - 2, (-3)*a + 2*b, (-2*b)*a - 3, (-7)*a + 5*b] 389 sage: O.free_module() 390 Free module of degree 4 and rank 4 over Integer Ring 391 User basis matrix: 392 [1/4 1/4 3/4 3/4] 393 [ 0 1/2 0 1/2] 394 [ 0 0 1 0] 395 [ 0 0 0 1] 396 """ 397 try: 398 return self.__free_module 399 except AttributeError: 400 pass 401 from number_field_ideal import basis_to_module 402 M = basis_to_module(self.basis(), self.number_field()) 403 self.__free_module = M 404 return M 366 405 367 406 def ring_generators(self):
Note: See TracChangeset
for help on using the changeset viewer.
