Ticket #9541: trac_9541-part6-flint_elts.patch

File trac_9541-part6-flint_elts.patch, 45.3 KB (added by was, 7 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  
    523523              sources = ['sage/libs/singular/singular.pyx'],
    524524              libraries = ['m', 'readline', 'singular', 'givaro', 'ntl', 'gmpxx', 'gmp'],
    525525              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/'],             
    527528              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
    528529   
    529530    Extension('sage.libs.singular.polynomial',
    530531              sources = ['sage/libs/singular/polynomial.pyx'],
    531532              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
    532533              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/'],
    534536              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
    535537
    536538    Extension('sage.libs.singular.ring',
    537539              sources = ['sage/libs/singular/ring.pyx'],
    538540              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
    539541              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/'],
    541543              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
    542544
    543545    Extension('sage.libs.singular.groebner_strategy',
     
    11991201        ################################
    12001202
    12011203    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              ),
    12031208
    12041209    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"]),
    12061215
    12071216    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   
    12101222    Extension('sage.rings.number_field.number_field_element',
    12111223              sources = ['sage/rings/number_field/number_field_element.pyx']),
    12121224
    12131225    Extension('sage.rings.number_field.number_field_element_ntl',
    12141226              sources = ['sage/rings/number_field/number_field_element_ntl.pyx'],
    12151227              libraries=['ntl','gmp'],
    1216               language = 'c++'),
     1228              language = 'c++',
     1229              include_dirs = [SAGE_ROOT+'/local/include/FLINT/', SAGE_ROOT+'/devel/sage/sage/libs/flint']),
    12171230
    12181231    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              ),
    12201236   
    12211237    Extension('sage.rings.number_field.number_field_element_flint',
    12221238              sources = ['sage/rings/number_field/number_field_element_flint.pyx', "sage/libs/flint/fmpq_poly.c"],
     
    13441360              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'],
    13451361              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
    13461362              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                              ],
    13481367              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
    13491368
    13501369    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  
    3232    int fmpq_poly_is_zero(fmpq_poly_t)
    3333   
    3434    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)   
    3536    void fmpq_poly_set_coeff_si(fmpq_poly_t, unsigned long, long)
    3637   
    3738    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  
    1111from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
    1212from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
    1313
    14 from sage.rings.number_field.number_field_base cimport NumberField
    15 
    1614# ======================================
    1715# Conversion from Singular to Sage types
    1816# ======================================
  • sage/libs/singular/singular.pyx

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/libs/singular/singular.pyx
    a b  
    4848from sage.structure.parent_base cimport ParentWithBase
    4949from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
    5050
     51from sage.rings.number_field.number_field_base cimport NumberField
     52
    5153cdef Rational si2sa_QQ(number *n, ring *_ring):
    5254    """
    5355    TESTS::
  • sage/rings/number_field/implementation.pxd

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/implementation.pxd
    a b  
     1# Abstract base class
    12cdef class ArithmeticImplementation:
    23    cdef object _name
    34
     5# Generic implementation (polynomials)
    46cdef class ArithmeticImplementation_generic(ArithmeticImplementation):
    57    cdef object modulus
    6    
     8
     9# NTL-based implementation (both relative and absolute)
    710cdef class ArithmeticImplementation_ntl(ArithmeticImplementation):
    811    pass
    912
     13# FLINT-based implementation
     14include "../../libs/flint/fmpq_poly.pxd"
    1015cdef class ArithmeticImplementation_flint(ArithmeticImplementation):
    11     pass
     16    cdef fmpq_poly_t modulus
    1217
     18# Singular-based implementation
    1319cdef class ArithmeticImplementation_singular(ArithmeticImplementation):
    1420    pass
    1521
  • sage/rings/number_field/implementation.pyx

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/implementation.pyx
    a b  
    112112        ArithmeticImplementation.__init__(self, 'ntl')
    113113
    114114cdef class ArithmeticImplementation_flint(ArithmeticImplementation):
    115     def __init__(self):
     115    def __init__(self, modulus):
    116116        """
    117117        EXAMPLES::
    118118
    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)
    120121            Arithmetic implementation 'flint'
    121122        """
    122123        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       
    123131
    124132cdef class ArithmeticImplementation_singular(ArithmeticImplementation):
    125133    def __init__(self):
  • sage/rings/number_field/number_field.py

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/number_field.py
    a b  
    12571257        Return a random element of this number field.
    12581258       
    12591259        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
    12781273       
    12791274        EXAMPLES::
    12801275       
     
    12921287        """
    12931288        if integral_coefficients:
    12941289            den_bound = 1
    1295        
    12961290        return self._zero_element._random_element(num_bound=num_bound,
    12971291                                                  den_bound=den_bound,
    12981292                                                  distribution=distribution)
     
    18601854            False
    18611855            sage: QuadraticField(2, 'a', embedding=2) == QuadraticField(2, 'a', embedding=-2)
    18621856            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
    18631866        """
    18641867        if not isinstance(other, NumberField_generic):
    18651868            return cmp(type(self), type(other))
     
    18681871        # compare coefficients so that the polynomial variable does not count
    18691872        c = cmp(list(self.__polynomial), list(other.__polynomial))
    18701873        if c: return c
     1874        # compare implementations
     1875        c = cmp(self.implementation(), other.implementation())
     1876        if c: return c
    18711877        # Now we compare the embeddings (if any).
    18721878        f, g = self.coerce_embedding(), other.coerce_embedding()
    18731879        if f is None and g is None:
     
    48024808            self._element_class = number_field_element_quadratic.NumberFieldElement_quadratic
    48034809            self._order_element_class = number_field_element_quadratic.OrderElement_quadratic
    48044810            self._set_implementation(arithmetic_implementation.ArithmeticImplementation_quadratic())
     4811
    48054812        elif implementation == 'flint':
    48064813            import number_field_element_flint
    48074814            self._element_class = number_field_element_flint.NumberFieldElement_flint
    48084815            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))
    48104817
    48114818        elif implementation == 'ntl':
    48124819            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  
    22Number Field Elements
    33
    44AUTHORS:
    5 
    65   - William Stein: version before it got Cython'd
    76   - Joel B. Mohler (2007-03-09): First reimplementation in Cython
    87   - William Stein (2007-09-04): add doctests
     
    295294            return str(x).replace(x.parent().variable_name(), K.variable_name())
    296295        else:
    297296            # 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())
    300322
    301323    def _im_gens_(self, codomain, im_gens):
    302324        """
     
    639661            if n < 0 or n >= self.parent().relative_degree():
    640662                raise IndexError, "index must be between 0 and the relative degree minus 1."
    641663            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
    642692    ####################################################
    643693    # Comparision
    644694    ####################################################
     
    26182668
    26192669        Examples in a relative order::
    26202670
    2621             sage: x = ZZ['x'].0
     2671            sage: R.<x> = ZZ[]
    26222672            sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3])
    26232673            sage: OK = K.maximal_order()
    26242674            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  
    2424from sage.structure.element cimport RingElement, ModuleElement, Element
    2525
    2626from number_field_element cimport NumberFieldElement
     27from number_field_base cimport NumberField
    2728
    2829cdef class NumberFieldElement_flint(NumberFieldElement):
    29 
    30     cdef fmpq_poly_t _f
    31     cdef fmpq_poly_t _m
     30    cdef fmpq_poly_t f
    3231
    3332    cdef _new(self)
     33    cdef fmpq_poly_t* modulus(self)  # fast parent modulus lookup
    3434   
    3535cdef 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  
    11"""
    22FLINT-based implementation of number field elements
     3
     4We implement basic arithmetic in absolute and relative number fields,
     5where elements are represented using a single univariate polynomial.
     6Arithmetic occurs modulo a generator for the number field.
     7
     8This code is written against the FLINT C library, version 1.
    39"""
     10
    411##############################################################################
    512#       Copyright (C) 2010 William Stein <wstein@gmail.com>
    613#       Copyright (C) 2010 Sebastian Pancratz
     
    1724#                  http://www.gnu.org/licenses/
    1825###############################################################################
    1926
     27from order_base cimport Order_base
     28from implementation cimport ArithmeticImplementation_flint
     29
    2030cdef inline fmpq_poly_pow(fmpq_poly_t f, fmpq_poly_t g, unsigned long n):
    2131    fmpq_poly_power(f, g, n)
    2232
    2333cdef class NumberFieldElement_flint(NumberFieldElement):
    2434    """
    2535    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'>
    2641    """
     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
    2763    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        """
    2872        return True
    2973   
    3074    def __init__(self, parent, f): # FIXME
    3175        """
    3276        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
    3383        """
    3484        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)
    5392
    5493    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
    57103
    58104    cdef void _randomize(self, num_bound, den_bound, distribution):
    59105        """
    60106        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
    61115        """
    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)
    64122
    65123    def __getitem__(self, long n):
    66124        """
    67125        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.
    68153        """
    69154        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."
    72159        return res
    73160
    74161    def __getslice__(self, long i, long j):
    75162        """
    76163        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
    77174        """
    78175        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)
    80177        return res
    81178
     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
    82198    def polynomial(self, var=None): # FIXME
    83199        """
    84200        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
    85209        """
    86         cdef unsigned long i, n
    87210        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())
    96212        else:
    97             return self.polynomial().change_variable(var)
     213            return self.polynomial().change_variable_name(var)
    98214
    99215    cpdef RingElement _mul_(left, RingElement right):
    100216        """
    101217        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
    102222        """
    103223        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])
    106226        return res
    107227
    108228    cpdef ModuleElement _add_(left, ModuleElement right):
    109229        """
    110230        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
    111235        """
    112236        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)
    114238        return res
    115239
    116240    cpdef ModuleElement _sub_(left, ModuleElement right):
    117241        """
    118242        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
    119247        """
    120248        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)
    122250        return res
    123251
    124     cpdef RingElement _div_(left, RingElement right):
     252    cpdef RingElement _div_(self, RingElement right):
    125253        """
    126254        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
    127259        """
    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
    129271
    130272    def __invert__(self):
    131273        """
    132274        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
    133283        """
    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()
    135287        cdef fmpq_poly_t d, v
    136         if fmpq_poly_is_zero(self._f):
    137             raise ValueError, "cannot invert zero"
    138         u = self._new()
    139288        fmpq_poly_init(d)
    140289        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])
    143292        fmpq_poly_clear(d)
    144293        fmpq_poly_clear(v)
    145294        return u
     
    147296    def __richcmp__(left, right, int op):
    148297        """
    149298        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
    150308        """
    151309        return (<Element>left)._richcmp(right, op)
    152310
    153311    cdef int _cmp_c_impl(left, Element right) except -2:
    154312        """
    155313        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       
    156330        """
    157         return fmpq_poly_cmp(left._f, (<NumberFieldElement_flint> right)._f)
     331        return fmpq_poly_cmp(left.f, (<NumberFieldElement_flint> right).f)
    158332
    159333    def _integer_(self, Z=None):
    160334        """
    161335        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
    162348        """
    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   
    165357    def _rational_(self):
    166358        """
    167359        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
    168372        """
    169373        cdef Rational res
    170         cdef unsigned long len = fmpq_poly_length(self._f)
     374        cdef unsigned long len = fmpq_poly_length(self.f)
    171375        if len == 0:
    172376            res = PY_NEW(Rational)
    173377            return res
    174378        elif len == 1:
    175379            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)
    177381            return res
    178382        else:
    179383            raise TypeError, "cannot coerce nonconstant polynomial"
    180384
    181385cdef 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   
    186422    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
    188446    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        """
    189454        return True
     455
    190456    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   
    192469    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
    194482    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       
    198514    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   
    200536    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        """
    201553        return (<Element>left)._richcmp(right, op)
     554   
    202555    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  
    111111        """
    112112        # We get the modulus with no Python calls -- it's all a Cython/C struct lookup.
    113113        cdef NumberField P = self._parent
    114         cdef ArithmeticImplementation_generic I = P.implementation()
     114        cdef ArithmeticImplementation_generic I = P._implementation
    115115        return I.modulus
    116116
    117117    cpdef RingElement _mul_(left, RingElement right):
     
    357357
    358358    def __richcmp__(left, right, int op):
    359359        """
     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
    360371        """
    361372        return (<Element>left)._richcmp(right, op)
    362373
  • sage/rings/number_field/order.py

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/order.py
    a b  
    863863        Return a random element of this order.
    864864
    865865        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.
    870869
    871870        OUTPUT:
    872871
  • sage/rings/number_field/order_base.pxd

    diff -r f8a3a8cdcf94 -r f09d5a19ec34 sage/rings/number_field/order_base.pxd
    a b  
    22from implementation cimport ArithmeticImplementation
    33
    44cdef class Order_base(IntegralDomain):
     5    cdef public object _K   # number field
    56    cdef ArithmeticImplementation _implementation
    67    cpdef ArithmeticImplementation implementation(self)
    78    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  
    2525   [x] test stabilization
    2626   [x] increase coverage a lot
    2727   [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
    2831
    29    [ ] generic: get to work in the *relative case*
     32   [x] flint elements
     33   [x] implement OrderElement_flint
    3034
    3135   [ ] rewrite order elements to use implementation, e.g., this line in order.py:
    3236       #TODO: fix this
    3337       from number_field_element_ntl import OrderElement_absolute, OrderElement_relative
    3438
    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
    3745   [ ] get implementation = 'generic' to fully work as another default type
    3846
    3947   [ ] move data out of elements into implementation objects for ntl and quadratic types
    4048
    4149   [ ] fix all INPUT block list formatting
    4250
    43    [ ] generic elements
    44 
    45    [ ] libsingular elements
    46    [ ] flint elements
    47 
    4851   [ ] rewrite base class "def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0):"
    4952
    50    [ ] make default implementation computation be centralized?
     53   [ ] make default implementation computation be centralized somehow??
    5154
    5255   [ ] fix unpickling of old nf elts
    5356
    54    [ ] fix order.py -- it explicitly references ntl but must not.
    5557   [ ] change number_field_element_quadratic to derive from
    5658       number_field_element code (i.e., the abstract base), instead of
    5759       deriving from number_field_element_ntl.
     60
    5861   [ ] write generic ver    def _lift_cyclotomic_element(self, new_parent, bint check=True, int rel=0):
    5962       of this in number_field_element.pyx
     63
    6064   [ ] make sure the _cmp_c_impl's are compatible across number field element implementations.
     65
    6166   [ ] format all documentation perfectly
     67
    6268   [ ] make the implementation part of elements into a cython class hierarchy with
    6369       [ ] implementation object needs to get pickled with number field -- test
    6470       [ ] flint implementation object
    6571       [ ] libsingular implementation object
     72
    6673   [ ] benchmark *every single operation* with each type of elements... for sanity
    6774   [ ] benchmark for comparison with magma
     75
    6876   [ ] get doctest coverage to 100% for the number_field directory
     77
    6978   [ ] arithmetic/automatic coercions between isomorphic fields, where
    7079       the only difference is the underlying implementation of
    7180       elements.
     81
    7282   [ ] other stuff in the library outside the rings directory:
    7383       [ ] come up with a Cython api for digging into internals of any
    7484           kind of number field element, which is good enough to deal
    7585           with the following:
    7686       [ ] quaternion algebra elements -- deal with that they only work for ntl number field elements
    7787       [ ] matrix_cyclo_dense.pyx
     88
    7889   [ ] write a function that can be included in doctests that
    7990       guarantees at least a certain amount of speed.  add this to
    8091       library so that nobody can frack my shizzle up.
     92
    8193   [ ] add proper headers
    8294   [ ] add overview docs to each file
    8395   [ ] overview of everything
     
    8597   [ ] rebase 2 -- make sure my fast mod-p reduction works.
    8698   [ ] get refereed
    8799   [ ] check through todo
    88    [ ] cacheing in number_field_element.pxd seems excessive
     100   [ ] caching in number_field_element.pxd seems excessive
    89101   [ ] suspicious bound:
    90102     "   D = (Dpoly.numer() * Dpoly.denom()).squarefree_part(bound=10000) "
    91103
     104OTHER:
     105
    92106[ ] optimize -- creation of the order generated by elements, especially in relative case (use singular?)
    93107[ ] plug in sebastian's code for QQ['x']?
    94108[ ] Organize a similar refactoring for function fields.