Ticket #9541: trac_9541-part6-flint_elts.patch
File trac_9541-part6-flint_elts.patch, 45.3 KB (added by , 12 years ago) |
---|
-
module_list.py
# HG changeset patch # User William Stein <wstein@gmail.com> # Date 1279735308 -7200 # Node ID f09d5a19ec34645612cc112d30fa735cc7b77aa0 # Parent f8a3a8cdcf94052e64c133a8f1f6b70c2a854abd [mq]: trac_9541-part6-flint_elts.patch diff -r f8a3a8cdcf94 -r f09d5a19ec34 module_list.py
a b 523 523 sources = ['sage/libs/singular/singular.pyx'], 524 524 libraries = ['m', 'readline', 'singular', 'givaro', 'ntl', 'gmpxx', 'gmp'], 525 525 language="c++", 526 include_dirs = [SAGE_ROOT +'/local/include/singular'], 526 include_dirs = [SAGE_ROOT +'/local/include/singular', 527 SAGE_ROOT+'/devel/sage/sage/libs/flint', SAGE_ROOT+'/local/include/FLINT/'], 527 528 depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 528 529 529 530 Extension('sage.libs.singular.polynomial', 530 531 sources = ['sage/libs/singular/polynomial.pyx'], 531 532 libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 532 533 language="c++", 533 include_dirs = [SAGE_ROOT +'/local/include/singular'], 534 include_dirs = [SAGE_ROOT +'/local/include/singular', 535 SAGE_ROOT+'/devel/sage/sage/libs/flint', SAGE_ROOT+'/local/include/FLINT/'], 534 536 depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 535 537 536 538 Extension('sage.libs.singular.ring', 537 539 sources = ['sage/libs/singular/ring.pyx'], 538 540 libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 539 541 language="c++", 540 include_dirs = [SAGE_ROOT +'/local/include/singular' ],542 include_dirs = [SAGE_ROOT +'/local/include/singular', SAGE_ROOT+'/devel/sage/sage/libs/flint', SAGE_ROOT+'/local/include/FLINT/'], 541 543 depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 542 544 543 545 Extension('sage.libs.singular.groebner_strategy', … … 1199 1201 ################################ 1200 1202 1201 1203 Extension('sage.rings.number_field.number_field_base', 1202 sources = ['sage/rings/number_field/number_field_base.pyx']), 1204 sources = ['sage/rings/number_field/number_field_base.pyx'], 1205 include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint'], 1206 extra_compile_args=["-std=c99", "-D_XPG6"], 1207 ), 1203 1208 1204 1209 Extension('sage.rings.number_field.implementation', 1205 sources = ['sage/rings/number_field/implementation.pyx']), 1210 sources = ['sage/rings/number_field/implementation.pyx' , "sage/libs/flint/fmpq_poly.c"], 1211 include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint'], 1212 extra_compile_args=["-std=c99", "-D_XPG6"], 1213 libraries=['flint'], 1214 depends = [SAGE_ROOT + "/local/include/FLINT/flint.h"]), 1206 1215 1207 1216 Extension('sage.rings.number_field.order_base', 1208 sources = ['sage/rings/number_field/order_base.pyx']), 1209 1217 sources = ['sage/rings/number_field/order_base.pyx'], 1218 include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint'], 1219 extra_compile_args=["-std=c99", "-D_XPG6"] 1220 ), 1221 1210 1222 Extension('sage.rings.number_field.number_field_element', 1211 1223 sources = ['sage/rings/number_field/number_field_element.pyx']), 1212 1224 1213 1225 Extension('sage.rings.number_field.number_field_element_ntl', 1214 1226 sources = ['sage/rings/number_field/number_field_element_ntl.pyx'], 1215 1227 libraries=['ntl','gmp'], 1216 language = 'c++'), 1228 language = 'c++', 1229 include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint']), 1217 1230 1218 1231 Extension('sage.rings.number_field.number_field_element_generic', 1219 sources = ['sage/rings/number_field/number_field_element_generic.pyx']), 1232 sources = ['sage/rings/number_field/number_field_element_generic.pyx'], 1233 include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint'], 1234 extra_compile_args=["-std=c99", "-D_XPG6"] 1235 ), 1220 1236 1221 1237 Extension('sage.rings.number_field.number_field_element_flint', 1222 1238 sources = ['sage/rings/number_field/number_field_element_flint.pyx', "sage/libs/flint/fmpq_poly.c"], … … 1344 1360 sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'], 1345 1361 libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 1346 1362 language="c++", 1347 include_dirs = [SAGE_ROOT +'/local/include/singular'], 1363 include_dirs = [SAGE_ROOT +'/local/include/singular', 1364 SAGE_ROOT+'/devel/sage/sage/libs/flint', 1365 SAGE_ROOT+'/local/include/FLINT/' 1366 ], 1348 1367 depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 1349 1368 1350 1369 Extension('sage.rings.polynomial.multi_polynomial_ring_generic', -
sage/libs/flint/fmpq_poly.pxd
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/libs/flint/fmpq_poly.pxd
a b 32 32 int fmpq_poly_is_zero(fmpq_poly_t) 33 33 34 34 void fmpq_poly_get_coeff_mpq(mpq_t, fmpq_poly_t, unsigned long) 35 void fmpq_poly_set_coeff_mpq(fmpq_poly_t, unsigned long, mpq_t) 35 36 void fmpq_poly_set_coeff_si(fmpq_poly_t, unsigned long, long) 36 37 37 38 void fmpq_poly_add(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) -
sage/libs/singular/singular.pxd
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/libs/singular/singular.pxd
a b 11 11 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular 12 12 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 13 13 14 from sage.rings.number_field.number_field_base cimport NumberField15 16 14 # ====================================== 17 15 # Conversion from Singular to Sage types 18 16 # ====================================== -
sage/libs/singular/singular.pyx
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/libs/singular/singular.pyx
a b 48 48 from sage.structure.parent_base cimport ParentWithBase 49 49 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular 50 50 51 from sage.rings.number_field.number_field_base cimport NumberField 52 51 53 cdef Rational si2sa_QQ(number *n, ring *_ring): 52 54 """ 53 55 TESTS:: -
sage/rings/number_field/implementation.pxd
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/implementation.pxd
a b 1 # Abstract base class 1 2 cdef class ArithmeticImplementation: 2 3 cdef object _name 3 4 5 # Generic implementation (polynomials) 4 6 cdef class ArithmeticImplementation_generic(ArithmeticImplementation): 5 7 cdef object modulus 6 8 9 # NTL-based implementation (both relative and absolute) 7 10 cdef class ArithmeticImplementation_ntl(ArithmeticImplementation): 8 11 pass 9 12 13 # FLINT-based implementation 14 include "../../libs/flint/fmpq_poly.pxd" 10 15 cdef class ArithmeticImplementation_flint(ArithmeticImplementation): 11 pass16 cdef fmpq_poly_t modulus 12 17 18 # Singular-based implementation 13 19 cdef class ArithmeticImplementation_singular(ArithmeticImplementation): 14 20 pass 15 21 -
sage/rings/number_field/implementation.pyx
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/implementation.pyx
a b 112 112 ArithmeticImplementation.__init__(self, 'ntl') 113 113 114 114 cdef class ArithmeticImplementation_flint(ArithmeticImplementation): 115 def __init__(self ):115 def __init__(self, modulus): 116 116 """ 117 117 EXAMPLES:: 118 118 119 sage: sage.rings.number_field.implementation.ArithmeticImplementation_flint() 119 sage: R.<x> = QQ[] 120 sage: sage.rings.number_field.implementation.ArithmeticImplementation_flint(x^3+2) 120 121 Arithmetic implementation 'flint' 121 122 """ 122 123 ArithmeticImplementation.__init__(self, 'flint') 124 fmpq_poly_init(self.modulus) 125 t = str(modulus.degree()+1)+ ' ' + ' '.join([str(x) for x in modulus.list()]) 126 fmpq_poly_from_string(self.modulus, t) 127 128 def __dealloc__(self): 129 fmpq_poly_clear(self.modulus) 130 123 131 124 132 cdef class ArithmeticImplementation_singular(ArithmeticImplementation): 125 133 def __init__(self): -
sage/rings/number_field/number_field.py
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field.py
a b 1257 1257 Return a random element of this number field. 1258 1258 1259 1259 INPUT: 1260 1261 - ``num_bound`` - Bound on numerator of the coefficients of 1262 the resulting element 1263 1264 - ``den_bound`` - Bound on denominators of the coefficients 1265 of the resulting element 1266 1267 - ``integral_coefficients`` (default: False) - If True, then 1268 the resulting element will have integral 1269 coefficients. This option overrides any 1270 value of `den_bound`. 1271 1272 - ``distribution`` - Distribution to use for the coefficients 1273 of the resulting element 1274 1275 OUTPUT: 1276 1277 - Element of this number field 1260 - ``num_bound`` - Bound on numerator of the coefficients of 1261 the resulting element 1262 - ``den_bound`` - Bound on denominators of the coefficients 1263 of the resulting element 1264 - ``integral_coefficients`` (default: False) - If True, 1265 then the resulting element will have integral 1266 coefficients. This option overrides any value of 1267 `den_bound`. 1268 - ``distribution`` - Distribution to use for the coefficients 1269 of the resulting element 1270 1271 OUTPUT: 1272 - Element of this number field 1278 1273 1279 1274 EXAMPLES:: 1280 1275 … … 1292 1287 """ 1293 1288 if integral_coefficients: 1294 1289 den_bound = 1 1295 1296 1290 return self._zero_element._random_element(num_bound=num_bound, 1297 1291 den_bound=den_bound, 1298 1292 distribution=distribution) … … 1860 1854 False 1861 1855 sage: QuadraticField(2, 'a', embedding=2) == QuadraticField(2, 'a', embedding=-2) 1862 1856 False 1857 1858 Different implementations:: 1859 1860 sage: K.<a> = NumberField(x^14 - 7*x^2 + 2, implementation='ntl') 1861 sage: L.<a> = NumberField(x^14 - 7*x^2 + 2, implementation='flint') 1862 sage: K == L 1863 False 1864 sage: K == K 1865 True 1863 1866 """ 1864 1867 if not isinstance(other, NumberField_generic): 1865 1868 return cmp(type(self), type(other)) … … 1868 1871 # compare coefficients so that the polynomial variable does not count 1869 1872 c = cmp(list(self.__polynomial), list(other.__polynomial)) 1870 1873 if c: return c 1874 # compare implementations 1875 c = cmp(self.implementation(), other.implementation()) 1876 if c: return c 1871 1877 # Now we compare the embeddings (if any). 1872 1878 f, g = self.coerce_embedding(), other.coerce_embedding() 1873 1879 if f is None and g is None: … … 4802 4808 self._element_class = number_field_element_quadratic.NumberFieldElement_quadratic 4803 4809 self._order_element_class = number_field_element_quadratic.OrderElement_quadratic 4804 4810 self._set_implementation(arithmetic_implementation.ArithmeticImplementation_quadratic()) 4811 4805 4812 elif implementation == 'flint': 4806 4813 import number_field_element_flint 4807 4814 self._element_class = number_field_element_flint.NumberFieldElement_flint 4808 4815 self._order_element_class = number_field_element_flint.OrderElement_flint 4809 self._set_implementation(arithmetic_implementation.ArithmeticImplementation_flint( ))4816 self._set_implementation(arithmetic_implementation.ArithmeticImplementation_flint(polynomial)) 4810 4817 4811 4818 elif implementation == 'ntl': 4812 4819 import number_field_element_ntl -
sage/rings/number_field/number_field_element.pyx
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field_element.pyx
a b 2 2 Number Field Elements 3 3 4 4 AUTHORS: 5 6 5 - William Stein: version before it got Cython'd 7 6 - Joel B. Mohler (2007-03-09): First reimplementation in Cython 8 7 - William Stein (2007-09-04): add doctests … … 295 294 return str(x).replace(x.parent().variable_name(), K.variable_name()) 296 295 else: 297 296 # Compute representation of self in terms of relative vector space. 298 R = K.base_field()[K.variable_name()] 299 return repr(R(self.list())) 297 return self.relative_polynomial()._repr(K.variable_name()) 298 299 def relative_polynomial(self, var=None): 300 """ 301 Return the polynomial in var (default: 'x') over the base 302 field that represents this element. 303 304 EXAMPLES:: 305 306 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3]) 307 sage: f = (a+b+1)^2; f 308 (2*b + 2)*a + 2*b - 3 309 sage: f.relative_polynomial() 310 (2*b + 2)*x + 2*b - 3 311 sage: f.relative_polynomial().parent() 312 Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^2 + 3 313 sage: f.relative_polynomial('T') 314 (2*b + 2)*T + 2*b - 3 315 """ 316 if self.is_absolute(): 317 return self.polynomial(var) 318 else: 319 if var is None: var = 'x' 320 R = self.number_field().base_ring()[var] 321 return R(self.list()) 300 322 301 323 def _im_gens_(self, codomain, im_gens): 302 324 """ … … 639 661 if n < 0 or n >= self.parent().relative_degree(): 640 662 raise IndexError, "index must be between 0 and the relative degree minus 1." 641 663 return self.vector()[n] 664 665 def __getslice__(self, i, j): 666 """ 667 EXAMPLES:: 668 669 sage: K.<alpha> = NumberField(x^3 - 5/8*x + 2/5, implementation='ntl') 670 sage: f = -3*alpha^2 + 2/3*alpha + 5/7 671 sage: f[1:] 672 -3*alpha^2 + 2/3*alpha 673 sage: f[:2] 674 2/3*alpha + 5/7 675 676 A relative example:: 677 678 sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 3], implementation='ntl') 679 sage: f = (a+b+1)^2; f 680 (2*b + 2)*a + 2*b - 3 681 sage: f[:1] 682 2*b - 3 683 sage: f[1:] 684 (2*b + 2)*a 685 sage: f[:] 686 (2*b + 2)*a + 2*b - 3 687 sage: f[3:] 688 0 689 """ 690 return self.parent()(self.relative_polynomial().__getslice__(i,j)) 691 642 692 #################################################### 643 693 # Comparision 644 694 #################################################### … … 2618 2668 2619 2669 Examples in a relative order:: 2620 2670 2621 sage: x = ZZ['x'].02671 sage: R.<x> = ZZ[] 2622 2672 sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3]) 2623 2673 sage: OK = K.maximal_order() 2624 2674 sage: _, u, _, v = OK.basis() -
sage/rings/number_field/number_field_element_flint.pxd
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field_element_flint.pxd
a b 24 24 from sage.structure.element cimport RingElement, ModuleElement, Element 25 25 26 26 from number_field_element cimport NumberFieldElement 27 from number_field_base cimport NumberField 27 28 28 29 cdef class NumberFieldElement_flint(NumberFieldElement): 29 30 cdef fmpq_poly_t _f 31 cdef fmpq_poly_t _m 30 cdef fmpq_poly_t f 32 31 33 32 cdef _new(self) 33 cdef fmpq_poly_t* modulus(self) # fast parent modulus lookup 34 34 35 35 cdef class OrderElement_flint(NumberFieldElement_flint): 36 pass 36 cdef _new_nfelt(self) 37 cdef NumberField _number_field(self) 38 -
sage/rings/number_field/number_field_element_flint.pyx
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field_element_flint.pyx
a b 1 1 """ 2 2 FLINT-based implementation of number field elements 3 4 We implement basic arithmetic in absolute and relative number fields, 5 where elements are represented using a single univariate polynomial. 6 Arithmetic occurs modulo a generator for the number field. 7 8 This code is written against the FLINT C library, version 1. 3 9 """ 10 4 11 ############################################################################## 5 12 # Copyright (C) 2010 William Stein <wstein@gmail.com> 6 13 # Copyright (C) 2010 Sebastian Pancratz … … 17 24 # http://www.gnu.org/licenses/ 18 25 ############################################################################### 19 26 27 from order_base cimport Order_base 28 from implementation cimport ArithmeticImplementation_flint 29 20 30 cdef inline fmpq_poly_pow(fmpq_poly_t f, fmpq_poly_t g, unsigned long n): 21 31 fmpq_poly_power(f, g, n) 22 32 23 33 cdef class NumberFieldElement_flint(NumberFieldElement): 24 34 """ 25 35 EXAMPLES:: 36 37 We create a flint-based number field element:: 38 39 sage: K.<a> = NumberField(x^3 -x + 2, implementation='flint'); type(a) 40 <type 'sage.rings.number_field.number_field_element_flint.NumberFieldElement_flint'> 26 41 """ 42 43 cdef fmpq_poly_t* modulus(self): 44 """ 45 Return a pointer to the modulus of the parent number field. 46 This is used in basic arithmetic operations. 47 """ 48 # We get the modulus with no Python calls -- it's all a Cython/C struct lookup. 49 cdef NumberField P = self._parent 50 cdef ArithmeticImplementation_flint I = P._implementation 51 return &I.modulus 52 53 cdef _new(self): 54 """ 55 Return a new FLINT number field element with the underlying 56 fmpq_poly initialized. 57 """ 58 cdef NumberFieldElement_flint res = PY_NEW(NumberFieldElement_flint) 59 res._parent = self._parent 60 fmpq_poly_init(res.f) 61 return res 62 27 63 cpdef bint is_absolute(self): 64 """ 65 Return True since this is an alement of an absolute field. 66 67 EXAMPLES:: 68 69 sage: K.<a> = NumberField(x^3 -x + 2, implementation='flint'); a.is_absolute() 70 True 71 """ 28 72 return True 29 73 30 74 def __init__(self, parent, f): # FIXME 31 75 """ 32 76 EXAMPLES:: 77 78 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2, implementation='flint'); type(alpha) 79 <type 'sage.rings.number_field.number_field_element_flint.NumberFieldElement_flint'> 80 sage: x = K.polynomial_ring().gen() 81 sage: sage.rings.number_field.number_field_element_flint.NumberFieldElement_flint(K, x^3 + 2/3*x + 5/8) 82 alpha^3 + 2/3*alpha + 5/8 33 83 """ 34 84 self._parent = parent 35 g = parent.defining_polynomial() 36 f = g.parent()(f) 37 s = str(f.degree()+1)+ ' ' + ' '.join([str(x) for x in f.list()]) 38 t = str(g.degree()+1)+ ' ' + ' '.join([str(x) for x in g.list()]) 39 fmpq_poly_init(self._f) 40 fmpq_poly_from_string(self._f, s) 41 fmpq_poly_init(self._m) 42 fmpq_poly_from_string(self._m, t) 43 #self._m = <fmpq_poly_struct *> self._parent.__fmpq_polynomial 44 45 cdef _new(self): # FIXME 46 cdef NumberFieldElement_flint res = PY_NEW(NumberFieldElement_flint) 47 res._parent = self._parent 48 fmpq_poly_init(res._f) 49 fmpq_poly_init(res._m) 50 fmpq_poly_set(res._m, self._m) 51 #res._m = self._m 52 return res 85 fmpq_poly_init(self.f) 86 if PY_TYPE_CHECK(f, NumberFieldElement_flint): 87 fmpq_poly_set(self.f, (<NumberFieldElement_flint>f).f) 88 else: 89 f = parent.polynomial_ring()(f) 90 s = str(f.degree()+1)+ ' ' + ' '.join([str(x) for x in f.list()]) 91 fmpq_poly_from_string(self.f, s) 53 92 54 93 def __dealloc__(self): 55 fmpq_poly_clear(self._f) 56 fmpq_poly_clear(self._m) # FIXME 94 """ 95 Free memory allocated for this element. 96 """ 97 fmpq_poly_clear(self.f) 98 99 def _random_element(self, num_bound, den_bound, distribution): 100 cdef NumberFieldElement_flint x = self._new() 101 x._randomize(num_bound, den_bound, distribution) 102 return x 57 103 58 104 cdef void _randomize(self, num_bound, den_bound, distribution): 59 105 """ 60 106 EXAMPLES:: 107 108 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint') 109 sage: K.random_element() 110 -1/95*a^3 - 1/2*a^2 - 4 111 sage: K.random_element(num_bound=10^6,den_bound=10^6) 112 830119/76689*a^3 - 263147/19919*a^2 - 281029/157499*a + 950091/225847 113 sage: K.random_element(num_bound=10^6,den_bound=1) 114 -183009*a^3 - 446372*a^2 + 722086*a + 347486 61 115 """ 62 # TODO 63 pass 116 cdef Py_ssize_t n 117 cdef Rational x 118 K = self._parent.base_field() 119 for n in range(self._parent.degree()): 120 x = K.random_element(num_bound, den_bound, distribution) 121 fmpq_poly_set_coeff_mpq(self.f, n, x.value) 64 122 65 123 def __getitem__(self, long n): 66 124 """ 67 125 EXAMPLES:: 126 127 sage: K.<alpha> = NumberField(x^3 - 5/8*x + 2/5, implementation='flint') 128 sage: f = -3*alpha^2 + 2/3*alpha + 5/7 129 sage: f[0] 130 5/7 131 sage: f[1] 132 2/3 133 sage: f[2] 134 -3 135 sage: f[-1] 136 Traceback (most recent call last): 137 ... 138 IndexError: index must be between 0 and degree minus 1. 139 sage: f[3] 140 Traceback (most recent call last): 141 ... 142 IndexError: index must be between 0 and degree minus 1. 143 144 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2, implementation='flint') 145 sage: f = 1 + 2/3*alpha; f 146 2/3*alpha + 1 147 sage: f[4] 148 0 149 sage: f[5] 150 Traceback (most recent call last): 151 ... 152 IndexError: index must be between 0 and degree minus 1. 68 153 """ 69 154 cdef Rational res = PY_NEW(Rational) 70 if 0 <= n and n < fmpq_poly_length(self._f): 71 fmpq_poly_get_coeff_mpq(res.value, self._f, n) 155 if 0 <= n and n < fmpq_poly_length(self.f): 156 fmpq_poly_get_coeff_mpq(res.value, self.f, n) 157 if n >= fmpq_poly_length(self.modulus()[0])-1: 158 raise IndexError, "index must be between 0 and degree minus 1." 72 159 return res 73 160 74 161 def __getslice__(self, long i, long j): 75 162 """ 76 163 EXAMPLES:: 164 165 sage: K.<alpha> = NumberField(x^4 - 2/3*x + 2/7, implementation='flint') 166 sage: f = (1+2/3*alpha)^3; f 167 8/27*alpha^3 + 4/3*alpha^2 + 2*alpha + 1 168 sage: f[1:] 169 8/27*alpha^3 + 4/3*alpha^2 + 2*alpha 170 sage: f[1:3] 171 4/3*alpha^2 + 2*alpha 172 sage: f[:3] 173 4/3*alpha^2 + 2*alpha + 1 77 174 """ 78 175 cdef NumberFieldElement_flint res = self._new() 79 fmpq_poly_getslice(res. _f, self._f, i, j)176 fmpq_poly_getslice(res.f, self.f, i, j) 80 177 return res 81 178 179 def list(self): 180 """ 181 Return list that defines this element. 182 183 EXAMPLES:: 184 185 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2, implementation='flint') 186 sage: f = 1+2/3*alpha; f 187 2/3*alpha + 1 188 sage: f = (1+2/3*alpha)^3; f 189 8/27*alpha^3 + 4/3*alpha^2 + 2*alpha + 1 190 sage: f.list() 191 [1, 2, 4/3, 8/27, 0] 192 sage: f.vector() 193 (1, 2, 4/3, 8/27, 0) 194 """ 195 # TODO: make fast 196 return [self[i] for i in range(fmpq_poly_length(self.modulus()[0])-1)] 197 82 198 def polynomial(self, var=None): # FIXME 83 199 """ 84 200 EXAMPLES:: 201 202 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2, implementation='flint') 203 sage: f = (1+2/3*alpha)^3; f 204 8/27*alpha^3 + 4/3*alpha^2 + 2*alpha + 1 205 sage: f.polynomial() 206 8/27*x^3 + 4/3*x^2 + 2*x + 1 207 sage: f.polynomial('W') 208 8/27*W^3 + 4/3*W^2 + 2*W + 1 85 209 """ 86 cdef unsigned long i, n87 210 if var is None: 88 from sage.rings.rational_field import QQ 89 from sage.rings.polynomial.polynomial_ring import polygen 90 t = polygen(QQ) 91 n = fmpq_poly_length(self._f) 92 res = self[0] 93 for i in xrange(1, n): 94 res = res + self[i] * t**i 95 return res 211 return self._parent.polynomial_ring()(self.list()) 96 212 else: 97 return self.polynomial().change_variable (var)213 return self.polynomial().change_variable_name(var) 98 214 99 215 cpdef RingElement _mul_(left, RingElement right): 100 216 """ 101 217 EXAMPLES:: 218 219 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 220 sage: (1/3 - 4/3*alpha) * (9/7 + alpha^4) # indirect doctest 221 1/3*alpha^4 - 164/63*alpha + 17/21 102 222 """ 103 223 cdef NumberFieldElement_flint res = left._new() 104 fmpq_poly_mul(res. _f, left._f, (<NumberFieldElement_flint> right)._f)105 fmpq_poly_mod(res. _f, res._f, left._m)224 fmpq_poly_mul(res.f, left.f, (<NumberFieldElement_flint> right).f) 225 fmpq_poly_mod(res.f, res.f, left.modulus()[0]) 106 226 return res 107 227 108 228 cpdef ModuleElement _add_(left, ModuleElement right): 109 229 """ 110 230 EXAMPLES:: 231 232 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 233 sage: (1/3 - 4/3*alpha) + (9/7 + alpha^4) 234 alpha^4 - 4/3*alpha + 34/21 111 235 """ 112 236 cdef NumberFieldElement_flint res = left._new() 113 fmpq_poly_add(res. _f, left._f, (<NumberFieldElement_flint> right)._f)237 fmpq_poly_add(res.f, left.f, (<NumberFieldElement_flint> right).f) 114 238 return res 115 239 116 240 cpdef ModuleElement _sub_(left, ModuleElement right): 117 241 """ 118 242 EXAMPLES:: 243 244 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 245 sage: (1/3 - 4/3*alpha) - (9/7 + alpha^4) 246 -alpha^4 - 4/3*alpha - 20/21 119 247 """ 120 248 cdef NumberFieldElement_flint res = left._new() 121 fmpq_poly_sub(res. _f, left._f, (<NumberFieldElement_flint> right)._f)249 fmpq_poly_sub(res.f, left.f, (<NumberFieldElement_flint> right).f) 122 250 return res 123 251 124 cpdef RingElement _div_( left, RingElement right):252 cpdef RingElement _div_(self, RingElement right): 125 253 """ 126 254 EXAMPLES:: 255 256 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 257 sage: (1/3 - 4/3*alpha) / (9/7 + alpha^4) 258 -1400273/25440921*alpha^4 - 68306/8480307*alpha^3 - 3332/2826769*alpha^2 - 1930964/2826769*alpha + 8201599/76322763 127 259 """ 128 return left * (~right) # FIXME 260 if fmpq_poly_is_zero((<NumberFieldElement_flint>right).f): 261 raise ZeroDivisionError 262 263 cdef NumberFieldElement_flint u = self._new() 264 cdef fmpq_poly_t d, v 265 fmpq_poly_init(d); fmpq_poly_init(v) 266 fmpq_poly_xgcd(d, u.f, v, (<NumberFieldElement_flint>right).f, self.modulus()[0]) 267 fmpq_poly_mul(u.f, u.f, self.f) 268 fmpq_poly_mod(u.f, u.f, self.modulus()[0]) 269 fmpq_poly_clear(d); fmpq_poly_clear(v) 270 return u 129 271 130 272 def __invert__(self): 131 273 """ 132 274 EXAMPLES:: 275 276 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 277 sage: ~(9/7 + alpha^4) 278 -3377129/8480307*alpha^4 - 164738/2826769*alpha^3 - 24108/2826769*alpha^2 - 3528/2826769*alpha + 19780327/25440921 279 sage: ~K(0) 280 Traceback (most recent call last): 281 ... 282 ZeroDivisionError: cannot invert zero 133 283 """ 134 cdef NumberFieldElement_flint u 284 if fmpq_poly_is_zero(self.f): 285 raise ZeroDivisionError, "cannot invert zero" 286 cdef NumberFieldElement_flint u = self._new() 135 287 cdef fmpq_poly_t d, v 136 if fmpq_poly_is_zero(self._f):137 raise ValueError, "cannot invert zero"138 u = self._new()139 288 fmpq_poly_init(d) 140 289 fmpq_poly_init(v) 141 fmpq_poly_xgcd(d, u. _f, v, self._f, self._m)142 fmpq_poly_mod(u. _f, u._f, self._m)290 fmpq_poly_xgcd(d, u.f, v, self.f, self.modulus()[0]) 291 fmpq_poly_mod(u.f, u.f, self.modulus()[0]) 143 292 fmpq_poly_clear(d) 144 293 fmpq_poly_clear(v) 145 294 return u … … 147 296 def __richcmp__(left, right, int op): 148 297 """ 149 298 EXAMPLES:: 299 300 sage: K.<alpha> = NumberField(x^4 - 2/3*x + 2/7, implementation='flint') 301 sage: a = (9/7 - 4/3*alpha^4); b = (9/7 + alpha^4) 302 sage: a < b 303 True 304 sage: b > a 305 True 306 sage: a == a 307 True 150 308 """ 151 309 return (<Element>left)._richcmp(right, op) 152 310 153 311 cdef int _cmp_c_impl(left, Element right) except -2: 154 312 """ 155 313 EXAMPLES:: 314 315 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2/7, implementation='flint') 316 sage: a = (1/3 - 4/3*alpha); b = (9/7 + alpha^4) 317 sage: a < b 318 True 319 sage: b > a 320 True 321 sage: a == b 322 False 323 sage: a != b 324 True 325 sage: a == a 326 True 327 sage: a.polynomial() < b.polynomial() 328 True 329 156 330 """ 157 return fmpq_poly_cmp(left. _f, (<NumberFieldElement_flint> right)._f)331 return fmpq_poly_cmp(left.f, (<NumberFieldElement_flint> right).f) 158 332 159 333 def _integer_(self, Z=None): 160 334 """ 161 335 EXAMPLES:: 336 337 sage: K.<alpha> = NumberField(x^4 - 2/3*x + 2/7, implementation='flint') 338 sage: K(5)._integer_() 339 5 340 sage: parent(K(5)._integer_()) 341 Integer Ring 342 sage: K(5/3)._integer_() 343 Traceback (most recent call last): 344 ... 345 TypeError 346 sage: ZZ(K(5)) 347 5 162 348 """ 163 return Z(self) 164 349 if fmpq_poly_length(self.f) == 0: 350 return Z.zero_element() 351 elif fmpq_poly_length(self.f) == 1: 352 r = self[0] 353 if r.is_integral(): 354 return r.numerator() 355 raise TypeError 356 165 357 def _rational_(self): 166 358 """ 167 359 EXAMPLES:: 360 361 sage: K.<alpha> = NumberField(x^4 - 2/3*x + 2/7, implementation='flint') 362 sage: K(5/3)._rational_() 363 5/3 364 sage: parent(K(5)._rational_()) 365 Rational Field 366 sage: parent(K(5/3)._rational_()) 367 Rational Field 368 sage: alpha._rational_() 369 Traceback (most recent call last): 370 ... 371 TypeError: cannot coerce nonconstant polynomial 168 372 """ 169 373 cdef Rational res 170 cdef unsigned long len = fmpq_poly_length(self. _f)374 cdef unsigned long len = fmpq_poly_length(self.f) 171 375 if len == 0: 172 376 res = PY_NEW(Rational) 173 377 return res 174 378 elif len == 1: 175 379 res = PY_NEW(Rational) 176 fmpq_poly_get_coeff_mpq(<mpq_t>res.value, self. _f, 0)380 fmpq_poly_get_coeff_mpq(<mpq_t>res.value, self.f, 0) 177 381 return res 178 382 else: 179 383 raise TypeError, "cannot coerce nonconstant polynomial" 180 384 181 385 cdef class OrderElement_flint(NumberFieldElement_flint): 182 #cdef _new(self): 183 # raise NotImplementedError 184 #cdef _new_nfelt(self): 185 # raise NotImplementedError 386 cdef _new(self): 387 """ 388 Construct a new order element very quickly, setting the parent 389 and initializing the underlying fmpq_poly. 390 """ 391 cdef OrderElement_flint res = PY_NEW(OrderElement_flint) 392 res._parent = self._parent 393 fmpq_poly_init(res.f) 394 return res 395 396 cdef _new_nfelt(self): 397 """ 398 Construct a new number field element very quickly, setting the 399 parent and initializing the underlying fmpq_poly. 400 """ 401 cdef NumberFieldElement_flint res = PY_NEW(NumberFieldElement_flint) 402 res._parent = self._number_field() 403 fmpq_poly_init(res.f) 404 return res 405 406 cdef NumberField _number_field(self): 407 """ 408 Quickly return the ambient number field. 409 """ 410 return (<Order_base>self._parent)._K 411 412 cdef fmpq_poly_t* modulus(self): 413 """ 414 Return a pointer to the modulus of the parent number field. 415 This is used in basic arithmetic operations. 416 """ 417 # We get the modulus with no Python calls -- it's all a Cython/C struct lookup. 418 cdef Order_base P = self._parent 419 cdef ArithmeticImplementation_flint I = P._implementation 420 return &I.modulus 421 186 422 def __init__(self, parent, f): 187 raise NotImplementedError 423 """ 424 EXAMPLES:: 425 426 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1; b 427 a 428 sage: type(b) 429 <type 'sage.rings.number_field.number_field_element_flint.OrderElement_flint'> 430 """ 431 self._parent = parent 432 fmpq_poly_init(self.f) 433 if PY_TYPE_CHECK(f, NumberFieldElement_flint): 434 fmpq_poly_set(self.f, (<NumberFieldElement_flint>f).f) 435 else: 436 f = self.number_field().polynomial_ring()(f) 437 s = str(f.degree()+1)+ ' ' + ' '.join([str(x) for x in f.list()]) 438 fmpq_poly_from_string(self.f, s) 439 440 def __dealloc__(self): 441 """ 442 Free memory allocated for this element. 443 """ 444 fmpq_poly_clear(self.f) 445 188 446 cpdef bint is_order_element(self): 447 """ 448 EXAMPLES:: 449 450 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 451 sage: b.is_order_element() 452 True 453 """ 189 454 return True 455 190 456 cpdef RingElement _mul_(left, RingElement right): 191 raise NotImplementedError 457 """ 458 EXAMPLES:: 459 460 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 461 sage: (b^3+7*b+5) * (2*b^2-b+3) 462 31*a^3 - 4*a^2 + 12*a + 17 463 """ 464 cdef OrderElement_flint res = left._new() 465 fmpq_poly_mul(res.f, left.f, (<OrderElement_flint> right).f) 466 fmpq_poly_mod(res.f, res.f, left.modulus()[0]) 467 return res 468 192 469 cpdef ModuleElement _add_(left, ModuleElement right): 193 raise NotImplementedError 470 """ 471 EXAMPLES:: 472 473 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 474 sage: (b^3+7*b+5) + (2*b^2-b+3) 475 a^3 + 2*a^2 + 6*a + 8 476 """ 477 cdef OrderElement_flint res = left._new() 478 fmpq_poly_add(res.f, left.f, (<OrderElement_flint> right).f) 479 return res 480 481 194 482 cpdef ModuleElement _sub_(left, ModuleElement right): 195 raise NotImplementedError 196 cpdef RingElement _div_(left, RingElement right): 197 raise NotImplementedError 483 """ 484 EXAMPLES:: 485 486 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 487 sage: (b^3+7*b+5) - (2*b^2-b+3) 488 a^3 - 2*a^2 + 8*a + 2 489 """ 490 cdef OrderElement_flint res = left._new() 491 fmpq_poly_sub(res.f, left.f, (<OrderElement_flint> right).f) 492 return res 493 494 cpdef RingElement _div_(self, RingElement right): 495 """ 496 EXAMPLES:: 497 498 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 499 sage: (b^3+7*b+5) / (2*b^2-b+3) 500 -827/3316*a^3 - 483/3316*a^2 + 4223/1658*a + 2717/1658 501 """ 502 if fmpq_poly_is_zero((<OrderElement_flint>right).f): 503 raise ZeroDivisionError 504 505 cdef NumberFieldElement_flint u = self._new_nfelt() 506 cdef fmpq_poly_t d, v 507 fmpq_poly_init(d); fmpq_poly_init(v) 508 fmpq_poly_xgcd(d, u.f, v, (<OrderElement_flint>right).f, self.modulus()[0]) 509 fmpq_poly_mul(u.f, u.f, self.f) 510 fmpq_poly_mod(u.f, u.f, self.modulus()[0]) 511 fmpq_poly_clear(d); fmpq_poly_clear(v) 512 return u 513 198 514 def __invert__(self): 199 raise NotImplementedError 515 """ 516 EXAMPLES:: 517 518 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='flint'); R = K.maximal_order(); b = R.1 519 sage: c = (2*b^2-b+3); ~c 520 -39/3316*a^3 - 115/3316*a^2 + 137/1658*a + 489/1658 521 sage: (~c)*c 522 1 523 """ 524 if fmpq_poly_is_zero(self.f): 525 raise ZeroDivisionError, "cannot invert zero" 526 cdef NumberFieldElement_flint u = self._new_nfelt() 527 cdef fmpq_poly_t d, v 528 fmpq_poly_init(d) 529 fmpq_poly_init(v) 530 fmpq_poly_xgcd(d, u.f, v, self.f, self.modulus()[0]) 531 fmpq_poly_mod(u.f, u.f, self.modulus()[0]) 532 fmpq_poly_clear(d) 533 fmpq_poly_clear(v) 534 return u 535 200 536 def __richcmp__(left, right, int op): 537 """ 538 Comparison is comparison on the underlying polynomial representatives. 539 540 EXAMPLES:: 541 542 sage: K.<a> = NumberField(x^4 - 7*x^2 + 2, implementation='ntl'); R = K.maximal_order(); b = R.1 543 sage: s = (b^3+7*b+5); t = (2*b^2-b+3) 544 sage: cmp(s,t) 545 1 546 sage: cmp(s.polynomial(), t.polynomial()) 547 1 548 sage: s < t 549 False 550 sage: t > s 551 False 552 """ 201 553 return (<Element>left)._richcmp(right, op) 554 202 555 cdef int _cmp_c_impl(left, Element right) except -2: 203 raise NotImplementedError 556 return fmpq_poly_cmp(left.f, (<NumberFieldElement_flint> right).f) 557 558 def polynomial(self, var=None): 559 """ 560 EXAMPLES:: 561 562 sage: K.<alpha> = NumberField(x^5 - 2/3*x + 2, implementation='flint') 563 sage: f = (1+2/3*alpha)^3; f 564 8/27*alpha^3 + 4/3*alpha^2 + 2*alpha + 1 565 sage: f.polynomial() 566 8/27*x^3 + 4/3*x^2 + 2*x + 1 567 sage: f.polynomial('W') 568 8/27*W^3 + 4/3*W^2 + 2*W + 1 569 """ 570 if var is None: 571 return self.number_field().polynomial_ring()(self.list()) 572 else: 573 return self.polynomial().change_variable_name(var) -
sage/rings/number_field/number_field_element_generic.pyx
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field_element_generic.pyx
a b 111 111 """ 112 112 # We get the modulus with no Python calls -- it's all a Cython/C struct lookup. 113 113 cdef NumberField P = self._parent 114 cdef ArithmeticImplementation_generic I = P. implementation()114 cdef ArithmeticImplementation_generic I = P._implementation 115 115 return I.modulus 116 116 117 117 cpdef RingElement _mul_(left, RingElement right): … … 357 357 358 358 def __richcmp__(left, right, int op): 359 359 """ 360 EXAMPLES:: 361 362 sage: K.<a> = NumberField(x^3 -x + 2, implementation='generic'); b = K.maximal_order()(a^2-3) 363 sage: b == b 364 True 365 sage: b < b 366 False 367 sage: b < b+1 368 True 369 sage: b + 1 > b 370 True 360 371 """ 361 372 return (<Element>left)._richcmp(right, op) 362 373 -
sage/rings/number_field/order.py
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/order.py
a b 863 863 Return a random element of this order. 864 864 865 865 INPUT: 866 867 - ``args``, ``kwds`` -- parameters passed to the random 868 integer function. See the documentation for 869 ``ZZ.random_element()`` for details. 866 - ``args``, ``kwds`` -- parameters passed to the random 867 integer function. See the documentation for 868 ``ZZ.random_element()`` for details. 870 869 871 870 OUTPUT: 872 871 -
sage/rings/number_field/order_base.pxd
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/order_base.pxd
a b 2 2 from implementation cimport ArithmeticImplementation 3 3 4 4 cdef class Order_base(IntegralDomain): 5 cdef public object _K # number field 5 6 cdef ArithmeticImplementation _implementation 6 7 cpdef ArithmeticImplementation implementation(self) 7 8 cpdef _set_implementation(self, ArithmeticImplementation implementation) -
sage/rings/number_field/todo.txt
diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/todo.txt
a b 25 25 [x] test stabilization 26 26 [x] increase coverage a lot 27 27 [x] fix all doctests outside number_field directory (except pickling) 28 [x] generic elements 29 [x] get doctest coverage of 'generic' to 100% 30 [x] implement OrderElement_generic 28 31 29 [ ] generic: get to work in the *relative case* 32 [x] flint elements 33 [x] implement OrderElement_flint 30 34 31 35 [ ] rewrite order elements to use implementation, e.g., this line in order.py: 32 36 #TODO: fix this 33 37 from number_field_element_ntl import OrderElement_absolute, OrderElement_relative 34 38 35 [ ] implement OrderElement_generic, _singular, _flint 36 [ ] get doctest coverage of 'generic' to 100% 39 [ ] implement OrderElement_singular 40 41 [ ] generic: get to work in the *relative case* 42 43 [ ] libsingular elements 44 37 45 [ ] get implementation = 'generic' to fully work as another default type 38 46 39 47 [ ] move data out of elements into implementation objects for ntl and quadratic types 40 48 41 49 [ ] fix all INPUT block list formatting 42 50 43 [ ] generic elements44 45 [ ] libsingular elements46 [ ] flint elements47 48 51 [ ] rewrite base class "def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0):" 49 52 50 [ ] make default implementation computation be centralized ?53 [ ] make default implementation computation be centralized somehow?? 51 54 52 55 [ ] fix unpickling of old nf elts 53 56 54 [ ] fix order.py -- it explicitly references ntl but must not.55 57 [ ] change number_field_element_quadratic to derive from 56 58 number_field_element code (i.e., the abstract base), instead of 57 59 deriving from number_field_element_ntl. 60 58 61 [ ] write generic ver def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0): 59 62 of this in number_field_element.pyx 63 60 64 [ ] make sure the _cmp_c_impl's are compatible across number field element implementations. 65 61 66 [ ] format all documentation perfectly 67 62 68 [ ] make the implementation part of elements into a cython class hierarchy with 63 69 [ ] implementation object needs to get pickled with number field -- test 64 70 [ ] flint implementation object 65 71 [ ] libsingular implementation object 72 66 73 [ ] benchmark *every single operation* with each type of elements... for sanity 67 74 [ ] benchmark for comparison with magma 75 68 76 [ ] get doctest coverage to 100% for the number_field directory 77 69 78 [ ] arithmetic/automatic coercions between isomorphic fields, where 70 79 the only difference is the underlying implementation of 71 80 elements. 81 72 82 [ ] other stuff in the library outside the rings directory: 73 83 [ ] come up with a Cython api for digging into internals of any 74 84 kind of number field element, which is good enough to deal 75 85 with the following: 76 86 [ ] quaternion algebra elements -- deal with that they only work for ntl number field elements 77 87 [ ] matrix_cyclo_dense.pyx 88 78 89 [ ] write a function that can be included in doctests that 79 90 guarantees at least a certain amount of speed. add this to 80 91 library so that nobody can frack my shizzle up. 92 81 93 [ ] add proper headers 82 94 [ ] add overview docs to each file 83 95 [ ] overview of everything … … 85 97 [ ] rebase 2 -- make sure my fast mod-p reduction works. 86 98 [ ] get refereed 87 99 [ ] check through todo 88 [ ] cach eing in number_field_element.pxd seems excessive100 [ ] caching in number_field_element.pxd seems excessive 89 101 [ ] suspicious bound: 90 102 " D = (Dpoly.numer() * Dpoly.denom()).squarefree_part(bound=10000) " 91 103 104 OTHER: 105 92 106 [ ] optimize -- creation of the order generated by elements, especially in relative case (use singular?) 93 107 [ ] plug in sebastian's code for QQ['x']? 94 108 [ ] Organize a similar refactoring for function fields.