Ticket #9541: trac_9541-part10-libsingular_technical_stuff.patch
File trac_9541-part10-libsingular_technical_stuff.patch, 53.8 KB (added by , 12 years ago) |
---|
-
module_list.py
# HG changeset patch # User William Stein <wstein@gmail.com> # Date 1279980735 25200 # Node ID 33929e45edc22b90bca891fc02d692d0d8514694 # Parent 313613462727c43cf4142c5b82c73b5009dd67b1 [mq]: trac_9541-part10-libsingular_technical_stuff.patch diff -r 313613462727 -r 33929e45edc2 module_list.py
a b 1217 1217 extra_compile_args=["-std=c99", "-D_XPG6"] 1218 1218 ), 1219 1219 1220 Extension('sage.rings.number_field.number_field_fast', 1221 sources = ['sage/rings/number_field/number_field_fast.pyx']), 1222 1220 1223 Extension('sage.rings.number_field.number_field_element', 1221 1224 sources = ['sage/rings/number_field/number_field_element.pyx']), 1222 1225 -
sage/libs/flint/fmpq_poly.c
diff -r 313613462727 -r 33929e45edc2 sage/libs/flint/fmpq_poly.c
a b 3555 3555 3556 3556 if (fmpq_poly_is_zero(op)) 3557 3557 { 3558 str = calloc(2, sizeof(char));3558 str = (char*) calloc(2, sizeof(char)); 3559 3559 str[0] = '0'; 3560 3560 str[1] = '\0'; 3561 3561 return str; … … 3581 3581 } 3582 3582 3583 3583 mpq_init(q); 3584 str = calloc(len, sizeof(char));3584 str = (char*) calloc(len, sizeof(char)); 3585 3585 sprintf(str, "%lu", fmpq_poly_length(op)); 3586 3586 for (j = 0; str[j] != '\0'; j++); 3587 3587 str[j++] = ' '; … … 3625 3625 3626 3626 if (fmpq_poly_is_zero(op)) /* Zero polynomial */ 3627 3627 { 3628 str = calloc(2, sizeof(char));3628 str = (char*) calloc(2, sizeof(char)); 3629 3629 str[0] = '0'; 3630 3630 str[1] = '\0'; 3631 3631 return str; … … 3674 3674 } 3675 3675 3676 3676 mpq_init(q); 3677 str = calloc(len, sizeof(char));3677 str = (char*) calloc(len, sizeof(char)); 3678 3678 j = 0; 3679 3679 3680 3680 /* Print the leading term */ -
sage/rings/integer_ring.pyx
diff -r 313613462727 -r 33929e45edc2 sage/rings/integer_ring.pyx
a b 227 227 228 228 def __init__(self): 229 229 ParentWithGens.__init__(self, self, ('x',), normalize=False, category = EuclideanDomains()) 230 self._populate_coercion_lists_(element_constructor=integer.Integer, 230 self._populate_coercion_lists_(element_constructor=integer.Integer, 231 231 init_no_parent=True, 232 232 convert_method_name='_integer_') 233 233 -
sage/rings/number_field/implementation.pxd
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/implementation.pxd
a b 15 15 cdef class ArithmeticImplementation_flint(ArithmeticImplementation): 16 16 cdef fmpq_poly_t modulus 17 17 18 cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation):19 cdef object nf_t_wrap20 cdef object ideal21 cdef object ring22 23 18 cdef class ArithmeticImplementation_quadratic(ArithmeticImplementation): 24 19 pass -
sage/rings/number_field/implementation.pyx
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/implementation.pyx
a b 178 178 """ 179 179 return True 180 180 181 from number_field_element_libsingular import nf_t_wrap182 183 cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation):184 def __init__(self, ideal):185 """186 EXAMPLES::187 188 sage: sage.rings.number_field.implementation.ArithmeticImplementation_libsingular()189 Arithmetic implementation 'singular'190 """191 ArithmeticImplementation.__init__(self, 'singular')192 self.nf_t_wrap = nf_t_wrap(ideal)193 self.ideal = ideal194 self.ring = ideal.ring()195 196 181 cdef class ArithmeticImplementation_quadratic(ArithmeticImplementation): 197 182 def __init__(self): 198 183 """ -
sage/rings/number_field/maps.py
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/maps.py
a b 731 731 """ 732 732 return self.__to_V(self.__to_K(x)) 733 733 734 #################################################### 735 # Maps between relative number fields and towers of 736 # univariate quotient polynomial rings. 737 #################################################### 738 739 class MapRelativeNumberFieldToPolynomialQuotientTower(NumberFieldIsomorphism): 740 def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0): 741 """ 742 The isomorphism from a relative number field to a polynomial 743 quotient tower, which sends the generator for the relative number 744 field to the generator for the quotient ring, and sends the bases 745 as specified. 746 747 INPUT: 748 - `K` -- relative number field 749 - `Q` -- quotient of multivariate polynomial ring 750 - ``base_Q0_to_K0`` -- map on base from poly quotient ring to base field 751 - ``base_K0_to_Q0`` -- map on base from base field to poly quotient ring 752 753 EXAMPLES:: 754 755 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower() 756 sage: t 757 Isomorphism map: 758 From: Number Field in a with defining polynomial x^2 + 7 over its base field 759 To: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7 760 """ 761 self._K = K 762 self._Q = Q 763 self._base_Q0_to_K0 = base_Q0_to_K0 764 self._base_K0_to_Q0 = base_K0_to_Q0 765 NumberFieldIsomorphism.__init__(self, Hom(K, Q)) 766 767 def __cmp__(self, right): 768 """ 769 EXAMPLES:: 770 771 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower() 772 sage: loads(dumps(t)) == t 773 True 774 """ 775 c = cmp(type(self),type(right)) 776 if c: return c 777 return cmp((self._K,self._Q), (right._K,right._Q)) 778 779 def _call_(self, x): 780 """ 781 EXAMPLES:: 782 783 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t=K.polynomial_quotient_tower() 784 sage: r = K.random_element(); r 785 (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95 786 sage: t(r) 787 (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95 788 sage: f(t(r)) == r 789 True 790 """ 791 f = x.relative_polynomial() 792 v = [self._base_K0_to_Q0(a) for a in f.list()] 793 return self._Q(v) 794 795 def inverse(self): 796 """ 797 Return the inverse of this isomorphism. 798 799 EXAMPLES:: 800 801 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.polynomial_quotient_tower() 802 sage: t.inverse() 803 Isomorphism map: 804 From: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7 805 To: Number Field in a with defining polynomial x^2 + 7 over its base field 806 """ 807 return PolynomialQuotientTowerToRelativeNumberField( 808 self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0) 809 810 class PolynomialQuotientTowerToRelativeNumberField(NumberFieldIsomorphism): 811 def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0): 812 """ 813 The isomorphism from a polynomial quotient tower to a relative 814 number field, which sends the generator for the quotient ring to 815 the generator for the relative number field, and sends the bases 816 as specified. 817 818 EXAMPLES:: 819 820 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower() 821 sage: f 822 Isomorphism map: 823 From: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7 824 To: Number Field in a with defining polynomial x^2 + 7 over its base field 825 """ 826 self._K = K 827 self._Q = Q 828 self._base_Q0_to_K0 = base_Q0_to_K0 829 self._base_K0_to_Q0 = base_K0_to_Q0 830 NumberFieldIsomorphism.__init__(self, Hom(Q,K)) 831 832 def __cmp__(self, right): 833 """ 834 EXAMPLES:: 835 836 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t=K.polynomial_quotient_tower() 837 sage: loads(dumps(f)) == f 838 True 839 """ 840 c = cmp(type(self),type(right)) 841 if c: return c 842 return cmp((self._K,self._Q), (right._K,right._Q)) 843 844 def _call_(self, x): 845 """ 846 EXAMPLES:: 847 848 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower() 849 sage: r = Q.random_element() 850 sage: f(r) 851 (-12*b^2 + 1/2*b - 1/95)*a - 1/2*b^2 - 4 852 sage: t(f(r)) == r 853 True 854 """ 855 v = [self._base_Q0_to_K0(a) for a in x.list()] 856 return self._K(v) 857 858 def inverse(self): 859 """ 860 Return the inverse of this isomorphism. 861 862 EXAMPLES:: 863 864 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower() 865 sage: f.inverse() 866 Isomorphism map: 867 From: Number Field in a with defining polynomial x^2 + 7 over its base field 868 To: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7 869 """ 870 return MapRelativeNumberFieldToPolynomialQuotientTower( 871 self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0) 872 873 874 #################################################### 875 # Maps between relative number fields and a quotient 876 # of a multivariate polynomial ring over QQ. 877 #################################################### 878 879 class MapRelativeNumberFieldToMPolynomialQuotient(NumberFieldIsomorphism): 880 def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0): 881 """ 882 The isomorphism from a relative number field to a quotient of a 883 multivariate polynomial ring. 884 885 EXAMPLES:: 886 887 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 888 sage: t 889 Isomorphism map: 890 From: Number Field in a with defining polynomial x^2 + 7 over its base field 891 To: Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7) 892 893 Notice above that amusingly that there are two distinct variables 894 that both print as x. Sage should deal with this just fine. 895 """ 896 self._K = K 897 self._Q = Q 898 self._base_Q0_to_K0 = base_Q0_to_K0 899 self._base_K0_to_Q0 = base_K0_to_Q0 900 Q0 = base_Q0_to_K0.domain() 901 self._phi = Q0.cover_ring().hom(Q.gens()[1:]) 902 903 NumberFieldIsomorphism.__init__(self, Hom(K, Q)) 904 905 def _call_(self, x): 906 """ 907 EXAMPLES:: 908 909 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 910 sage: r = K.random_element(); r 911 (79797/95*b^2 + 135*b - 55473/95)*a - 91/2*b^2 + 279184/95*b + 161878/95 912 sage: t(r) 913 79797/95*a*b^2 + 135*a*b - 91/2*b^2 - 55473/95*a + 279184/95*b + 161878/95 914 sage: f(t(r)) == r 915 True 916 """ 917 f = x.relative_polynomial() 918 x = self._Q.gen(0) 919 return sum(self._phi(self._base_K0_to_Q0(a).lift())*x**i for i,a in enumerate(f.list())) 920 921 def __cmp__(self, right): 922 """ 923 EXAMPLES:: 924 925 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 926 sage: loads(dumps(t)) == t 927 True 928 """ 929 c = cmp(type(self),type(right)) 930 if c: return c 931 return cmp((self._K,self._Q), (right._K,right._Q)) 932 933 def inverse(self): 934 """ 935 Return the inverse of this isomorphism. 936 937 EXAMPLES:: 938 939 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 940 sage: t.inverse() 941 Isomorphism map: 942 From: Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7) 943 To: Number Field in a with defining polynomial x^2 + 7 over its base field 944 """ 945 return MPolynomialQuotientToRelativeNumberField( 946 self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0) 947 948 class MPolynomialQuotientToRelativeNumberField(NumberFieldIsomorphism): 949 def __init__(self, K, Q, base_Q0_to_K0, base_K0_to_Q0): 950 """ 951 The isomorphism from a quotient of a multivariate polynomial ring 952 to a relative number field. 953 954 EXAMPLES:: 955 956 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 957 sage: f 958 Isomorphism map: 959 From: Quotient of Multivariate Polynomial Ring in x, x over Rational Field by the ideal (x^3 + 2, x^2 + 7) 960 To: Number Field in a with defining polynomial x^2 + 7 over its base field 961 962 TESTS:: 963 sage: loads(dumps(f)) == f 964 """ 965 self._K = K 966 self._Q = Q 967 self._base_Q0_to_K0 = base_Q0_to_K0 968 self._base_K0_to_Q0 = base_K0_to_Q0 969 Q0 = base_Q0_to_K0.domain() 970 971 NumberFieldIsomorphism.__init__(self, Hom(Q,K)) 972 973 def _call_(self, x): 974 """ 975 EXAMPLES:: 976 977 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower() 978 sage: r = Q.random_element() 979 sage: f(r) 980 (-12*b^2 + 1/2*b - 1/95)*a - 1/2*b^2 - 4 981 sage: t(f(r)) == r 982 True 983 """ 984 # psi has to be initialized outside of __init__, because the __init__ method 985 # above is called *during* the construction of K. 986 if not hasattr(self, '_psi'): 987 self._psi = Q.hom([K.gen()] + [K(base_Q0_to_K0(g)) for g in Q0.gens()]) 988 return self._psi(x) 989 990 def __cmp__(self, right): 991 """ 992 EXAMPLES:: 993 994 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q, f, t = K.multi_polynomial_quotient_ring() 995 sage: loads(dumps(f)) == f 996 True 997 """ 998 c = cmp(type(self),type(right)) 999 if c: return c 1000 return cmp((self._K,self._Q), (right._K,right._Q)) 1001 1002 def inverse(self): 1003 """ 1004 Return the inverse of this isomorphism. 1005 1006 EXAMPLES:: 1007 1008 sage: K.<a,b> = NumberField([x^2 + 7, x^3 + 2]); Q,f,t = K.polynomial_quotient_tower() 1009 sage: f.inverse() 1010 Isomorphism map: 1011 From: Number Field in a with defining polynomial x^2 + 7 over its base field 1012 To: Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^2 + 7 1013 """ 1014 return MapRelativeNumberFieldToPolynomialQuotientTower( 1015 self._K, self._Q, self._base_Q0_to_K0, self._base_K0_to_Q0) -
sage/rings/number_field/morphism.py
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/morphism.py
a b 256 256 """ 257 257 def __call__(self, im_gen, base_hom=None, check=True): 258 258 """ 259 EXAMPLES:: 260 259 261 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3]); H = Hom(K,K); H 260 262 Automorphism group of Number Field in a with defining polynomial x^2 + 1 over its base field 261 263 sage: type(H) -
sage/rings/number_field/number_field.py
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field.py
a b 2 2 Number Fields 3 3 4 4 AUTHORS: 5 6 - William Stein (2004, 2005): initial version 7 8 - Steven Sivek (2006-05-12): added support for relative extensions 9 10 - William Stein (2007-09-04): major rewrite and documentation 11 12 - Robert Bradshaw (2008-10): specified embeddings into ambient fields 5 - William Stein (2004, 2005): initial version 6 - Steven Sivek (2006-05-12): added support for relative extensions 7 - William Stein (2007-09-04): major rewrite and documentation 8 - Robert Bradshaw (2008-10): specified embeddings into ambient fields 13 9 14 10 .. note:: 15 11 … … 256 252 # - 'generic' 257 253 # - 'singular' 258 254 #DEFAULT_IMPLEMENTATION = {'relative':'generic', 'absolute':'generic'} 259 DEFAULT_IMPLEMENTATION = {'relative':' ntl', 'absolute':'ntl'}255 DEFAULT_IMPLEMENTATION = {'relative':'singular', 'absolute':'flint'} 260 256 261 257 _nf_cache = {} 262 258 def NumberField(polynomial, name=None, check=True, names=None, cache=True, … … 481 477 482 478 R = polynomial.base_ring() 483 479 polynomial = polynomial.change_ring(R.fraction_field()) 484 480 481 implementation = 'flint' 485 482 if implementation == 'default': 483 # disable quadratic for now, since flint is fast and quadratic causes lots of trouble 486 484 if polynomial.degree() == 2 and polynomial.base_ring() == QQ: 487 485 implementation = 'quadratic' 488 486 else: … … 502 500 _nf_cache[key] = weakref.ref(S) 503 501 return S 504 502 505 if polynomial.degree() == 2: 503 # TODO -- ?? 504 if False and polynomial.degree() == 2: 506 505 K = NumberField_quadratic(polynomial, name, latex_name, check, embedding, implementation=implementation) 507 506 else: 508 507 K = NumberField_absolute(polynomial, name, latex_name, check, embedding, implementation=implementation) … … 1014 1013 self._integral_basis_dict = {} 1015 1014 embedding = number_field_morphisms.create_embedding_from_approx(self, embedding) 1016 1015 self._populate_coercion_lists_(embedding=embedding) 1017 1016 1018 1017 def _element_constructor_(self, x): 1019 1018 r""" 1020 1019 Make x into an element of this number field, possibly not canonically. … … 1871 1870 c = cmp(self.variable_name(), other.variable_name()) 1872 1871 if c: return c 1873 1872 # compare coefficients so that the polynomial variable does not count 1874 c = cmp(list(self. __polynomial), list(other.__polynomial))1873 c = cmp(list(self.relative_polynomial()), list(other.relative_polynomial())) 1875 1874 if c: return c 1876 1875 # compare implementations 1877 1876 c = cmp(self.implementation(), other.implementation()) … … 3341 3340 if implementation == 'quadratic': 3342 3341 # extension of quadratic must be represented by ntl 3343 3342 implementation = 'ntl' 3343 if implementation == 'flint': 3344 implementation = 'singular' 3344 3345 if not isinstance(poly, polynomial_element.Polynomial): 3345 3346 try: 3346 3347 poly = poly.polynomial(self) … … 3353 3354 if name is None: 3354 3355 raise TypeError, "the variable name must be specified." 3355 3356 from sage.rings.number_field.number_field_rel import NumberField_relative 3356 return NumberField_relative(self, poly, str(name), check=check, 3357 embedding=embedding, implementation=implementation) 3357 if implementation == 'singular': 3358 from number_field_fast import NumberField_libsingular 3359 return NumberField_libsingular(self, poly, str(name), check=check, 3360 embedding=embedding, implementation=implementation) 3361 else: 3362 return NumberField_relative(self, poly, str(name), check=check, 3363 embedding=embedding, implementation=implementation) 3358 3364 3359 3365 def factor(self, n): 3360 3366 r""" … … 3470 3476 if self.__polynomial != None: 3471 3477 X = self.__polynomial.parent().gen() 3472 3478 else: 3479 from sage.rings.all import PolynomialRing 3473 3480 X = PolynomialRing(rational_field.RationalField()).gen() 3474 3481 self.__gen = self._element_class(self, X) 3475 3482 return self.__gen … … 4788 4795 """ 4789 4796 return self.pari_nf().dirzetak(n) 4790 4797 4798 def multi_polynomial_quotient_ring(self): 4799 r""" 4800 Return a polynomial quotient ring `R/I`, and maps `f` and `t`, 4801 where `f: R/I \to K` and `t:K \to R/I` are isomorphisms, where 4802 `K` is self. 4803 4804 OUTPUT: 4805 - `Q` -- quotient of a polynomial ring 4806 - `f` -- homomorphism Q to self 4807 - `t` -- homomorphism self to Q 4808 4809 EXAMPLES:: 4810 4811 An absolute extension:: 4812 4813 sage: K.<a> = NumberField(x^3 + x + 3); Q, f, t = K.multi_polynomial_quotient_ring(); Q 4814 Quotient of Multivariate Polynomial Ring in x over Rational Field by the ideal (x^3 + x + 3) 4815 sage: f(Q.0) 4816 a 4817 sage: t(a) 4818 a 4819 4820 A relative extension:: 4821 4822 sage: K.<a> = NumberField(x^3 + x + 3); R.<y> = K[]; L.<b> = K.extension(y^2 + a*y + a^2) 4823 sage: Q, f, t = L.multi_polynomial_quotient_ring(); alpha = L.random_element(); alpha 4824 (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95 4825 sage: Q 4826 Quotient of Multivariate Polynomial Ring in y, x over Rational Field by the ideal (x^3 + x + 3, y^2 + y*x + x^2) 4827 sage: Q.gens() 4828 (b, a) 4829 sage: t(alpha) 4830 -12*b*a^2 - 36*b*a - 71/2*a^2 - 3/2*b + 1141/95*a + 3043/95 4831 sage: f(t(alpha)) 4832 (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95 4833 sage: f(t(alpha))== alpha 4834 True 4835 """ 4836 from sage.rings.all import PolynomialRing, QQ 4837 p = self.defining_polynomial() 4838 var = p.variable_name() 4839 if self.is_absolute(): 4840 R = PolynomialRing(QQ, 1, names=self.variable_name()) 4841 p2 = R(p.change_variable_name(self.variable_name())) 4842 Q = R.quotient(p2, names=self.variable_name()) 4843 f = Q.hom([self.gen()]) 4844 t = self.hom([Q.gen()]) 4845 return Q, f, t 4846 else: 4847 B = self.base_field() 4848 Q0, f0, t0 = B.multi_polynomial_quotient_ring() 4849 R = PolynomialRing(QQ, Q0.ngens()+1, self.variable_names()) 4850 phi = Q0.cover_ring().hom(R.gens()[1:]) 4851 x = R.gen(0) 4852 p2 = sum(phi(t0(a).lift())*x**i for i, a in enumerate(p.list())) 4853 I = R.ideal([phi(g) for g in Q0.defining_ideal().gens()] + [p2]) 4854 Q = R.quotient(I, names = self.variable_names()) 4855 t = maps.MapRelativeNumberFieldToMPolynomialQuotient(self, Q, f0, t0) 4856 f = t.inverse() 4857 return Q, f, t 4858 4859 def polynomial_quotient_tower(self): 4860 """ 4861 EXAMPLES:: 4862 4863 An absolute extension:: 4864 4865 sage: K.<a> = NumberField(x^2 + 3) 4866 sage: Q, f, t = K.polynomial_quotient_tower(); Q 4867 Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 + 3 4868 sage: f(Q.0^2+3) 4869 0 4870 sage: f(Q.0-2/3) 4871 a - 2/3 4872 sage: t(a-2/3) 4873 a - 2/3 4874 4875 A relative extension:: 4876 4877 sage: K.<a,b> = NumberField([x^17 + 7, x^3 + 2]) 4878 sage: Q, f, t = K.polynomial_quotient_tower() 4879 sage: Q 4880 Univariate Quotient Polynomial Ring in a over Univariate Quotient Polynomial Ring in b over Rational Field with modulus x^3 + 2 with modulus x^17 + 7 4881 sage: f 4882 Isomorphism map: 4883 From: Univariate Quotient Polynomial Ring in a ... 4884 To: Number Field in a with defining polynomial x^17 + 7... 4885 sage: t 4886 Isomorphism map: 4887 From: Number Field in a with defining polynomial x^17 + 7... 4888 To: Univariate Quotient Polynomial Ring in a ... 4889 4890 4891 A more complicated relative extension:: 4892 4893 sage: K.<a> = NumberField(x^3 + x + 3); R.<y> = K[] 4894 sage: L.<b> = K.extension(y^2 + a*y + a^2); L 4895 Number Field in b with defining polynomial y^2 + a*y + a^2 over its base field 4896 sage: Q, f, t = L.polynomial_quotient_tower(); Q 4897 Univariate Quotient Polynomial Ring in b over Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + x + 3 with modulus y^2 + a*y + a^2 4898 sage: f(Q.0) 4899 b 4900 sage: t(L.0) 4901 b 4902 sage: r = L.random_element(); r 4903 (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95 4904 sage: t(r) 4905 (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95 4906 sage: f(t(r)) 4907 (-12*a^2 - 36*a - 3/2)*b - 71/2*a^2 + 1141/95*a + 3043/95 4908 sage: f(t(r)) == r 4909 True 4910 """ 4911 p = self.defining_polynomial() 4912 if self.is_absolute(): 4913 R = p.parent() 4914 Q = R.quotient(p, names=self.variable_name()) 4915 f = Q.hom([self.gen()]) 4916 t = self.hom([Q.gen()]) 4917 return Q, f, t 4918 else: 4919 B = self.base_field() 4920 Q0, f0, t0 = B.polynomial_quotient_tower() 4921 R = Q0[p.variable_name()] 4922 q = R([t0(z).lift() for z in p.list()]) 4923 Q = R.quotient(q, names = self.variable_name()) 4924 t = maps.MapRelativeNumberFieldToPolynomialQuotientTower(self, Q, f0, t0) 4925 f = t.inverse() 4926 return Q, f, t 4927 4791 4928 4792 4929 class NumberField_absolute(NumberField_generic): 4793 4930 … … 4840 4977 self._zero_element = self(0) 4841 4978 self._one_element = self(1) 4842 4979 4980 def _mpoly_ideal(self): 4981 """ 4982 Return the multivariate polynomial ring ideal that we use to 4983 implement arithmetic in the relative extension defined by the 4984 given polynomial. 4985 4986 OUTPUT: 4987 - an ideal in a multivariate polynomial ring 4988 4989 EXAMPLES:: 4990 4991 sage: K.<a> = NumberField(x^3 + 7) 4992 sage: K._mpoly_ideal() 4993 Ideal (x^3 + 7) of Multivariate Polynomial Ring in x over Rational Field 4994 sage: R.<T> = QQ[] 4995 sage: K.<alpha> = NumberField(T^3 - 5/3) 4996 sage: K._mpoly_ideal() 4997 Ideal (T^3 - 5/3) of Multivariate Polynomial Ring in T over Rational Field 4998 """ 4999 polynomial = self.polynomial() 5000 from sage.rings.all import PolynomialRing, QQ 5001 R = PolynomialRing(QQ,1,names=polynomial.variable_name()) 5002 I = R.ideal([polynomial]) 5003 return I 5004 4843 5005 def _coerce_from_other_number_field(self, x): 4844 5006 """ 4845 5007 Coerce a number field element x into this number field. … … 4900 5062 TypeError: <type 'sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX'> 4901 5063 4902 5064 One can also coerce an element of the polynomial quotient ring 4903 that's isomorphic to the number field: 5065 that's isomorphic to the number field:: 5066 4904 5067 sage: K.<a> = NumberField(x^3 + 17) 4905 5068 sage: b = K.polynomial_quotient_ring().random_element() 4906 5069 sage: K(b) -
sage/rings/number_field/number_field_element_libsingular.pxd
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_element_libsingular.pxd
a b 35 35 cdef void nfelt_mul(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K) 36 36 cdef void nfelt_add(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K) 37 37 cdef void nfelt_sub(nfelt_t rop, nfelt_t op1, nfelt_t op2, nf_t K) 38 cdef void nfelt_neg(nfelt_t rop, nfelt_t op, nf_t K) 38 39 cdef void nfelt_div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K) 39 cdef void nfelt_ div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K)40 cdef void nfelt_pow_ui(nfelt_t rop, nfelt_t op, unsigned long exp, nf_t K) 40 41 41 42 cdef void nfelt_canonicalize(nfelt_t rop, nf_t K) 42 43 cdef object nfelt_pystr(nfelt_t op, nf_t K) … … 58 59 cdef nfelt_t poly 59 60 cdef _new(self) 60 61 cdef MPolynomialRing_libsingular mpoly_ring(self) 62 cdef MPolynomial_libsingular coerce(self, x) 61 63 cdef imp(self) 62 64 63 65 -
sage/rings/number_field/number_field_element_libsingular.pyx
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_element_libsingular.pyx
a b 28 28 int unlikely(int) 29 29 int likely(int) 30 30 31 # We do this to force compilation of the file using C++. Once this is 32 # moved to a library, there will be a different solution to including 33 # fmpq_poly. 34 cdef extern from "../../libs/flint/fmpq_poly.c": 35 pass 36 31 37 include "../../ext/stdsage.pxi" 32 38 33 39 from sage.structure.element cimport RingElement, ModuleElement, Element 34 40 from number_field_base cimport NumberField 35 41 36 42 from sage.libs.singular.decl cimport ( 37 p_Copy, p_Delete, p_ISet, 43 p_Copy, p_Delete, p_GetCoeff, p_ISet, p_Init, p_SetCoeff, 44 p_GetExp, p_SetExp, pNext, p_Setm, p_Add_q, 38 45 currRing, rChangeCurrRing, 39 46 redNF, redtailBba, 40 IDELEMS, idInit, idLift, id_Delete) 47 IDELEMS, idInit, idLift, id_Delete, 48 number, nlInit2gmp, 49 pTakeOutComp1) 50 51 from sage.libs.gmp.mpq cimport ( 52 mpq_t, mpq_init, mpq_clear, 53 mpq_numref, mpq_denref, mpq_sgn) 54 55 from sage.libs.gmp.mpz cimport ( 56 mpz_t, mpz_init_set_si, mpz_clear) 57 58 from sage.libs.flint.fmpq_poly cimport ( 59 fmpq_poly_t, 60 fmpq_poly_get_coeff_mpq, fmpq_poly_degree) 41 61 42 62 # singular poly arith 43 63 from sage.libs.singular.polynomial cimport ( 44 64 singular_polynomial_call, singular_polynomial_cmp, 45 singular_polynomial_add, singular_polynomial_sub, 65 singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg, 46 66 singular_polynomial_neg, singular_polynomial_rmul, singular_polynomial_mul, 47 67 singular_polynomial_div_coeff, singular_polynomial_pow, 48 68 singular_polynomial_str, singular_polynomial_latex, 49 69 singular_polynomial_str_with_changed_varnames, 50 70 singular_polynomial_deg, singular_polynomial_length_bounded) 51 71 52 from implementation cimport ArithmeticImplementation_libsingular 72 from sage.rings.integer cimport Integer 73 from sage.rings.rational cimport Rational 74 75 from implementation cimport ArithmeticImplementation 76 77 cdef class ArithmeticImplementation_libsingular(ArithmeticImplementation): 78 cdef object nf_t_wrap 79 cdef object ideal 80 cdef object ring 81 cdef object field_to_ring 82 cdef object base_field 83 def __init__(self, ideal, field_to_ring, base_field): 84 """ 85 EXAMPLES:: 86 87 sage: sage.rings.number_field.implementation.ArithmeticImplementation_libsingular() 88 Arithmetic implementation 'singular' 89 """ 90 ArithmeticImplementation.__init__(self, 'singular') 91 self.nf_t_wrap = nf_t_wrap(ideal) 92 self.ideal = ideal 93 self.ring = ideal.ring() 94 self.field_to_ring = field_to_ring 95 self.base_field = base_field 96 97 from number_field_element_flint cimport NumberFieldElement_flint 53 98 54 99 cdef class NumberFieldElement_libsingular(NumberFieldElement): 55 100 … … 127 172 128 173 #### end BENCHMARKING CODE 129 174 130 def __init__(self, parent, f): 175 def __init__(self, parent, x): 176 """ 177 You can coerce the following types in: 178 179 - MPolynomial_libsingular -- in which case x is supposed to be in the 180 multivariate polynomial ring corresponding to the parent. 181 - NumberFieldElement_libsingular -- in which case x is assumed to be 182 in either the base field or in parent. 183 - NumberFieldElement_flint -- in which x must be in the base field of self. 184 - Integer 185 186 The above stated assumptions need not be checked. 187 188 EXAMPLES:: 189 """ 190 cdef poly *p, *q, *mon 191 cdef number* c 192 cdef ring *R_p, *R_q 193 cdef long exponent 194 cdef fmpq_poly_t f 195 cdef mpq_t t 196 cdef mpz_t z, z2 197 131 198 self._parent = parent 132 #cdef MPolynomial_libsingular g = self.mpoly_ring()(f) 133 cdef MPolynomial_libsingular g = self.mpoly_ring().gen() 134 nfelt_init_set_poly(self.poly, g._poly, imp(self).nf) 199 if PY_TYPE_CHECK(x, MPolynomial_libsingular): 200 #print "MPolynomial_libsingular --> " 201 # Directly set the pointer. Note we are assuming here 202 # that the ring containing x is correct. 203 p = (<MPolynomial_libsingular>x)._poly 204 205 elif PY_TYPE_CHECK(x, NumberFieldElement_libsingular): 206 #print "NumberFieldElement_libsingular --> " 207 # x is an element of the base field, and the base field is 208 # a relative extension. We construct a multivariate 209 # polynomial from x in the bigger ring (with one more 210 # variable adjoined). 211 212 # Get a pointer to the underlying libsingular polynomial 213 q = (<NumberFieldElement_libsingular>x).poly.poly 214 215 # Get the libsingular rings for both p and q, which are 216 # stored in their implementation nf objects. 217 R_q = imp(x).nf.ring 218 R_p = imp(self).nf.ring 219 220 # Initialize p (which will be the image of q) to 0. 221 p = p_ISet(0, R_p) 222 223 # Now we iterate over each coefficient of q, grabbing 224 # the corresponding monomial. 225 while q: 226 # Switch to the ring R_q and grab the leading coefficient 227 rChangeCurrRing(R_q) 228 c = p_GetCoeff(q, R_q) 229 230 # If the coefficient is nonzero, add the corresponding 231 # coefficient*monomial to p. 232 if c: 233 rChangeCurrRing(R_p) 234 mon = p_Init(R_p) # make a new unitialized monomial (pointer to a poly) 235 p_SetCoeff(mon, c, R_p) 236 # iterate over the variables, getting the exponents 237 for j in range(1, R_p.N): 238 exponent = p_GetExp(q, j, R_q) 239 if exponent: 240 # We set the exponent of the (j+1)th variable, because the map 241 # from the smaller field to this one is: 242 # Q[y,z] \---> Q[x,y,z], i.e., the first variable is the new one. 243 p_SetExp(mon, j+1, exponent, R_p) 244 # Finalize the change (having set p_SetExp). 245 p_Setm(mon, R_p) 246 # Replace p by p plus the monomial (with coefficient). 247 p = p_Add_q(p, mon, R_p) 248 # Move to the next monomial of q. 249 q = pNext(q) 250 251 elif PY_TYPE_CHECK(x, NumberFieldElement_flint): 252 #print "NumberFieldElement_flint --> " 253 254 # Now x is represented by a flint polynomial. 255 # We iterate through its coefficient, setting 256 # the corresponding monomial of p. 257 258 # Get the ring for self, and initialize p to 0. 259 R_p = imp(self).nf.ring 260 p = p_ISet(0, R_p) 261 262 mpq_init(t) 263 264 # Get C-level access to underlying flint polynomial. 265 f[0] = ((<NumberFieldElement_flint>x).f)[0] 266 #print " degree =", fmpq_poly_degree(f) 267 for exponent in range(fmpq_poly_degree(f)+1): 268 # Get the i-th coefficient as a GMP integer 269 fmpq_poly_get_coeff_mpq(t, f, exponent) 270 if mpq_sgn(t) != 0: # if the coefficient is nonzero 271 # Make a Singular number. 272 c = nlInit2gmp(mpq_numref(t), mpq_denref(t)) 273 # Set the coefficient, then exponent of the variable. 274 mon = p_Init(R_p) 275 p_SetCoeff(mon, c, R_p) 276 # It must be the last variable, since FLINT is always at bottom of tower 277 p_SetExp(mon, R_p.N, exponent, R_p) 278 # Finalize the change (having set p_SetExp). 279 p_Setm(mon, R_p) 280 # Now add the monomial to p. 281 p = p_Add_q(p, mon, R_p) 282 283 mpq_clear(t) 284 285 elif PY_TYPE_CHECK(x, Integer): 286 287 # Get the ring for self, and initialize p to 0. 288 R_p = imp(self).nf.ring 289 # Initialize p to 0 290 p = p_Init(R_p) 291 # Create the GMP integer 1, for the denominator below. 292 mpz_init_set_si(z, 1) 293 # Create a singular number from x. 294 c = nlInit2gmp((<Integer>x).value, z) 295 # Set p to that number. 296 p_SetCoeff(p, c, R_p) 297 p_Setm(p, R_p) # and finalize 298 mpz_clear(z) 299 300 elif PY_TYPE_CHECK(x, Rational): 301 302 # Get the ring for self, and initialize p to 0. 303 R_p = imp(self).nf.ring 304 # Initialize p to 0 305 p = p_Init(R_p) 306 # Create the GMP integer 1, for the denominator below. 307 # Create a singular number from x. 308 c = nlInit2gmp(mpq_numref((<Rational>x).value), mpq_denref((<Rational>x).value)) 309 # Set p to that number. 310 p_SetCoeff(p, c, R_p) 311 p_Setm(p, R_p) # and finalize 312 mpz_clear(z) 313 314 elif PY_TYPE_CHECK(x, int): 315 316 # TODO -- surely there is a vastly better way to do this. 317 R_p = imp(self).nf.ring 318 p = p_Init(R_p) 319 mpz_init_set_si(z, 1) 320 mpz_init_set_si(z2, x) 321 c = nlInit2gmp(z2, z) 322 p_SetCoeff(p, c, R_p) 323 p_Setm(p, R_p) 324 mpz_clear(z) 325 mpz_clear(z2) 326 327 else: 328 raise TypeError 329 330 # Set self to the result of the above. 331 nfelt_init_set_poly(self.poly, p, imp(self).nf) 332 333 def __dealloc__(self): 334 nfelt_clear(self.poly, imp(self).nf) 135 335 136 336 cdef imp(self): 137 337 cdef ArithmeticImplementation_libsingular A 138 338 A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation 139 339 return A 140 340 341 cdef MPolynomial_libsingular coerce(self, x): 342 print x, type(x) 343 if isinstance(x, MPolynomial_libsingular): return x 344 cdef ArithmeticImplementation_libsingular A 345 A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation 346 # TODO: having to lift here is stupid; but fixing this is going to require even 347 # more maps in maps.py... ugh. 348 return A.field_to_ring(x).lift() 349 141 350 cdef inline MPolynomialRing_libsingular mpoly_ring(self): 142 351 cdef ArithmeticImplementation_libsingular A 143 352 A = <ArithmeticImplementation_libsingular> (<NumberField>self._parent)._implementation … … 171 380 nfelt_sub(rop.poly, self.poly, (<NumberFieldElement_libsingular>right).poly, imp(self).nf) 172 381 return rop 173 382 383 def __neg__(self): 384 cdef NumberFieldElement_libsingular rop = self._new() 385 nfelt_neg(rop.poly, self.poly, imp(self).nf) 386 return rop 387 174 388 cpdef RingElement _div_(self, RingElement right): 175 389 if nfelt_is_zero((<NumberFieldElement_libsingular>right).poly): 176 390 raise ZeroDivisionError … … 185 399 nfelt_invert(rop.poly, self.poly, imp(self).nf) 186 400 return rop 187 401 402 def __pow__(NumberFieldElement_libsingular self, long exp, dummy): 403 """ 404 EXAMPLES:: 405 """ 406 if exp < 0: 407 return self.__invert__().__pow__(-exp) 408 cdef NumberFieldElement_libsingular rop = self._new() 409 nfelt_pow_ui(rop.poly, self.poly, exp, imp(self).nf) 410 return rop 411 188 412 def __richcmp__(left, right, int op): 189 413 return (<Element>left)._richcmp(right, op) 190 414 … … 274 498 nfelt_clear(rop, K) 275 499 singular_polynomial_sub(&(rop.poly), op1.poly, op2.poly, K.ring) 276 500 501 cdef void nfelt_neg(nfelt_t rop, nfelt_t op, nf_t K): 502 nfelt_clear(rop, K) 503 singular_polynomial_neg(&(rop.poly), op.poly, K.ring) 504 277 505 cdef void nfelt_div(nfelt_t q, nfelt_t n, nfelt_t d, nf_t K): 278 506 cdef ideal *I, *nI, *res 507 508 # TODO: I did benchmarks, and in some examples this is easily 509 # way slower than magma, say by a factor of 10 or more. Not good. 510 # E.g., comparing this in Sage: 511 # K.<a,b> = NumberField([x^6 + 2*x^3 + 7, x^10 +17*x + 152]) 512 # with some simple divides to this in Magma 513 # R<x> := PolynomialRing(RationalField()); 514 # K<a,b> := NumberField([x^6 + 2*x^3 + 7, x^10 +17*x + 152]); 279 515 280 516 # Initialize the ideal generated by n. 281 517 nI = idInit(1, 1) 282 518 nI.m[0] = p_Copy(n.poly, K.ring) 283 519 284 520 # Initialize the ideal with generators [d] + K.ideal.gens() 285 I = idInit(IDELEMS(K.ideal) +1, 1)521 I = idInit(IDELEMS(K.ideal) + 1, 1) 286 522 I.m[0] = p_Copy(d.poly, K.ring) 287 for i in range(1, IDELEMS(K.ideal) +1):523 for i in range(1, IDELEMS(K.ideal) + 1): 288 524 I.m[i] = p_Copy(K.ideal.m[i-1], K.ring) 289 525 290 526 # Now compute the lift of nI 291 527 res = idLift(I, nI, NULL, 0, 0, 0) 528 529 # The answer is the first entry in the lift. 292 530 nfelt_clear(q, K) 293 q.poly = p_Copy(res.m[0], K.ring) 531 #q.poly = p_Copy(res.m[0], K.ring) 532 q.poly = pTakeOutComp1(&res.m[0], 1) 533 534 # Clean up. 294 535 id_Delete(&nI, K.ring) 295 536 id_Delete(&I, K.ring) 537 id_Delete(&res, K.ring) 538 539 cdef void nfelt_pow_ui(nfelt_t rop, nfelt_t op, unsigned long exp, nf_t K): 540 nfelt_clear(rop, K) 541 singular_polynomial_pow(&(rop.poly), op.poly, exp, K.ring) 542 nfelt_canonicalize(rop, K) 296 543 297 544 cdef void nfelt_canonicalize(nfelt_t op, nf_t K): 298 545 if unlikely(K.ring != currRing): rChangeCurrRing(K.ring) 299 546 cdef int max_ind 300 op.poly = redNF( p_Copy(op.poly, K.ring), max_ind, 0, K.strategy)547 op.poly = redNF(op.poly, max_ind, 0, K.strategy) 301 548 if likely(op.poly != NULL): 302 549 op.poly = redtailBba(op.poly, max_ind, K.strategy) 303 550 … … 310 557 cdef nf_t_wrap imp(NumberFieldElement_libsingular x): 311 558 return (<ArithmeticImplementation_libsingular>(x.imp())).nf_t_wrap 312 559 313 314 560 cdef class nf_t_wrap: 315 561 def __init__(self, ideal): 316 562 self.ideal = ideal 317 563 nf_init_sage_ideal(self.nf, ideal) 564 318 565 566 -
new file sage/rings/number_field/number_field_fast.pyx
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_fast.pyx
- + 1 include "../../ext/stdsage.pxi" 2 3 import number_field_rel 4 from sage.rings.integer cimport Integer 5 from sage.rings.rational cimport Rational 6 from number_field_element_libsingular import NumberFieldElement_libsingular 7 8 class NumberField_libsingular(number_field_rel.NumberField_libsingular): 9 def _element_constructor_(self, x): 10 if PY_TYPE_CHECK(x, Integer): 11 return NumberFieldElement_libsingular(self, x) 12 if PY_TYPE_CHECK(x, Rational): 13 return NumberFieldElement_libsingular(self, x) 14 return super(NumberField_libsingular, self)._element_constructor_(x) 15 -
sage/rings/number_field/number_field_morphisms.pyx
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_morphisms.pyx
a b 103 103 104 104 def __init__(self, K, L, ambient_field=None): 105 105 """ 106 EXAMPLES: 106 EXAMPLES: : 107 107 108 sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism 108 109 sage: K.<a> = NumberField(x^2-17, embedding=4.1) 109 110 sage: L.<b> = NumberField(x^4-17, embedding=2.0) … … 124 125 To: Cyclotomic Field of order 36 and degree 12 125 126 Defn: zeta12 -> zeta36^3 126 127 127 The embeddings must be compatible: 128 The embeddings must be compatible:: 129 128 130 sage: F1 = NumberField(x^3 + 2, 'a', embedding=2) 129 131 sage: F2 = NumberField(x^3 + 2, 'a', embedding=CC.0) 130 132 sage: F1.gen() + F2.gen() … … 143 145 144 146 def section(self): 145 147 """ 146 EXAMPLES: 148 EXAMPLES:: 149 147 150 sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism 148 151 sage: K.<a> = NumberField(x^2-700, embedding=25) 149 152 sage: L.<b> = NumberField(x^6-700, embedding=3) -
sage/rings/number_field/number_field_rel.py
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/number_field_rel.py
a b 276 276 polynomial = polynomial.change_ring(base) 277 277 278 278 ######################################### 279 # Trivial initialization that must be done 280 # before constructing implementation object 281 # below. 282 ######################################### 283 self.__base_field = base 284 self.__relative_polynomial = polynomial 285 286 ######################################### 287 # Compute the generators of this field, 288 # going down the tower and coercing in 289 # each generator. 290 ######################################### 291 self.__gens = [None] 292 v = [None] 293 K = base 294 names = [name] 295 while K != QQ: 296 names.append(K.variable_name()) 297 v.append(K.gen()) 298 K = K.base_field() 299 self._assign_names(tuple(names), normalize=False) 300 301 ######################################### 279 302 # Set the implementation object 280 ######################################### 303 ######################################### 304 # TODO 305 implementation = 'singular' 306 281 307 if implementation == 'default': 282 308 implementation = number_field.DEFAULT_IMPLEMENTATION['relative'] 283 309 … … 295 321 import number_field_element_libsingular 296 322 self._element_class = number_field_element_libsingular.NumberFieldElement_libsingular 297 323 self._order_element_class = number_field_element_libsingular.OrderElement_libsingular 298 ring, ideal = self._libsingular_ring(polynomial) 299 self._set_implementation(arithmetic_implementation.ArithmeticImplementation_libsingular(ideal)) 324 Q,_,to_Q = self.multi_polynomial_quotient_ring() 325 ideal = Q.defining_ideal() 326 self._set_implementation(number_field_element_libsingular.ArithmeticImplementation_libsingular( 327 ideal, to_Q, base)) 300 328 else: 301 329 raise ValueError, "invalid relative number field implementation '%s'"%implementation 302 330 assert self.implementation() is not None … … 318 346 from_abs_base = maps.IdentityMap(base) 319 347 to_abs_base = maps.IdentityMap(base) 320 348 self.__absolute_base_field = abs_base, from_abs_base, to_abs_base 321 self.__base_field = base322 self.__relative_polynomial = polynomial323 349 324 350 # Check that defining polynomial for this field is irreducible. 325 351 if check: … … 330 356 # polynomials over number fields -- see ticket #4724 331 357 raise ValueError, "defining polynomial (%s) must be irreducible"%polynomial 332 358 333 #########################################334 # Compute the generators of this field,335 # going down the tower and coercing in336 # each generator.337 #########################################338 self.__gens = [None]339 v = [None]340 K = base341 names = [name]342 while K != QQ:343 names.append(K.variable_name())344 v.append(K.gen())345 K = K.base_field()346 359 347 360 ######################################### 348 361 # Generic initialization 349 362 ######################################### 350 self._assign_names(tuple(names), normalize=False)351 363 NumberField_generic.__init__(self, self.absolute_polynomial(), name=None, 352 364 latex_name=latex_name, check=False, 353 365 embedding=embedding) … … 356 368 # Now we can finish our gens initialization 357 369 ######################################### 358 370 v[0] = self._gen_relative() 371 self.__gens = tuple(v) 359 372 v = [self(x) for x in v] 360 373 self.__gens = tuple(v) 361 374 self._zero_element = self(0) 362 375 self._one_element = self(1) 363 376 364 def _libsingular_ring(self, polynomial):365 """366 Return the libsingular ring that we use to implement arithmetic in367 the relative extension defined by the given polynomial.368 369 INPUT:370 - ``polynomial`` -- a polynomial over a number field371 372 OUTPUT:373 - a singular multivariate polynomial ring374 - an ideal375 """376 from sage.rings.all import PolynomialRing, QQ377 ring = PolynomialRing(QQ, 2, names=('x','y'))378 x,y = ring.gens()379 ideal = ring.ideal([x**3+7,y**3+2])380 return ring, ideal381 382 377 def change_names(self, names): 383 378 r""" 384 379 Return relative number field isomorphic to self but with the … … 776 771 sage: type(K.Hom(K)) 777 772 <class 'sage.rings.number_field.morphism.RelativeNumberFieldHomset_with_category'> 778 773 """ 779 780 774 from number_field import is_NumberFieldHomsetCodomain 781 775 if is_NumberFieldHomsetCodomain(codomain): 782 776 import morphism … … 819 813 """ 820 814 if x.parent() is self.base_ring() or x.parent() == self.base_ring(): 821 815 return self.__base_inclusion(x) 816 822 817 f = x.polynomial() 823 818 if f.degree() <= 0: 824 819 return self._element_class(self, f[0]) … … 1465 1460 if self.implementation().use_absolute_polynomials(): 1466 1461 f = self._absolute_pari_polynomial() 1467 1462 else: 1468 f = self. polynomial_ring().gen()1463 f = self.multi_polynomial_quotient_ring()[0].gen(0).lift() 1469 1464 return self._element_class(self, f) 1470 1465 1471 1466 @cached_method … … 2424 2419 return NumberField_relative(base_field, poly, name, latex_name, check=False, embedding=canonical_embedding) 2425 2420 2426 2421 NumberField_extension_v1 = NumberField_relative_v1 # historical reasons only 2422 2423 2424 2425 ##################### 2426 2427 import number_field_element 2428 import sage.modules.free_module_element 2429 2430 class NumberField_libsingular(NumberField_relative): 2431 def _coerce_from_other_number_field(self, x): 2432 K = self.base_field() 2433 if x.parent() != K: x = K(x) 2434 return self._element_class(self, x) 2435 2436 def _coerce_non_number_field_element_in(self, x): 2437 return self._element_class(self, self.base_field()(x)) 2438 2439 def _element_constructor_(self, x): 2440 if isinstance(x, integer.Integer): 2441 return self._element_class(self, x) 2442 2443 if number_field_element.is_NumberFieldElement(x): 2444 K = x.parent() 2445 if K is self: 2446 return x 2447 elif K == self: 2448 return self._element_class(self, x.polynomial()) 2449 elif number_field_element.is_OrderElement(x): 2450 L = K.number_field() 2451 if L == self: 2452 return self._element_class(self, x) 2453 x = L(x) 2454 return self._coerce_from_other_number_field(x) 2455 elif isinstance(x,str): 2456 return self._coerce_from_str(x) 2457 elif isinstance(x, (tuple, list)) or \ 2458 (isinstance(x, sage.modules.free_module_element.FreeModuleElement) and 2459 self.base_ring().has_coerce_map_from(x.parent().base_ring())): 2460 if len(x) != self.relative_degree(): 2461 raise ValueError, "Length must be equal to the degree of this number field" 2462 result = x[0] 2463 for i in xrange(1,self.relative_degree()): 2464 result += x[i]*self.gen(0)**i 2465 return result 2466 return self._coerce_non_number_field_element_in(x) 2467 -
sage/rings/number_field/todo.txt
diff -r 313613462727 -r 33929e45edc2 sage/rings/number_field/todo.txt
a b 38 38 [x] make sure the _cmp_c_impl's are compatible across number field element implementations. 39 39 [x] make default implementation computation be centralized somehow?? 40 40 41 [x] isomorphisms between number fields and univariate poly tower 42 43 [x] isomorphisms between number fields and multi poly ring 44 45 [x] add loads/dumps doctests to all of maps.py, along with __cmp__ methods 46 47 [x] optimize coercion in 48 49 [x] fix division for singular nf elts 50 51 52 [ ] fix construction of towers with more than 2 fields in them. 53 [ ] make it so creation of relative number fields doesn't require computing 54 some stupid absolute polynomial, which takes forever. that's stupid. 55 56 ------------------------------------- 57 58 59 [ ] loads/dumps in maps.py broken due to non-uniqueness of homsets -- see rings/homset.py 60 I tried for about an hour to make this unique in various ways, but got ass kicked. 61 62 [ ] move the arithmetic implementation objects to the relevant element files, and make 63 sure module_list.py is maximally conservative 64 41 65 [ ] libsingular elements: 42 66 [ ] constructing the corresponding ring 43 67 44 45 68 [ ] implement OrderElement_singular 46 69 47 70 [ ] write general implementation of algorithm for computing absolute_field