Ticket #9359: trac_9359-fixed.patch

File trac_9359-fixed.patch, 97.8 KB (added by David Loeffler, 12 years ago)

Qfolded patch with better commit string. Apply only this patch.

  • doc/en/reference/number_fields.rst

    # HG changeset patch
    # User David Loeffler <d.loeffler.01@cantab.net>
    # Date 1277757057 -3600
    # Node ID ae11a4bd7bec1c4f77bd1e7cf64fde8745d9ba36
    # Parent  201d3b2a6ae982ade2a0a548c7979c5950ccb1fa
    #9359: finish doctesting number_fields and get rid of totallyreal_dsage
    
    diff -r 201d3b2a6ae9 -r ae11a4bd7bec doc/en/reference/number_fields.rst
    a b  
    44.. toctree::
    55   :maxdepth: 2
    66
     7   sage/rings/number_field/number_field_base
    78   sage/rings/number_field/number_field
    89   sage/rings/number_field/number_field_rel
    910   sage/rings/number_field/number_field_element
     
    1819   sage/rings/number_field/galois_group
    1920   sage/rings/number_field/unit_group
    2021   sage/rings/number_field/small_primes_of_degree_one
     22   sage/rings/number_field/totallyreal
     23   sage/rings/number_field/totallyreal_rel
    2124   sage/rings/qqbar
  • sage/rings/number_field/all.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/all.py
    a b  
    1515
    1616from totallyreal import enumerate_totallyreal_fields_prim
    1717from totallyreal_data import hermite_constant
    18 from totallyreal_dsage import totallyreal_dsage
    1918from totallyreal_rel import enumerate_totallyreal_fields_all, enumerate_totallyreal_fields_rel
    2019
    2120from unit_group import UnitGroup
  • sage/rings/number_field/number_field_base.pyx

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_base.pyx
    a b  
    22Base class for all number fields.
    33
    44
    5 TESTS:
     5TESTS::
     6
    67    sage: k = NumberField(x^2 + 1, 'i'); k == loads(dumps(k))
    78    True
    89"""
     
    1112    """
    1213    Return True if x is of number field type.
    1314
    14     EXAMPLES:
     15    EXAMPLES::
     16
    1517        sage: from sage.rings.number_field.number_field_base import is_NumberField
    1618        sage: is_NumberField(NumberField(x^2+1,'a'))
    1719        True
     
    2022        sage: is_NumberField(CyclotomicField(97))
    2123        True
    2224
    23     Note that the rational numbers QQ are a number field.
     25    Note that the rational numbers QQ are a number field.::
     26
    2427        sage: is_NumberField(QQ)
    2528        True
    2629        sage: is_NumberField(ZZ)
     
    3437
    3538    def ring_of_integers(self, *args, **kwds):
    3639        r"""
    37         Synomym for \code{self.maximal_order(...)}.
     40        Synomym for ``self.maximal_order(...)``.
    3841
    39         EXAMPLES:
     42        EXAMPLES::
     43
    4044            sage: K.<a> = NumberField(x^2 + 1)
    4145            sage: K.ring_of_integers()
    4246            Maximal Order in Number Field in a with defining polynomial x^2 + 1
     
    4549
    4650    def OK(self, *args, **kwds):
    4751        r"""
    48         Synomym for \code{self.maximal_order(...)}.
     52        Synomym for ``self.maximal_order(...)``.
    4953
    50         EXAMPLES:
     54        EXAMPLES::
     55
    5156            sage: NumberField(x^3 - 2,'a').OK()
    5257            Maximal Order in Number Field in a with defining polynomial x^3 - 2
    5358        """
     
    5863        Return the maximal order, i.e., the ring of integers of this
    5964        number field.
    6065
    61         EXAMPLES:
     66        EXAMPLES::
     67
    6268            sage: NumberField(x^3 - 2,'b').maximal_order()
    6369            Maximal Order in Number Field in b with defining polynomial x^3 - 2
    6470        """
     
    6874        """
    6975        Return False since number fields are not finite.
    7076       
     77        EXAMPLES::
     78
    7179            sage: z = polygen(QQ)
    7280            sage: K.<theta, beta> = NumberField([z^3 - 3, z^2 + 1])
    7381            sage: K.is_finite()
     
    7785        """
    7886        return False
    7987       
    80 
    8188    def is_absolute(self):
    8289        """
    8390        Return True if self is viewed as a single extension over Q.
    8491       
    85         EXAMPLES:
     92        EXAMPLES::
     93
    8694            sage: K.<a> = NumberField(x^3+2)
    8795            sage: K.is_absolute()
    8896            True
     
    93101            sage: QQ.is_absolute()
    94102            True
    95103        """
    96         return False
     104        raise NotImplementedError
    97105
    98106    def signature(self):
    99107        """
    100108        Return (r1, r2), where r1 and r2 are the number of real embeddings
    101109        and pairs of complex embeddings of this field, respectively.
     110
     111        EXAMPLES::
     112
     113            sage: NumberField(x^3 - 2, 'a').signature()
     114            (1, 1)
    102115        """
    103116        raise NotImplementedError
    104117
    105118    def degree(self):
    106119        """
    107120        Return the degree of this number field.
     121
     122        EXAMPLES::
     123
     124            sage: NumberField(x^3 + 9, 'a').degree()
     125            3
    108126        """
    109127        raise NotImplementedError
    110128
    111129    def discriminant(self):
    112130        """
    113131        Return the discriminant of this number field.
     132
     133        EXAMPLES::
     134
     135            sage: NumberField(x^3 + 9, 'a').discriminant()
     136            -243
    114137        """
    115138        raise NotImplementedError
    116139
     
    121144        modulo principal fractional ideals to an integral ideal of
    122145        norm at most B.
    123146
    124         See also: self.bach_bound()
     147        .. seealso::
     148       
     149            :meth:`~bach_bound`
    125150
    126151        OUTPUT:
    127             symbolic expression or Rational
     152
     153        symbolic expression or Rational
    128154
    129155        EXAMPLES:
    130         The Minkowski bound for $\QQ[i]$ tells us that the class
    131         number is 1:
     156
     157        The Minkowski bound for `\QQ[i]` tells us that the class
     158        number is 1::
     159
    132160            sage: K = QQ[I]
    133161            sage: B = K.minkowski_bound(); B
    134162            4/pi
    135163            sage: B.n()
    136164            1.27323954473516
    137165
    138         We compute the Minkowski bound for $\QQ[\sqrt[3]{2}]$:
     166        We compute the Minkowski bound for `\QQ[\sqrt[3]{2}]`::
     167
    139168            sage: K = QQ[2^(1/3)]
    140169            sage: B = K.minkowski_bound(); B
    141170            16/3*sqrt(3)/pi
     
    144173            sage: int(B)
    145174            2
    146175
    147         We compute the Minkowski bound for $\QQ[\sqrt{10}]$, which
    148         has class number $2$:
     176        We compute the Minkowski bound for `\QQ[\sqrt{10}]`, which has class
     177        number 2::
     178
    149179            sage: K = QQ[sqrt(10)]
    150180            sage: B = K.minkowski_bound(); B
    151181            sqrt(10)
     
    154184            sage: K.class_number()
    155185            2
    156186
    157         The bound of course also works for the rational numbers:
     187        The bound of course also works for the rational numbers::
     188
    158189            sage: QQ.minkowski_bound()
    159190            1
    160191        """
     
    174205        that every integral ideal is equivalent modulo principal
    175206        fractional ideals to an integral ideal of norm at most B.
    176207
    177         See also: self.minkowski_bound()
     208        .. seealso::
     209       
     210            :meth:`~minkowski_bound`
    178211
    179212        OUTPUT:
    180             symbolic expression or the Integer 1
     213
     214        symbolic expression or the Integer 1
    181215
    182216        EXAMPLES:
     217       
    183218        We compute both the Minkowski and Bach bounds for a quadratic
    184         field, where the Minkowski bound is much better:
     219        field, where the Minkowski bound is much better::
     220
    185221            sage: K = QQ[sqrt(5)]
    186222            sage: K.minkowski_bound()
    187223            1/2*sqrt(5)
     
    193229            31.0834847277628
    194230           
    195231        We compute both the Minkowski and Bach bounds for a bigger
    196         degree field, where the Bach bound is much better:
     232        degree field, where the Bach bound is much better::
     233
    197234            sage: K = CyclotomicField(37)
    198235            sage: K.minkowski_bound().n()
    199236            7.50857335698544e14
  • sage/rings/number_field/number_field_element.pxd

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_element.pxd
    a b  
    2929    cdef void _ntl_coeff_as_mpz(self, mpz_t* z, long i)
    3030    cdef void _ntl_denom_as_mpz(self, mpz_t* z)
    3131
    32     # _parent_poly_c_ is deprecated -- refer to doc-string
    33     cdef void _parent_poly_c_(self, ZZX_c *num, ZZ_c *den)
    3432    cdef void _invert_c_(self, ZZX_c *num, ZZ_c *den)
    3533    cdef void _reduce_c_(self)
    3634    cpdef ModuleElement _add_(self, ModuleElement right)
  • sage/rings/number_field/number_field_element.pyx

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_element.pyx
    a b  
    1717
    1818"""
    1919
    20 # TODO -- relative extensions need to be completely rewritten, so one
    21 # can get easy access to representation of elements in their relative
    22 # form.  Functions like matrix below can't be done until relative
    23 # extensions are re-written this way.  Also there needs to be class
    24 # hierarchy for number field elements, integers, etc.  This is a
    25 # nontrivial project, and it needs somebody to attack it.  I'm amazed
    26 # how long this has gone unattacked.
    27 
    28 # Relative elements need to be a derived class or something.  This is
    29 # terrible as it is now.
    30 
    3120#*****************************************************************************
    3221#       Copyright (C) 2004, 2007 William Stein <wstein@gmail.com>
    3322#
     
    10493
    10594def __create__NumberFieldElement_version0(parent, poly):
    10695    """
     96    Used in unpickling elements of number fields pickled under very old Sage versions.
     97   
     98    EXAMPLE::
     99   
     100        sage: k.<a> = NumberField(x^3 - 2)
     101        sage: R.<z> = QQ[]
     102        sage: sage.rings.number_field.number_field_element.__create__NumberFieldElement_version0(k, z^2 + z + 1)
     103        a^2 + a + 1
     104    """
     105    return NumberFieldElement(parent, poly)
     106
     107def __create__NumberFieldElement_version1(parent, cls, poly):
     108    """
    107109    Used in unpickling elements of number fields.
    108110   
    109111    EXAMPLES:
     
    113115    ::
    114116   
    115117        sage: k.<a> = NumberField(x^3 - 2)
    116         sage: loads(dumps(a+1)) == a + 1
    117         True
    118     """
    119     return NumberFieldElement(parent, poly)
    120 
    121 def __create__NumberFieldElement_version1(parent, cls, poly):
    122     """
    123     Used in unpickling elements of number fields.
    124    
    125     EXAMPLES:
    126 
    127     Since this is just used in unpickling, we unpickle.
    128    
    129     ::
    130    
    131         sage: k.<a> = NumberField(x^3 - 2)
    132         sage: loads(dumps(a+1)) == a + 1
     118        sage: loads(dumps(a+1)) == a + 1 # indirect doctest
    133119        True
    134120
    135121    This also gets called for unpickling order elements; we check that #6462 is
    136122    fixed::
    137123
    138124        sage: L = NumberField(x^3 - x - 1,'a'); OL = L.maximal_order(); w = OL.0
    139         sage: loads(dumps(w)) == w
     125        sage: loads(dumps(w)) == w # indirect doctest
    140126        True
    141127    """
    142128    return cls(parent, poly)
     
    202188        return x
    203189
    204190    cdef number_field(self):
     191        r"""
     192       
     193        Return the number field of self. Only accessible from Cython.
     194        EXAMPLE::
     195       
     196            sage: K.<a> = NumberField(x^3 + 3)
     197            sage: a._number_field() # indirect doctest
     198            Number Field in a with defining polynomial x^3 + 3
     199        """
    205200        return self._parent
    206201
    207202    def _number_field(self):
     203        r"""
     204        EXAMPLE::
     205       
     206            sage: K.<a> = NumberField(x^3 + 3)
     207            sage: a._number_field()
     208            Number Field in a with defining polynomial x^3 + 3
     209        """
    208210        return self.number_field()
    209211
    210212    def __init__(self, parent, f):
     
    324326            ZZX_SetCoeff( self.__numerator, i, coeff )
    325327
    326328    def __cinit__(self):
     329        r"""
     330        Initialise C variables.
     331       
     332        EXAMPLE::
     333       
     334            sage: K.<b> = NumberField(x^3 - 2)
     335            sage: b = K.gen(); b # indirect doctest
     336            b
     337        """   
    327338        ZZX_construct(&self.__numerator)
    328339        ZZ_construct(&self.__denominator)
    329340
     
    412423        """
    413424        Used in pickling number field elements.
    414425       
     426        Note for developers: If this is changed, please also change the doctests of __create__NumberFieldElement_version1.
     427       
    415428        EXAMPLES::
    416429       
    417430            sage: k.<a> = NumberField(x^3 - 17*x^2 + 1)
     
    423436        return __create__NumberFieldElement_version1, \
    424437               (self.parent(), type(self), self.polynomial())
    425438
    426     def __repr__(self):
     439    def _repr_(self):
    427440        """
    428441        String representation of this number field element, which is just a
    429442        polynomial in the generator.
     
    432445       
    433446            sage: k.<a> = NumberField(x^2 + 2)
    434447            sage: b = (2/3)*a + 3/5
    435             sage: b.__repr__()
     448            sage: b._repr_()
    436449            '2/3*a + 3/5'
    437450        """
    438451        x = self.polynomial()
     
    469482        EXAMPLES::
    470483       
    471484            sage: C,zeta12=CyclotomicField(12).objgen()
    472             sage: latex(zeta12^4-zeta12)
     485            sage: latex(zeta12^4-zeta12) # indirect doctest
    473486            \zeta_{12}^{2} - \zeta_{12} - 1
    474487        """
    475488        return self.polynomial()._latex_(name=self.number_field().latex_variable_name())
     
    489502            sage: gap(p._gap_init_())
    490503            zeta8^2+2*zeta8-3
    491504        """
    492         s = self.__repr__()
     505        s = self._repr_()
    493506        return s.replace(str(self.parent().gen()), 'GeneratorsOfField(%s)[1]'%sage.interfaces.gap.gap(self.parent()).name())
    494507
    495508
    496509    def _pari_(self, var='x'):
     510        r"""
     511        Convert self to a Pari element.
     512       
     513        EXAMPLE::
     514       
     515            sage: K.<a> = NumberField(x^3 + 2)
     516            sage: (a + 2)._pari_()
     517            Mod(x + 2, x^3 + 2)
     518            sage: L.<b> = K.extension(x^2 + 2)
     519            sage: (b + a)._pari_()
     520            Mod(24/101*x^5 - 9/101*x^4 + 160/101*x^3 - 156/101*x^2 + 397/101*x + 364/101, x^6 + 6*x^4 - 4*x^3 + 12*x^2 + 24*x + 12)
     521        """
    497522        raise NotImplementedError, "NumberFieldElement sub-classes must override _pari_"
    498523
    499524    def _pari_init_(self, var='x'):
     
    537562            Mod(-8/27*x^3 + 2/3*x^2 - 1/2*x + 1/8, x^5 - x - 1)
    538563        """
    539564        return repr(self._pari_(var=var))
    540 ##         if var == None:
    541 ##             var = self.parent().variable_name()
    542 ##         if isinstance(self.parent(), sage.rings.number_field.number_field.NumberField_relative):
    543 ##             f = self.polynomial()._pari_()
    544 ##             g = str(self.parent().pari_relative_polynomial())
    545 ##             base = self.parent().base_ring()
    546 ##             gsub = base.gen()._pari_()
    547 ##             gsub = str(gsub).replace(base.variable_name(), "y")
    548 ##             g = g.replace("y", gsub)
    549 ##         else:
    550 ##             f = str(self.polynomial()).replace("x",var)
    551 ##             g = str(self.parent().polynomial()).replace("x",var)
    552 ##         return 'Mod(%s, %s)'%(f,g)
    553565
    554566    def __getitem__(self, n):
    555567        """
     
    594606        return self.polynomial()[n]
    595607
    596608    def __richcmp__(left, right, int op):
     609        r"""
     610        EXAMPLE::
     611       
     612            sage: K.<a> = NumberField(x^3 - 3*x + 8)
     613            sage: a  + 1 > a # indirect doctest
     614            True
     615            sage: a + 1 < a # indirect doctest
     616            False
     617        """
    597618        return (<Element>left)._richcmp(right, op)
    598619
    599620    cdef int _cmp_c_impl(left, sage.structure.element.Element right) except -2:
     
    812833
    813834    def coordinates_in_terms_of_powers(self):
    814835        r"""
    815         Let `\alpha` be self. Return a Python function that takes
    816         any element of the parent of self in `\QQ(\alpha)`
    817         and writes it in terms of the powers of `\alpha`:
    818         `1, \alpha, \alpha^2, ...`.
     836        Let `\alpha` be self. Return a callable object (of type
     837        :class:`~CoordinateFunction`) that takes any element of the
     838        parent of self in `\QQ(\alpha)` and writes it in terms of the
     839        powers of `\alpha`: `1, \alpha, \alpha^2, ...`.
    819840       
    820841        (NOT CACHED).
    821842       
     
    862883        V, from_V, to_V = K.absolute_vector_space()
    863884        h = K(1)
    864885        B = [to_V(h)]
    865         f = self.minpoly()
     886        f = self.absolute_minpoly()
    866887        for i in range(f.degree()-1):
    867888            h *= self
    868889            B.append(to_V(h))
     
    12581279        self.__denominator = t1
    12591280
    12601281    cpdef ModuleElement _add_(self, ModuleElement right):
     1282        r"""
     1283        EXAMPLE::
     1284       
     1285            sage: K.<s> = QuadraticField(2)
     1286            sage: s + s # indirect doctest
     1287            2*s
     1288            sage: s + ZZ(3) # indirect doctest
     1289            s + 3
     1290        """
    12611291        cdef NumberFieldElement x
    12621292        cdef NumberFieldElement _right = right
    12631293        x = self._new()
     
    12701300        return x
    12711301
    12721302    cpdef ModuleElement _sub_(self, ModuleElement right):
     1303        r"""
     1304        EXAMPLES::
     1305       
     1306            sage: K.<a> = NumberField(x^3 + 2)
     1307            sage: (a/2) - (a + 3) # indirect doctest
     1308            -1/2*a - 3
     1309        """
    12731310        cdef NumberFieldElement x
    12741311        cdef NumberFieldElement _right = right
    12751312        x = self._new()
     
    12921329            sage: zeta12*zeta12^11
    12931330            1
    12941331            sage: G.<a> = NumberField(x^3 + 2/3*x + 1)
    1295             sage: a^3
     1332            sage: a^3 # indirect doctest
    12961333            -2/3*a - 1
    1297             sage: a^3+a
     1334            sage: a^3+a # indirect doctest
    12981335            1/3*a - 1
    12991336        """
    13001337        cdef NumberFieldElement x
     
    13381375        EXAMPLES::
    13391376       
    13401377            sage: C.<I>=CyclotomicField(4)
    1341             sage: 1/I
     1378            sage: 1/I # indirect doctest
    13421379            -I
    1343             sage: I/0
     1380            sage: I/0 # indirect doctest
    13441381            Traceback (most recent call last):
    13451382            ...
    13461383            ZeroDivisionError: rational division by zero
     
    13481385        ::
    13491386       
    13501387            sage: G.<a> = NumberField(x^3 + 2/3*x + 1)
    1351             sage: a/a
    1352             1
    1353             sage: 1/a
     1388            sage: a/a # indirect doctest
     1389            1
     1390            sage: 1/a # indirect doctest
    13541391            -a^2 - 2/3
    1355             sage: a/0
     1392            sage: a/0 # indirect doctest
    13561393            Traceback (most recent call last):
    13571394            ...
    13581395            ZeroDivisionError: Number field element division by zero
     
    14241461        return not IsZero_ZZX(self.__numerator)
    14251462
    14261463    cpdef ModuleElement _neg_(self):
     1464        r"""
     1465        EXAMPLE::
     1466       
     1467            sage: K.<a> = NumberField(x^3 + 2)
     1468            sage: -a # indirect doctest
     1469            -a
     1470        """
    14271471        cdef NumberFieldElement x
    14281472        x = self._new()
    14291473        ZZX_mul_long(x.__numerator, self.__numerator, -1)
     
    14311475        return x
    14321476
    14331477    def __copy__(self):
     1478        r"""
     1479        EXAMPLE::
     1480       
     1481            sage: K.<a> = NumberField(x^3 + 2)
     1482            sage: b = copy(a)
     1483            sage: b == a
     1484            True
     1485            sage: b is a
     1486            False
     1487        """
    14341488        cdef NumberFieldElement x
    14351489        x = self._new()
    14361490        x.__numerator = self.__numerator
     
    14961550        """
    14971551        return long(self.polynomial())
    14981552
    1499     cdef void _parent_poly_c_(self, ZZX_c *num, ZZ_c *den):
    1500         """
    1501         I believe this function should be removed since I've put the
    1502         pointer __fld_numerator and __fld_denominator in the element
    1503         class. I'm not going to remove it quite yet, but feel free to
    1504         remove it if you agree with me that it should go.
    1505         """
    1506         raise NotImplementedError, "NumberFieldElement subclasses must override _parent_poly_c_()"
    1507 
    15081553    cdef void _invert_c_(self, ZZX_c *num, ZZ_c *den):
    15091554        """
    15101555        Computes the numerator and denominator of the multiplicative
     
    15481593        self._invert_c_(&x.__numerator, &x.__denominator)
    15491594        x._reduce_c_()
    15501595        return x
    1551 #        K = self.parent()
    1552 #        quotient = K(1)._pari_('x') / self._pari_('x')
    1553 #        if isinstance(K, sage.rings.number_field.number_field.NumberField_relative):
    1554 #            return K(K.pari_rnf().rnfeltreltoabs(quotient))
    1555 #        else:
    1556 #            return K(quotient)
    15571596
    15581597    def _integer_(self, Z=None):
    15591598        """
     
    16041643        EXAMPLES::
    16051644       
    16061645            sage: K.<a> = QuadraticField(2)
    1607             sage: SR(a)
     1646            sage: SR(a) # indirect doctest
    16081647            sqrt(2)
    1609             sage: SR(3*a-5)
     1648            sage: SR(3*a-5) # indirect doctest
    16101649            3*sqrt(2) - 5
    16111650            sage: K.<a> = QuadraticField(2, embedding=-1.4)
    1612             sage: SR(a)
     1651            sage: SR(a) # indirect doctest
    16131652            -sqrt(2)
    16141653            sage: K.<a> = NumberField(x^2 - 2)
    1615             sage: SR(a)
     1654            sage: SR(a) # indirect doctest
    16161655            Traceback (most recent call last):
    16171656            ...
    16181657            TypeError: An embedding into RR or CC must be specified.
     
    16201659        Now a more complicated example::
    16211660       
    16221661            sage: K.<a> = NumberField(x^3 + x - 1, embedding=0.68)
    1623             sage: b = SR(a); b
     1662            sage: b = SR(a); b # indirect doctest
    16241663            1/3*(3*(1/18*sqrt(3)*sqrt(31) + 1/2)^(2/3) - 1)/(1/18*sqrt(3)*sqrt(31) + 1/2)^(1/3)
    16251664
    16261665            sage: (b^3 + b - 1).simplify_radical()
     
    16361675        Special case for cyclotomic fields::
    16371676       
    16381677            sage: K.<zeta> = CyclotomicField(19)
    1639             sage: SR(zeta)
     1678            sage: SR(zeta) # indirect doctest
    16401679            e^(2/19*I*pi)
    16411680            sage: CC(zeta)
    16421681            0.945817241700635 + 0.324699469204683*I
     
    18391878        """
    18401879        Return hash of this number field element, which is just the
    18411880        hash of the underlying polynomial.
     1881       
     1882        EXAMPLE::
     1883       
     1884            sage: K.<b> = NumberField(x^3 - 2)
     1885            sage: hash(b^2 + 1) == hash((b^2 + 1).polynomial()) # indirect doctest
     1886            True
    18421887        """
    18431888        return hash(self.polynomial())
    18441889
     
    18531898          element written in terms of a generator.
    18541899       
    18551900        EXAMPLES:
     1901       
     1902            sage: K.<b> = NumberField(x^3 - 2)
     1903            sage: (b^2 + 1)._coefficients()
     1904            [1, 0, 1]
    18561905        """
    18571906        coeffs = []
    18581907        cdef Integer den = (<IntegerRing_class>ZZ)._coerce_ZZ(&self.__denominator)
     
    21382187        return self.number_field().relative_vector_space()[2](self)
    21392188
    21402189    def charpoly(self, var='x'):
     2190        r"""
     2191        Return the characteristic polynomial of this number field element.
     2192       
     2193        EXAMPLE::
     2194       
     2195            sage: K.<a> = NumberField(x^3 + 7)
     2196            sage: a.charpoly()
     2197            x^3 + 7
     2198            sage: K(1).charpoly()
     2199            x^3 - 3*x^2 + 3*x - 1
     2200        """
    21412201        raise NotImplementedError, "Subclasses of NumberFieldElement must override charpoly()"
    21422202
    21432203    def minpoly(self, var='x'):
     
    26022662           A ValueError will be raised if this function is called on
    26032663           0.
    26042664
    2605         .. note::
    2606 
    2607            See also ``denominator_ideal()``
     2665        .. seealso::
     2666
     2667           :meth:`~denominator_ideal`
    26082668       
    26092669        OUTPUT:
    26102670
     
    26492709           A ValueError will be raised if this function is called on
    26502710           0.
    26512711
    2652         .. note::
    2653 
    2654            See also ``numerator_ideal()``
     2712        .. seealso::
     2713
     2714           :meth:`~numerator_ideal`
    26552715       
    26562716        OUTPUT:
    26572717
     
    28012861        """
    28022862        Return the list of coefficients of self written in terms of a power
    28032863        basis.
    2804         """
    2805         # Power basis list is total nonsense, unless the parent of self is an
    2806         # absolute extension.
     2864       
     2865        EXAMPLE::
     2866       
     2867            sage: K.<a> = NumberField(x^3 - x + 2); ((a + 1)/(a + 2)).list()
     2868            [1/4, 1/2, -1/4]
     2869            sage: K.<a, b> = NumberField([x^3 - x + 2, x^2 + 23]); ((a + b)/(a + 2)).list()
     2870            [3/4*b - 1/2, -1/2*b + 1, 1/4*b - 1/2]
     2871        """
    28072872        raise NotImplementedError
    28082873       
    28092874    def inverse_mod(self, I):
     
    29483013        K = magma(self.parent())
    29493014        return '(%s!%s)'%(K.name(), self.list())
    29503015       
    2951     cdef void _parent_poly_c_(self, ZZX_c *num, ZZ_c *den):
    2952         """
    2953         I believe this function should be removed since I've put the
    2954         pointer __fld_numerator and __fld_denominator in the element
    2955         class. I'm not going to remove it quite yet, but feel free to
    2956         remove it if you agree with me that it should go.
    2957         """
    2958         cdef ntl_ZZX _num
    2959         cdef ntl_ZZ _den
    2960         _num, _den = self.number_field().polynomial_ntl()
    2961         num[0] = _num.x
    2962         den[0] = _den.x
    2963 
    29643016    def absolute_charpoly(self, var='x', algorithm=None):
    29653017        r"""
    2966         Return the characteristic polynomial of this element over
    2967 
    2968         For the meaning of the optional argument algorithm, see :meth:`charpoly`.
     3018        Return the characteristic polynomial of this element over `\QQ`.
     3019
     3020        For the meaning of the optional argument ``algorithm``, see :meth:`charpoly`.
    29693021
    29703022        EXAMPLES::
    29713023       
     
    31333185        lives in QQ[x]/(f(x)).
    31343186       
    31353187        EXAMPLES::
     3188       
    31363189            sage: K.<a> = QuadraticField(-3)
    31373190            sage: a.lift()
    31383191            x
     
    32043257    should happen in the parent.
    32053258    """
    32063259    def __init__(self, parent, f):
     3260        r"""
     3261        EXAMPLE::
     3262       
     3263            sage: L.<a, b> = NumberField([x^2 + 1, x^2 + 2])
     3264            sage: type(a) # indirect doctest
     3265            <type 'sage.rings.number_field.number_field_element.NumberFieldElement_relative'>
     3266        """
    32073267        NumberFieldElement.__init__(self, parent, f)
    32083268
    32093269    def __getitem__(self, n):
     
    32673327        lives in the relative number field K[x]/(f(x)).
    32683328       
    32693329        EXAMPLES::
     3330       
    32703331            sage: K.<a> = QuadraticField(-3)
    32713332            sage: x = polygen(K)
    32723333            sage: L.<b> = K.extension(x^7 + 5)
     
    33503411        self.__pari[var] = h
    33513412        return h
    33523413
    3353     cdef void _parent_poly_c_(self, ZZX_c *num, ZZ_c *den):
    3354         """
    3355         I believe this function should be removed since I've put the
    3356         pointer __fld_numerator and __fld_denominator in the element
    3357         class. I'm not going to remove it quite yet, but feel free to
    3358         remove it if you agree with me that it should go.
    3359         """
    3360         f = self.number_field().absolute_polynomial()
    3361         _ntl_poly(f, num, den)
    3362 
    3363     def __repr__(self):
     3414    def _repr_(self):
     3415        r"""
     3416        EXAMPLE::
     3417       
     3418            sage: L.<a, b> = NumberField([x^3 - x + 1, x^2 + 23])
     3419            sage: repr(a^4*b) # indirect doctest
     3420            'b*a^2 - b*a'
     3421        """
    33643422        K = self.number_field()
    33653423        # Compute representation of self in terms of relative vector space.
    33663424        R = K.base_field()[K.variable_name()]
     
    33753433            sage: C.<zeta> = CyclotomicField(12)
    33763434            sage: PC.<x> = PolynomialRing(C)
    33773435            sage: K.<alpha> = NumberField(x^2 - 7)
    3378             sage: latex((alpha + zeta)^4)
     3436            sage: latex((alpha + zeta)^4) # indirect doctest
    33793437            \left(4 \zeta_{12}^{3} + 28 \zeta_{12}\right) \alpha + 43 \zeta_{12}^{2} + 48
    33803438            sage: PK.<y> = PolynomialRing(K)
    33813439            sage: L.<beta> = NumberField(y^3 + y + alpha)
    3382             sage: latex((beta + zeta)^3)
     3440            sage: latex((beta + zeta)^3) # indirect doctest
    33833441            3 \zeta_{12} \beta^{2} + \left(3 \zeta_{12}^{2} - 1\right) \beta - \alpha + \zeta_{12}^{3}
    33843442        """
    33853443        K = self.number_field()
     
    34803538        r"""
    34813539        Return the minimal polynomial over `\QQ` of this element.
    34823540
    3483         For the meaning of the optional argument algorithm, see :meth:`absolute_charpoly`.
     3541        For the meaning of the optional argument ``algorithm``, see :meth:`absolute_charpoly`.
    34843542       
    34853543        EXAMPLES::
    34863544       
     
    35483606        Univariate Polynomial Ring in x over Integer Ring
    35493607    """
    35503608    def __init__(self, order, f):
     3609        r"""
     3610        EXAMPLE::
     3611       
     3612            sage: K.<a> = NumberField(x^3 + 2)
     3613            sage: O2 = K.order(2*a)
     3614            sage: type(O2.1) # indirect doctest
     3615            <type 'sage.rings.number_field.number_field_element.OrderElement_absolute'>
     3616        """
    35513617        K = order.number_field()
    35523618        NumberFieldElement_absolute.__init__(self, K, f)
    35533619        self._number_field = K
     
    35753641        return x
    35763642
    35773643    cdef number_field(self):
     3644        r"""
     3645        Return the number field of self. Only accessible from Cython.
     3646       
     3647        EXAMPLE::
     3648           
     3649            sage: K = NumberField(x^3 - 17, 'a')
     3650            sage: OK = K.ring_of_integers()
     3651            sage: a = OK(K.gen())
     3652            sage: a._number_field() is K # indirect doctest
     3653            True
     3654        """
    35783655        return self._number_field
    35793656
    35803657    cpdef RingElement _div_(self, RingElement other):
     
    35893666            sage: K = NumberField(x^3 - 17, 'a')
    35903667            sage: OK = K.ring_of_integers()
    35913668            sage: a = OK(K.gen())
    3592             sage: (17/a) in OK
    3593             True
    3594             sage: (17/a).parent() is K
    3595             True
    3596             sage: (17/(2*a)).parent() is K
    3597             True
    3598             sage: (17/(2*a)) in OK
     3669            sage: (17/a) in OK # indirect doctest
     3670            True
     3671            sage: (17/a).parent() is K # indirect doctest
     3672            True
     3673            sage: (17/(2*a)).parent() is K # indirect doctest
     3674            True
     3675            sage: (17/(2*a)) in OK # indirect doctest
    35993676            False
    36003677        """     
    36013678        cdef NumberFieldElement_absolute x
     
    36653742        <type 'sage.rings.number_field.number_field_element.OrderElement_relative'>
    36663743    """
    36673744    def __init__(self, order, f):
     3745        r"""
     3746        EXAMPLE::
     3747       
     3748            sage: O = EquationOrder([x^2 + x + 1, x^3 - 2],'a,b')
     3749            sage: type(O.1) # indirect doctest
     3750            <type 'sage.rings.number_field.number_field_element.OrderElement_relative'>
     3751        """
    36683752        K = order.number_field()
    36693753        NumberFieldElement_relative.__init__(self, K, f)
    36703754        (<Element>self)._parent = order
     
    37113795            sage: OK2 = K2.order(K2.gen()) # (not maximal)
    37123796            sage: b = OK2.gens()[1]; b
    37133797            b
    3714             sage: (17/b).parent() is K2
    3715             True
    3716             sage: (17/b) in OK2 # not implemented (#4193)
    3717             True
    3718             sage: (17/b^7) in OK2
     3798            sage: (17/b).parent() is K2 # indirect doctest
     3799            True
     3800            sage: (17/b) in OK2 # indirect doctest
     3801            True
     3802            sage: (17/b^7) in OK2 # indirect doctest
    37193803            False
    37203804        """     
    37213805        cdef NumberFieldElement_relative x
     
    37393823            True
    37403824            sage: (~b).parent() is K2
    37413825            True
    3742             sage: (~b) in OK2 # not implemented (#4193)
    3743             False
    3744             sage: b**(-1) in OK2 # not implemented (#4193)
     3826            sage: (~b) in OK2 # indirect doctest
     3827            False
     3828            sage: b**(-1) in OK2 # indirect doctest
    37453829            False
    37463830        """
    37473831        return self._parent.number_field()(NumberFieldElement_relative.__invert__(self))
     
    38803964
    38813965
    38823966class CoordinateFunction:
     3967    r"""
     3968    This class provides a callable object which expresses
     3969    elements in terms of powers of a fixed field generator `\alpha`.
     3970   
     3971    EXAMPLE::
     3972   
     3973        sage: K.<a> = NumberField(x^2 + x + 3)
     3974        sage: f = (a + 1).coordinates_in_terms_of_powers(); f
     3975        Coordinate function that writes elements in terms of the powers of a + 1
     3976        sage: f.__class__
     3977        <class sage.rings.number_field.number_field_element.CoordinateFunction at ...>
     3978        sage: f(a)
     3979        [-1, 1]
     3980        sage: f == loads(dumps(f))
     3981        True
     3982    """
    38833983    def __init__(self, NumberFieldElement alpha, W, to_V):
     3984        r"""
     3985        EXAMPLE::
     3986       
     3987            sage: K.<a> = NumberField(x^2 + x + 3)
     3988            sage: f = (a + 1).coordinates_in_terms_of_powers(); f # indirect doctest
     3989            Coordinate function that writes elements in terms of the powers of a + 1
     3990        """
    38843991        self.__alpha = alpha
    38853992        self.__W = W
    38863993        self.__to_V = to_V
    38873994        self.__K = alpha.number_field()
    38883995
    38893996    def __repr__(self):
     3997        r"""
     3998        EXAMPLE::
     3999       
     4000            sage: K.<a> = NumberField(x^2 + x + 3)
     4001            sage: f = (a + 1).coordinates_in_terms_of_powers(); repr(f) # indirect doctest
     4002            'Coordinate function that writes elements in terms of the powers of a + 1'
     4003        """
    38904004        return "Coordinate function that writes elements in terms of the powers of %s"%self.__alpha
    38914005
    38924006    def alpha(self):
     4007        r"""
     4008        EXAMPLE::
     4009       
     4010            sage: K.<a> = NumberField(x^3 + 2)
     4011            sage: (a + 2).coordinates_in_terms_of_powers().alpha()
     4012            a + 2
     4013        """
    38934014        return self.__alpha
    38944015
    38954016    def __call__(self, x):
     4017        r"""
     4018        EXAMPLE::
     4019       
     4020            sage: K.<a> = NumberField(x^3 + 2)
     4021            sage: f = (a + 2).coordinates_in_terms_of_powers()
     4022            sage: f(1/a)
     4023            [-2, 2, -1/2]
     4024            sage: f(ZZ(2))
     4025            [2, 0, 0]
     4026            sage: L.<b> = K.extension(x^2 + 7)
     4027            sage: g = (a + b).coordinates_in_terms_of_powers()
     4028            sage: g(a/b)
     4029            [-3379/5461, -371/10922, -4125/38227, -15/5461, -14/5461, -9/76454]
     4030            sage: g(a)
     4031            [4459/10922, -4838/5461, -273/5461, -980/5461, -9/10922, -42/5461]
     4032            sage: f(b)
     4033            Traceback (most recent call last):
     4034            ...
     4035            TypeError: Cannot coerce element into this number field
     4036        """
    38964037        return self.__W.coordinates(self.__to_V(self.__K(x)))
    38974038   
     4039    def __cmp__(self, other):
     4040        r"""
     4041        EXAMPLE::
     4042       
     4043            sage: K.<a> = NumberField(x^4 + 1)
     4044            sage: f = (a + 1).coordinates_in_terms_of_powers()
     4045            sage: f == loads(dumps(f))
     4046            True
     4047            sage: f == (a + 2).coordinates_in_terms_of_powers()
     4048            False
     4049            sage: f == NumberField(x^2 + 3,'b').gen().coordinates_in_terms_of_powers()
     4050            False
     4051        """
     4052        return cmp(self.__class__, other.__class__) or cmp(self.__K, other.__K) or cmp(self.__alpha, other.__alpha)
    38984053
    38994054
    39004055
  • sage/rings/number_field/number_field_element_quadratic.pyx

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_element_quadratic.pyx
    a b  
    282282       
    283283
    284284    def __cinit__(self):
     285        r"""
     286        Initialisation function.
     287       
     288        EXAMPLE::
     289       
     290            sage: QuadraticField(-3, 'a').gen() # indirect doctest
     291            a
     292        """
    285293        mpz_init(self.a)
    286294        mpz_init(self.b)
    287295        mpz_init(self.denom)
     
    570578       
    571579    cpdef ModuleElement _add_(self, ModuleElement other_m):
    572580        """
    573         EXAMPLES:
     581        EXAMPLES::
     582       
    574583            sage: K.<a> = NumberField(x^2-5)
    575584            sage: K.discriminant()
    576585            5
     
    626635   
    627636    cpdef ModuleElement _sub_(self, ModuleElement other_m):
    628637        """
    629         EXAMPLES:
     638        EXAMPLES::
     639       
    630640            sage: K.<a> = NumberField(x^2-13)
    631641            sage: b = (a-3)/10; b # indirect doctest
    632642            1/10*a - 3/10
     
    889899        return hash(self.polynomial())
    890900
    891901    def __richcmp__(left, right, int op):
     902        r"""
     903        EXAMPLE::
     904       
     905            sage: K.<a> = NumberField(x^2+163)
     906            sage: K(1/2) < K(2/3) # indirect doctest
     907            False
     908            sage: K(1/2) > K(1/3) # indirect doctest
     909            True
     910        """
    892911        return (<Element>left)._richcmp(right, op)
    893912
    894913    cdef int _cmp_c_impl(self, Element _right) except -2:
  • sage/rings/number_field/number_field_ideal.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_ideal.py
    a b  
    26852685    Class to hold data needed by quotient maps from number field
    26862686    orders to residue fields.  These are only partial maps: the exact
    26872687    domain is the appropriate valuation ring.  For examples, see
    2688     residue_field().
     2688    :meth:`~sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal.residue_field`.
    26892689    """
    26902690    def __init__(self, K, M_OK_change, Q, I):
    26912691        """
    26922692        Initialize this QuotientMap.
     2693       
     2694        EXAMPLE::
     2695       
     2696            sage: K.<a> = NumberField(x^3 + 4)
     2697            sage: f = K.ideal(1 + a^2/2).residue_field().reduction_map(); f # indirect doctest
     2698            Partially defined reduction map:
     2699              From: Number Field in a with defining polynomial x^3 + 4
     2700              To:   Residue field of Fractional ideal (1/2*a^2 + 1)
     2701            sage: f.__class__
     2702            <type 'sage.rings.residue_field.ReductionMap'>
    26932703        """
    26942704        self.__M_OK_change = M_OK_change
    26952705        self.__Q = Q
     
    27022712        Apply this QuotientMap to an element of the number field.
    27032713
    27042714        INPUT:
     2715       
    27052716            x -- an element of the field
     2717           
     2718        EXAMPLE::
     2719       
     2720            sage: K.<a> = NumberField(x^3 + 4)
     2721            sage: f = K.ideal(1 + a^2/2).residue_field().reduction_map()
     2722            sage: f(a)
     2723            2
    27062724        """
    27072725        v = self.__to_L(x)
    27082726        w = v * self.__M_OK_change
     
    27112729    def __repr__(self):
    27122730        """
    27132731        Return a string representation of this QuotientMap.
     2732       
     2733        EXAMPLE::
     2734       
     2735            sage: K.<a> = NumberField(x^3 + 4)
     2736            sage: f = K.ideal(1 + a^2/2).residue_field().reduction_map()
     2737            sage: repr(f)
     2738            'Partially defined reduction map:\n  From: Number Field in a with defining polynomial x^3 + 4\n  To:   Residue field of Fractional ideal (1/2*a^2 + 1)'
    27142739        """
    27152740        return "Partially defined quotient map from %s to an explicit vector space representation for the quotient of the ring of integers by (p,I) for the ideal I=%s."%(self.__K, self.__I)
    27162741   
     
    27222747    def __init__(self, OK, M_OK_map, Q, I):
    27232748        """
    27242749        Initialize this LiftMap.
     2750       
     2751        EXAMPLE::
     2752       
     2753            sage: K.<a> = NumberField(x^3 + 4)
     2754            sage: I = K.ideal(1 + a^2/2)
     2755            sage: f = I.residue_field().lift_map()
     2756            sage: f.__class__
     2757            <type 'sage.rings.residue_field.LiftingMap'>
    27252758        """
    27262759        self.__I = I
    27272760        self.__OK = OK
     
    27312764    def __call__(self, x):
    27322765        """
    27332766        Apply this LiftMap to an element of the residue field.
     2767       
     2768        EXAMPLE::
     2769       
     2770            sage: K.<a> = NumberField(x^3 + 4)
     2771            sage: R = K.ideal(1 + a^2/2).residue_field()
     2772            sage: f = R.lift_map()
     2773            sage: f(R(a/17))
     2774            1
    27342775        """
    27352776        # This lifts to OK tensor F_p
    27362777        v = self.__Q.lift(x)
     
    27432784    def __repr__(self):
    27442785        """
    27452786        Return a string representation of this QuotientMap.
     2787       
     2788        EXAMPLE::
     2789       
     2790            sage: K.<a> = NumberField(x^3 + 4)
     2791            sage: R = K.ideal(1 + a^2/2).residue_field()
     2792            sage: repr(R.lift_map())
     2793            'Lifting map:\n  From: Residue field of Fractional ideal (1/2*a^2 + 1)\n  To:   Maximal Order in Number Field in a with defining polynomial x^3 + 4'
    27462794        """
    27472795        return "Lifting map to %s from quotient of integers by %s"%(self.__OK, self.__I)
    27482796
  • sage/rings/number_field/number_field_ideal_rel.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_ideal_rel.py
    a b  
    5656        sage: i = K.ideal(38); i
    5757        Fractional ideal (38)
    5858       
    59     .. warning::
    60 
    61        Ideals in relative number fields are broken::
    62 
    6359        sage: K.<a0, a1> = NumberField([x^2 + 1, x^2 + 2]); K
    6460        Number Field in a0 with defining polynomial x^2 + 1 over its base field
    6561        sage: i = K.ideal([a0+1]); i # random
     
    7066        True
    7167        sage: ((a0 + 1) / g).is_integral()
    7268        True
     69   
     70    TESTS: one test fails, because ideals aren't fully integrated into the categories framework yet::
     71   
     72        sage: TestSuite(i).run()
     73        Failure in _test_category:
     74        ...
     75        The following tests failed: _test_category
    7376    """
    7477    def __cmp__(self, other):
    7578        """
     
    97100
    98101            sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7])
    99102            sage: I = K.ideal(2, (a + 2*b + 3)/2)
    100             sage: [z in I for z in [a, b, 2, a + b]]
     103            sage: [z in I for z in [a, b, 2, a + b]] # indirect doctest
    101104            [False, False, True, True]
    102105        """
    103106        abs_ideal = self.absolute_ideal()
     
    107110    def pari_rhnf(self):
    108111        """
    109112        Return PARI's representation of this relative ideal in Hermite
    110         normal form.       
     113        normal form.
     114       
     115        EXAMPLE::
     116       
     117            sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7])
     118            sage: I = K.ideal(2, (a + 2*b + 3)/2)
     119            sage: I.pari_rhnf()
     120            [[1, -2; 0, 1], [[2, 1; 0, 1], [1/2, 0; 0, 1/2]]]
    111121        """
    112122        try:
    113123            return self.__pari_rhnf
     
    206216        return L.ideal(map(to_L, id.gens()))
    207217
    208218    def free_module(self):
     219        r"""
     220        Return this ideal as a `\ZZ`-submodule of the `\QQ`-vector
     221        space corresponding to the ambient number field.
     222       
     223        EXAMPLES::
     224       
     225            sage: K.<a, b> = NumberField([x^3 - x + 1, x^2 + 23])
     226            sage: I = K.ideal(a*b - 1)
     227            sage: I.free_module()
     228            Free module of degree 6 and rank 6 over Integer Ring
     229            User basis matrix:
     230            ...
     231            sage: I.free_module().is_submodule(K.maximal_order().free_module())
     232            True
     233
     234        """
    209235        return self.absolute_ideal().free_module()
    210236
    211237    def gens_reduced(self):
     238        r"""
     239        Return a small set of generators for this ideal. This will always
     240        return a single generator if one exists (i.e. if the ideal is
     241        principal), and otherwise two generators.
     242       
     243        EXAMPLE::
     244       
     245            sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
     246            sage: I = K.ideal((a + 1)*b/2 + 1)
     247            sage: I.gens_reduced()
     248            (1/2*b*a + 1/2*b + 1,)
     249        """
    212250        try:
    213251            ## Compute the single generator, if it exists           
    214252            dummy = self.is_principal()
     
    272310            return self.__is_principal
    273311
    274312    def is_zero(self):
     313        r"""
     314        Return True if this is the zero ideal.
     315       
     316        EXAMPLE::
     317       
     318            sage: K.<a, b> = NumberField([x^2 + 3, x^3 + 4])
     319            sage: K.ideal(17).is_zero()
     320            False
     321            sage: K.ideal(0).is_zero()
     322            True
     323        """
    275324        zero = self.number_field().pari_rnf().rnfidealhnf(0)
    276325        return self.pari_rhnf() == zero
    277326
     
    332381        The norm of a fractional ideal in a relative number field is deliberately
    333382        unimplemented, so that a user cannot mistake the absolute norm
    334383        for the relative norm, or vice versa.
     384       
     385        EXAMPLE::
     386       
     387            sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
     388            sage: K.ideal(2).norm()
     389            Traceback (most recent call last):
     390            ...
     391            NotImplementedError: For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate
    335392        """
    336393        raise NotImplementedError, "For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate"
    337394
     
    592649            sage: I = K.ideal(3, c)
    593650            sage: I.relative_ramification_index()
    594651            2
    595             sage: I.ideal_below()
    596             Fractional ideal (-b)  # 32-bit
    597             Fractional ideal (b)   # 64-bit
     652            sage: I.ideal_below()  # random sign
     653            Fractional ideal (b)
     654            sage: I.ideal_below() == K.ideal(b)
     655            True
    598656            sage: K.ideal(b) == I^2
    599657            True
    600658        """
     
    608666        r"""
    609667        For ideals in relative number fields, ``ramification_index``
    610668        is deliberately not implemented in order to avoid ambiguity.
    611         Either ``relative_ramification_index`` or
    612         ``absolute_ramification_index`` should be used instead.
     669        Either :meth:`~relative_ramification_index` or
     670        :meth:`~absolute_ramification_index` should be used instead.
     671       
     672        EXAMPLE::
     673       
     674            sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
     675            sage: K.ideal(2).ramification_index()
     676            Traceback (most recent call last):
     677            ...
     678            NotImplementedError: For an ideal in a relative number field you must use relative_ramification_index or absolute_ramification_index as appropriate
    613679        """
    614680        raise NotImplementedError, "For an ideal in a relative number field you must use relative_ramification_index or absolute_ramification_index as appropriate"
    615681
  • sage/rings/number_field/number_field_rel.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/number_field_rel.py
    a b  
    629629        The degree, unqualified, of a relative number field is deliberately
    630630        not implemented, so that a user cannot mistake the absolute degree
    631631        for the relative degree, or vice versa.
     632       
     633        EXAMPLE::
     634       
     635            sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
     636            sage: K.degree()
     637            Traceback (most recent call last):
     638            ...
     639            NotImplementedError: For a relative number field you must use relative_degree or absolute_degree as appropriate
    632640        """
    633641        raise NotImplementedError, "For a relative number field you must use relative_degree or absolute_degree as appropriate"
    634642
     
    685693        Return string representation of this relative number field.
    686694
    687695        The base field is not part of the string representation.  To
    688         find out what the base field is use ``self.base_field()``.
     696        find out what the base field is use :meth:`~base_field`.
    689697
    690698        EXAMPLES::
    691699
    692700            sage: k.<a, b> = NumberField([x^5 + 2, x^7 + 3])
    693             sage: k
    694             Number Field in a with defining polynomial x^5 + 2 over its base field
     701            sage: repr(k) # indirect doctest
     702            'Number Field in a with defining polynomial x^5 + 2 over its base field'
    695703            sage: k.base_field()
    696704            Number Field in b with defining polynomial x^7 + 3
    697705        """
    698706       
    699707        return "Number Field in %s with defining polynomial %s over its base field"%(self.variable_name(), self.relative_polynomial())
    700708       
    701         #return "Extension by %s of the Number Field in %s with defining polynomial %s"%(
    702         #self.polynomial(), self.base_field().variable_name(),
    703         #    self.base_field().polynomial())
    704 
    705709    def _Hom_(self, codomain, cat=None):
    706710        """
    707711        Return homset of homomorphisms from this relative number field
    708712        to the codomain.
    709713
    710         The cat option is currently ignored.   The result is not cached.
     714        The cat option is currently ignored. The result is not cached.
    711715
    712716        EXAMPLES:
    713717        This function is implicitly called by the Hom method or function.::
    714718
    715719            sage: K.<a,b> = NumberField([x^3 - 2, x^2+1])
    716             sage: K.Hom(K)
     720            sage: K.Hom(K) # indirect doctest
    717721            Automorphism group of Number Field in a with defining polynomial x^3 - 2 over its base field
    718722            sage: type(K.Hom(K))
    719723            <class 'sage.rings.number_field.morphism.RelativeNumberFieldHomset_with_category'>
     
    966970        Canonical coercion of x into this relative number field.
    967971
    968972        Currently integers, rationals, the base field, and this field
    969         itself coerce canonical into this field.
     973        itself coerce canonically into this field (and hence so does
     974        anything that coerces into one of these).
    970975
    971976        EXAMPLES::
    972 
    973             sage: S.<y> = NumberField(x^3 + x + 1)
    974             sage: S.coerce(int(4))
    975             4
    976             sage: S.coerce(long(7))
    977             7
    978             sage: S.coerce(-Integer(2))
    979             -2
    980             sage: z = S.coerce(-7/8); z, type(z)
    981             (-7/8, <type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>)
    982             sage: S.coerce(y) is y
    983             True
    984 
    985         Fields with embeddings into an ambient field coerce naturally.::
    986 
    987             sage: CyclotomicField(15).coerce(CyclotomicField(5).0 - 17/3)
    988             zeta15^3 - 17/3
    989             sage: K.<a> = CyclotomicField(16)
    990             sage: K(CyclotomicField(4).0)
    991             a^4
    992             sage: QuadraticField(-3, 'a').coerce_map_from(CyclotomicField(3))
    993             Generic morphism:
    994               From: Cyclotomic Field of order 3 and degree 2
    995               To:   Number Field in a with defining polynomial x^2 + 3
    996               Defn: zeta3 -> 1/2*a - 1/2
    997 
    998         There are situations for which one might imagine canonical
    999         coercion could make sense (at least after fixing choices), but
    1000         which are not yet implemented::
    1001 
    1002             sage: K.<a> = QuadraticField(2)
    1003             sage: K.coerce(sqrt(2))
    1004             Traceback (most recent call last):
    1005             ...
    1006             TypeError: no canonical coercion from Symbolic Ring to Number Field in a with defining polynomial x^2 - 2
    1007 
    1008         TESTS::
    1009 
    1010             sage: K.<a> = NumberField(polygen(QQ)^3-2)
    1011             sage: type(K.coerce_map_from(QQ))
    1012             <type 'sage.structure.coerce_maps.DefaultConvertMap_unique'>
    1013977           
    1014         Make sure we still get our optimized morphisms for special fields::
    1015        
    1016             sage: K.<a> = NumberField(polygen(QQ)^2-2)
    1017             sage: type(K.coerce_map_from(QQ))
    1018             <type 'sage.rings.number_field.number_field_element_quadratic.Q_to_quadratic_field_element'>
    1019         """
    1020         if R in [self, int, long, ZZ, QQ, self.base_field()]:
    1021             return self._generic_convert_map(R)
    1022         from sage.rings.number_field.order import is_NumberFieldOrder
    1023         if is_NumberFieldOrder(R) and R.number_field().has_coerce_map_from(self):
    1024             return self._generic_convert_map(R)
    1025         if is_NumberField(R) and R != QQ:
    1026             if R.coerce_embedding() is not None:
    1027                 if self.coerce_embedding() is not None:
    1028                     try:
    1029                         from sage.categories.pushout import pushout
    1030                         ambient_field = pushout(R.coerce_embedding().codomain(), self.coerce_embedding().codomain())
    1031                         if ambient_field is not None:
    1032                             return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
    1033                     except (TypeError, ValueError):
    1034                         pass
    1035 
    1036     def _coerce_map_from_(self, R):
    1037         """
    1038         Canonical implicit coercion of ``R`` into self.
    1039 
    1040         Elements of this field canonically coerce in, as does anything
    1041         that coerces into the base field of this field.
    1042 
    1043         EXAMPLES::
    1044 
    1045978            sage: k.<a> = NumberField([x^5 + 2, x^7 + 3])
    1046979            sage: b = k(k.base_field().gen())
    1047             sage: b = k.coerce(k.base_field().gen())
     980            sage: b = k.coerce(k.base_field().gen()) # indirect doctest
    1048981            sage: b^7
    1049982            -3
    1050983            sage: k.coerce(2/3)
    1051984            2/3
    1052             sage: c = a + b  # this works
     985            sage: c = a + b # no output
    1053986        """
    1054987        if R in [int, long, ZZ, QQ, self.base_field()]:
    1055988            return self._generic_convert_map(R)
     
    11061039            sage: k.<a> = NumberField([x^2 + 3, x^2 + 1])
    11071040            sage: m = k.base_field(); m
    11081041            Number Field in a1 with defining polynomial x^2 + 1
    1109             sage: k._coerce_(m.0 + 2/3)
     1042            sage: k.coerce(m.0 + 2/3) # indirect doctest
    11101043            a1 + 2/3
    1111             sage: s = k._coerce_(m.0); s
     1044            sage: s = k.coerce(m.0); s
    11121045            a1
    11131046            sage: s^2
    11141047            -1
     
    11161049        This implicitly tests this coercion map::
    11171050
    11181051            sage: K.<a> = NumberField([x^2 + p for p in [5,3,2]])
    1119             sage: K._coerce_(K.base_field().0)
     1052            sage: K.coerce(K.base_field().0)
    11201053            a1
    1121             sage: K._coerce_(K.base_field().0)^2
     1054            sage: K.coerce(K.base_field().0)^2
    11221055            -3
    11231056
    11241057        TESTS:
     
    13361269        r"""
    13371270        For a relative number field, ``vector_space()`` is
    13381271        deliberately not implemented, so that a user cannot confuse
    1339         ``relative_vector_space()`` with ``absolute_vector_space()``.
     1272        :meth:`~relative_vector_space` with :meth:`~absolute_vector_space`.
     1273       
     1274        EXAMPLE::
     1275       
     1276            sage: K.<a> = NumberFieldTower([x^2 - 17, x^3 - 2])
     1277            sage: K.vector_space()
     1278            Traceback (most recent call last):
     1279            ...
     1280            NotImplementedError: For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate
     1281
    13401282        """
    13411283        raise NotImplementedError, "For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate"
    13421284       
     
    14071349            sage: y = polygen(k)
    14081350            sage: m.<b> = k.extension(y^2+3); m
    14091351            Number Field in b with defining polynomial x^2 + 3 over its base field
    1410             sage: c = m.gen(); c
     1352            sage: c = m.gen(); c # indirect doctest
    14111353            b
    14121354            sage: c^2 + 3
    14131355            0
     
    16371579
    16381580        EXAMPLES::
    16391581
    1640             sage: NumberField(x^2 + (2/3)*x - 9/17,'a').polynomial_ntl()
     1582            sage: NumberField(x^2 + (2/3)*x - 9/17,'a').absolute_polynomial_ntl()
    16411583            ([-27 34 51], 51)
    16421584        """
    16431585        try:
     
    17021644    def polynomial(self):
    17031645        """
    17041646        For a relative number field, ``polynomial()`` is deliberately
    1705         not implemented.  Either ``relative_polynomial()`` or
    1706         ``absolute_polynomial()`` must be used.
     1647        not implemented.  Either :meth:`~relative_polynomial` or
     1648        :meth:`~absolute_polynomial` must be used.
     1649       
     1650        EXAMPLE::
     1651       
     1652            sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
     1653            sage: K.polynomial()
     1654            Traceback (most recent call last):
     1655            ...
     1656            NotImplementedError: For a relative number field L you must use either L.relative_polynomial() or L.absolute_polynomial() as appropriate
    17071657        """
    17081658        raise NotImplementedError, "For a relative number field L you must use either L.relative_polynomial() or L.absolute_polynomial() as appropriate"
    17091659
     
    19621912        The different, unqualified, of a relative number field is deliberately
    19631913        not implemented, so that a user cannot mistake the absolute different
    19641914        for the relative different, or vice versa.
     1915       
     1916        EXAMPLE::
     1917       
     1918            sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
     1919            sage: K.different()
     1920            Traceback (most recent call last):
     1921            ...
     1922            NotImplementedError: For a relative number field you must use relative_different or absolute_different as appropriate
    19651923        """
    19661924        raise NotImplementedError, "For a relative number field you must use relative_different or absolute_different as appropriate"
    19671925
     
    20271985        The discriminant, unqualified, of a relative number field is deliberately
    20281986        not implemented, so that a user cannot mistake the absolute discriminant
    20291987        for the relative discriminant, or vice versa.
     1988               
     1989        EXAMPLE::
     1990       
     1991            sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
     1992            sage: K.discriminant()
     1993            Traceback (most recent call last):
     1994            ...
     1995            NotImplementedError: For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate
    20301996        """
    20311997        raise NotImplementedError, "For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate"
    20321998
     
    20352001        The discriminant, unqualified, of a relative number field is deliberately
    20362002        not implemented, so that a user cannot mistake the absolute discriminant
    20372003        for the relative discriminant, or vice versa.
     2004       
     2005        EXAMPLE::
     2006       
     2007            sage: K.<a> = NumberFieldTower([x^2 + x + 1, x^3 + x + 1])
     2008            sage: K.disc()
     2009            Traceback (most recent call last):
     2010            ...
     2011            NotImplementedError: For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate
    20382012        """
    20392013        raise NotImplementedError, "For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate"
    20402014
  • sage/rings/number_field/totallyreal.pyx

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/totallyreal.pyx
    a b  
    11"""
    2 Enumeration of Totally Real Fields
     2Enumeration of Primitive Totally Real Fields
    33
    4 AUTHORS:
    5     -- Craig Citro and John Voight (2008-02-10):
    6         * Final modifications for submission.
    7     -- Craig Citro and John Voight (2007-11-04):
    8         * Additional doctests and type checking.
    9     -- John Voight (2007-10-27):
    10         * Separated DSage component.
    11     -- John Voight (2007-10-17):
    12         * Added pari functions to avoid recomputations.
    13     -- John Voight (2007-10-09):
    14         * Added DSage module.
    15     -- John Voight (2007-09-19):
    16         * Various optimization tweaks.
    17     -- John Voight (2007-09-01):
    18         * Initial version.
     4This module contains functions for enumerating all primitive
     5totally real number fields of given degree and small discriminant.
     6Here a number field is called *primitive* if it contains no proper
     7subfields except `\QQ`.
     8
     9See also :mod:`sage.rings.number_field.totallyreal_rel`, which handles the non-primitive
     10case using relative extensions.
     11
     12Algorithm
     13---------
     14
     15We use Hunter's algorithm ([C]_, Section 9.3) with modifications
     16due to Takeuchi [T]_ and the author [V]_.
     17
     18We enumerate polynomials `f(x) = x^n + a_{n-1} x^{n-1} + \dots + a_0`.   
     19Hunter's theorem gives bounds on `a_{n-1}` and `a_{n-2}`; then given
     20`a_{n-1}` and `a_{n-2}`, one can recursively compute bounds on `a_{n-3},
     21\dots, a_0`, using the fact that the polynomial is totally real by
     22looking at the zeros of successive derivatives and applying
     23Rolle's theorem. See [T]_ for more details.
     24
     25Examples
     26--------
     27
     28In this first simple example, we compute the totally real quadratic
     29fields of discriminant `\le 50`.
     30
     31::
     32
     33    sage: enumerate_totallyreal_fields_prim(2,50)
     34    [[5, x^2 - x - 1],
     35     [8, x^2 - 2],
     36     [12, x^2 - 3],
     37     [13, x^2 - x - 3],
     38     [17, x^2 - x - 4],
     39     [21, x^2 - x - 5],
     40     [24, x^2 - 6],
     41     [28, x^2 - 7],
     42     [29, x^2 - x - 7],
     43     [33, x^2 - x - 8],
     44     [37, x^2 - x - 9],
     45     [40, x^2 - 10],
     46     [41, x^2 - x - 10],
     47     [44, x^2 - 11]]
     48    sage: [ d for d in range(5,50) if (is_squarefree(d) and d%4 == 1) or (d%4 == 0 and is_squarefree(d/4)) ]
     49    [5, 8, 12, 13, 17, 20, 21, 24, 28, 29, 33, 37, 40, 41, 44]
     50
     51Next, we compute all totally real quintic fields of discriminant `\le 10^5`::
     52
     53    sage: ls = enumerate_totallyreal_fields_prim(5,10^5) ; ls
     54    [[14641, x^5 - x^4 - 4*x^3 + 3*x^2 + 3*x - 1],
     55     [24217, x^5 - 5*x^3 - x^2 + 3*x + 1],
     56     [36497, x^5 - 2*x^4 - 3*x^3 + 5*x^2 + x - 1],
     57     [38569, x^5 - 5*x^3 + 4*x - 1],
     58     [65657, x^5 - x^4 - 5*x^3 + 2*x^2 + 5*x + 1],
     59     [70601, x^5 - x^4 - 5*x^3 + 2*x^2 + 3*x - 1],
     60     [81509, x^5 - x^4 - 5*x^3 + 3*x^2 + 5*x - 2],
     61     [81589, x^5 - 6*x^3 + 8*x - 1],
     62     [89417, x^5 - 6*x^3 - x^2 + 8*x + 3]]
     63     sage: len(ls)
     64     9
     65
     66We see that there are 9 such fields (up to isomorphism!).
     67
     68References
     69----------
     70   
     71.. [C] Henri Cohen, Advanced topics in computational number
     72   theory, Graduate Texts in Mathematics, vol. 193,
     73   Springer-Verlag, New York, 2000.
     74
     75.. [M] Jacques Martinet, Petits discriminants des corps de nombres, Journ. Arithm. 1980,
     76   Cambridge Univ. Press, 1982, 151--193.       
     77
     78.. [T] Kisao Takeuchi, Totally real algebraic number fields of
     79   degree 9 with small discriminant, Saitama Math. J.
     80   17 (1999), 63--85 (2000).
     81       
     82.. [V] John Voight, Enumeration of totally real number fields
     83   of bounded root discriminant, to appear in
     84   Lect. Notes in Comp. Sci.
     85
     86Authors
     87-------
     88
     89- John Voight (2007-09-01): Initial version.
     90- John Voight (2007-09-19): Various optimization tweaks.
     91- John Voight (2007-10-09): Added DSage module.
     92- John Voight (2007-10-17): Added pari functions to avoid recomputations.
     93- John Voight (2007-10-27): Separated DSage component.
     94- Craig Citro and John Voight (2007-11-04): Additional doctests and type checking.
     95- Craig Citro and John Voight (2008-02-10): Final modifications for submission.
     96
     97------
    1998"""
    2099
    21100#*****************************************************************************
     
    69148    The bounds for n > 50 are not necessarily optimal.
    70149
    71150    INPUT:
    72     n -- integer, the degree
     151   
     152    - n (integer) the degree
    73153
    74154    OUTPUT:
    75     a lower bound on the root discriminant
     155   
     156    a lower bound on the root discriminant (as a real number)
    76157
    77     EXAMPLES:
    78     sage: [sage.rings.number_field.totallyreal.odlyzko_bound_totallyreal(n) for n in range(1,5)]
    79     [1.0, 2.2229999999999999, 3.6099999999999999, 5.0670000000000002]
     158    EXAMPLES::
     159   
     160        sage: [sage.rings.number_field.totallyreal.odlyzko_bound_totallyreal(n) for n in range(1,5)]
     161        [1.0, 2.2229999999999999, 3.6099999999999999, 5.0670000000000002]
    80162
    81163    AUTHORS:
     164   
    82165    - John Voight (2007-09-03)
    83166
    84167    NOTES:
    85     The values are calculated by Martinet [M].
    86 
    87         [M] Jacques Martinet, Petits discriminants des corps de nombres, Journ. Arithm. 1980,
    88             Cambridge Univ. Press, 1982, 151--193.
     168    The values are calculated by Martinet [M]_.
    89169    """
    90170
    91171    if n <= 10:
     
    107187                                      just_print=False):
    108188    r"""
    109189    This function enumerates primitive totally real fields of degree
    110     $n>1$ with discriminant $d \leq B$; optionally one can specify the
    111     first few coefficients, where the sequence $a$ corresponds to a
    112     polynomial by
    113         $$ a[d]*x^n + ... + a[0]*x^(n-d) $$
    114     where length(a) = d+1, so in particular always a[d] = 1.
     190    `n>1` with discriminant `d \leq B`; optionally one can specify the
     191    first few coefficients, where the sequence `a` corresponds to
    115192   
    116     If verbose == 1 (or 2), then print to the screen (really)
    117     verbosely; if verbose is a string, then print verbosely to the
    118     file specified by verbose.
     193    ::
    119194   
    120     If return_seqs, then return the polynomials as sequences (for
    121     easier exporting to a file).
     195        a[d]*x^n + ... + a[0]*x^(n-d)
     196       
     197    where ``length(a) = d+1``, so in particular always ``a[d] = 1``.
    122198   
    123     If keep_fields, then keep fields up to B*log(B); if keep_fields is
    124     an integer, then keep fields up to that integer.
     199    .. note::
    125200   
    126     If t_2 = T, then keep only polynomials with t_2 norm >= T.
    127 
    128     If just_print is not False, instead of creating a sorted list of
    129     totally real number fields, we simply write each totally real
    130     field we find to the file whose filename is given by
    131     just_print. In this case, we don't return anything.
    132 
    133     NOTE:
    134201        This is guaranteed to give all primitive such fields, and
    135202        seems in practice to give many imprimitive ones.
    136203
    137204    INPUT:
    138         n -- integer, the degree
    139         B -- integer, the discriminant bound
    140         a -- list (default: []), the coefficient list to begin with
    141         verbose -- boolean or string (default: False)
    142         phc -- boolean or integer (default: False)
     205   
     206    - ``n`` (integer): the degree
     207    - ``B`` (integer): the discriminant bound
     208    - ``a`` (list, default: []): the coefficient list to begin with
     209    - ``verbose`` (integer or string, default: 0): if ``verbose == 1``
     210      (or ``2``), then print to the screen (really) verbosely; if verbose is
     211      a string, then print verbosely to the file specified by verbose.
     212    - ``return_seqs`` (boolean, default False)If ``return_seqs``, then return
     213      the polynomials as sequences (for easier exporting to a file).
     214    - ``phc`` -- boolean or integer (default: False)
     215    - ``keep_fields`` (boolean or integer, default: False) If ``keep_fields`` is True,
     216      then keep fields up to ``B*log(B)``; if ``keep_fields`` is an integer, then
     217      keep fields up to that integer.
     218    - ``t_2`` (boolean or integer, default: False) If ``t_2 = T``, then keep
     219      only polynomials with t_2 norm >= T.
     220    - ``just_print`` (boolean, default: False): if ``just_print`` is not False,
     221      instead of creating a sorted list of totally real number fields, we simply
     222      write each totally real field we find to the file whose filename is given by
     223      ``just_print``. In this case, we don't return anything.
    143224
    144225    OUTPUT:
    145         the list of fields with entries [d,f], where d is the
    146           discriminant and f is a defining polynomial, sorted by
    147           discriminant.
     226   
     227    the list of fields with entries ``[d,f]``, where ``d`` is the
     228    discriminant and ``f`` is a defining polynomial, sorted by
     229    discriminant.
    148230
    149     EXAMPLES:
    150     In this first simple example, we compute the totally real quadratic
    151     fields of discriminant <= 50.
    152         sage: enumerate_totallyreal_fields_prim(2,50)
    153         [[5, x^2 - x - 1],
    154          [8, x^2 - 2],
    155          [12, x^2 - 3],
    156          [13, x^2 - x - 3],
    157          [17, x^2 - x - 4],
    158          [21, x^2 - x - 5],
    159          [24, x^2 - 6],
    160          [28, x^2 - 7],
    161          [29, x^2 - x - 7],
    162          [33, x^2 - x - 8],
    163          [37, x^2 - x - 9],
    164          [40, x^2 - 10],
    165          [41, x^2 - x - 10],
    166          [44, x^2 - 11]]
    167         sage: [ d for d in range(5,50) if (is_squarefree(d) and d%4 == 1) or (d%4 == 0 and is_squarefree(d/4)) ]
    168         [5, 8, 12, 13, 17, 20, 21, 24, 28, 29, 33, 37, 40, 41, 44]
    169 
    170     Next, we compute all totally real quintic fields of discriminant <= 10^5.
    171         sage: ls = enumerate_totallyreal_fields_prim(5,10^5) ; ls
    172         [[14641, x^5 - x^4 - 4*x^3 + 3*x^2 + 3*x - 1],
    173          [24217, x^5 - 5*x^3 - x^2 + 3*x + 1],
    174          [36497, x^5 - 2*x^4 - 3*x^3 + 5*x^2 + x - 1],
    175          [38569, x^5 - 5*x^3 + 4*x - 1],
    176          [65657, x^5 - x^4 - 5*x^3 + 2*x^2 + 5*x + 1],
    177          [70601, x^5 - x^4 - 5*x^3 + 2*x^2 + 3*x - 1],
    178          [81509, x^5 - x^4 - 5*x^3 + 3*x^2 + 5*x - 2],
    179          [81589, x^5 - 6*x^3 + 8*x - 1],
    180          [89417, x^5 - 6*x^3 - x^2 + 8*x + 3]]
    181          sage: len(ls)
    182          9
    183 
    184     We see that there are 9 such fields (up to isomorphism!).
    185 
    186     NOTES:
    187     This function uses Hunter's algorithm [C, Section 9.3] and
    188     modifications due to Takeuchi [T] and the author [V].
    189 
    190     We enumerate polynomials
    191         f(x) = x^n + a[n-1]*x^(n-1) + ... + a[0].
    192     Hunter's theorem gives bounds on a[n-1] and a[n-2]; then given
    193     a[n-1] and a[n-2], one can recursively compute bounds on a[n-3],
    194     ..., a[0] using the fact that the polynomial is totally real by
    195     looking at the zeros of successive derivatives and applying
    196     Rolle's theorem!  See [T] for more details.
    197 
    198         REFERENCES:
    199             [C] Henri Cohen, Advanced topics in computational number
    200                 theory, Graduate Texts in Mathematics, vol. 193,
    201                 Springer-Verlag, New York, 2000.
    202             [T] Kisao Takeuchi, Totally real algebraic number fields of
    203                 degree 9 with small discriminant, Saitama Math. J.
    204                 17 (1999), 63--85 (2000).
    205             [V] John Voight, Enumeration of totally real number fields
    206                 of bounded root discriminant, to appear in
    207                 Lect. Notes in Comp. Sci.
    208231
    209232    AUTHORS:
    210         - John Voight (2007-09-03)
    211         - Craig Citro (2008-09-19): moved to Cython for speed improvement
     233   
     234    - John Voight (2007-09-03)
     235    - Craig Citro (2008-09-19): moved to Cython for speed improvement
    212236
    213     TESTS:
     237    TESTS::
     238   
    214239        sage: len(enumerate_totallyreal_fields_prim(2,10**4))
    215240        3043
    216241        sage: len(enumerate_totallyreal_fields_prim(3,3**8))
     
    456481
    457482def weed_fields(S, Py_ssize_t lenS=0):
    458483    r"""
    459     Function used internally by the enumerate_totallyreal_fields()
     484    Function used internally by the :func:`~enumerate_totallyreal_fields_prim`
    460485    routine. (Weeds the fields listed by [discriminant, polynomial]
    461486    for isomorphism classes.) Returns the size of the resulting list.
    462487
    463     EXAMPLES:
     488    EXAMPLES::
     489   
    464490        sage: ls = [[5,pari('x^2-3*x+1')],[5,pari('x^2-5')]]
    465491        sage: sage.rings.number_field.totallyreal.weed_fields(ls)
    466492        1
     
    500526    Converts seconds to a human-readable time string.
    501527
    502528    INPUT:
    503         m -- integer, number of seconds
     529   
     530    - m -- integer, number of seconds
    504531
    505532    OUTPUT:
    506         The time in days, hours, etc.
     533   
     534    The time in days, hours, etc.
    507535
    508     EXAMPLES:
     536    EXAMPLES::
     537   
    509538        sage: sage.rings.number_field.totallyreal.timestr(3765)
    510539        '1h 2m 45.0s'
    511540    """
  • deleted file sage/rings/number_field/totallyreal_dsage.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/totallyreal_dsage.py
    + -  
    1 """nodoctest"""
    2 
    3 """
    4 Enumeration of Totally Real Fields: DSage components
    5 
    6 AUTHORS:
    7     -- John Voight (2007-11-04):
    8         * Changes made after DSage bug fixes.
    9     -- John Voight (2007-10-27):
    10         * Initial version.
    11 """
    12 
    13 #*****************************************************************************
    14 #       Copyright (C) 2007 William Stein and John Voight
    15 #
    16 #  Distributed under the terms of the GNU General Public License (GPL)
    17 #
    18 #    This code is distributed in the hope that it will be useful,
    19 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    20 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    21 #    General Public License for more details.
    22 #
    23 #  The full text of the GPL is available at:
    24 #
    25 #                  http://www.gnu.org/licenses/
    26 #*****************************************************************************
    27 
    28 import time
    29 from sage.rings.number_field.totallyreal_data import tr_data
    30 from sage.rings.number_field.totallyreal import timestr, weed_fields
    31 from sage.libs.pari.gen import pari
    32 
    33 class totallyreal_dsage:
    34     counts = [0,0,0,0]
    35     S = []
    36     cputime = 0
    37     walltime = 0
    38 
    39     def __init__(self, D=None, timeout = 0):
    40         r"""
    41         Initializes the totallyreal DSage instance.
    42 
    43         INPUT:
    44         D -- (default: None) a DSage instance
    45         timeout -- (default: 30*60) the default timeout
    46 
    47         OUTPUT:
    48         the totallyreal DSage instance
    49 
    50         EXAMPLES:
    51         First, in the server window:
    52 
    53         sage: dsage.setup_all()
    54         [...]
    55         sage: dsage.server()
    56         [...]
    57 
    58         Now, setup workers.  On each machine that wants to be a worker:
    59 
    60         sage: dsage.setup_worker()
    61         [...]
    62         sage: dsage.worker()
    63         [...]
    64 
    65         Finally, at a client:
    66 
    67         sage: Dtr = totallyreal_dsage()
    68         """
    69 
    70         if D == None:
    71             self.D = DSage()
    72         else:
    73             self.D = D
    74         self.timeout = timeout
    75 
    76     def enumerate(self, n, B, k, load=True, keep_fields=False, t_2=False):
    77         """
    78         Runs the enumeration algorithm in enumerate_totallyreal_fields_prim in
    79         a distributed computing environment.
    80         Once coefficients the coefficients a[k+1...n] are obtained,
    81         the rest are performed by workers.
    82 
    83         INPUT:
    84         n -- integer, the degree
    85         B -- integer, the discriminant bound
    86         k -- integer, the sequence length
    87 
    88         OUTPUT:
    89         the updated totallyreal dsage instance with jobs running.
    90 
    91         EXAMPLES:
    92         We enumerate totally real fields of degree 6 and root discriminant <= 15. 
    93         The workers are given coefficient ranges up to k = 3, i.e.
    94         [?,?,?,?,!,!,1].
    95 
    96         sage: Dtr.enumerate(6, 15^6, 4)
    97         [...]
    98         sage: Dtr.compile_fields()
    99 
    100         [[300125, x^6 - x^5 - 7*x^4 + 2*x^3 + 7*x^2 - 2*x - 1],
    101          [371293, x^6 - x^5 - 5*x^4 + 4*x^3 + 6*x^2 - 3*x - 1],
    102          [434581, x^6 - 2*x^5 - 4*x^4 + 5*x^3 + 4*x^2 - 2*x - 1],
    103          [453789, x^6 - x^5 - 6*x^4 + 6*x^3 + 8*x^2 - 8*x + 1],
    104          [485125, x^6 - 2*x^5 - 4*x^4 + 8*x^3 + 2*x^2 - 5*x + 1],
    105          [592661, x^6 - x^5 - 5*x^4 + 4*x^3 + 5*x^2 - 2*x - 1],
    106          [703493, x^6 - 2*x^5 - 5*x^4 + 11*x^3 + 2*x^2 - 9*x + 1],
    107          [722000, x^6 - x^5 - 6*x^4 + 7*x^3 + 4*x^2 - 5*x + 1]]
    108 
    109         """
    110 
    111         # We first precompute the a[k+1..n] possibilities.
    112         # Initialize.
    113         self.n = n
    114         self.B = B
    115         self.k = k
    116         T = tr_data(n,B,[])
    117         f_out = [0]*n + [1]
    118 
    119         # Increment, and halt at level k.
    120         # Feed tasks to the workers, one for each a.
    121         self.prestr = 'DSAGE_RESULT=enumerate_totallyreal_fields_prim(' + str(n) + ',' + str(B) + ','
    122         self.jobs = []
    123         # Small tweak.
    124         if k <> n-1:
    125             T.incr(f_out, haltk=k)
    126 
    127         list_jobs = []
    128 
    129         while f_out[n] <> 0:
    130             a = f_out[k:n+1]
    131             list_jobs.append([a[k]**2-2*a[k-1],a])
    132             T.incr(f_out, haltk=k)
    133 
    134         list_jobs.sort()
    135 
    136         for a in list_jobs:
    137             # Dsage handles it all here.
    138             if load:
    139                 job = self.D.eval(self.prestr + str(a[1]) + ',return_seqs=True,keep_fields=' + str(keep_fields) + ',t_2=' + str(t_2) + ')', timeout = self.timeout)
    140                 self.jobs.append([a[1],job])
    141             else:
    142                 self.jobs.append([a[1],''])
    143 
    144     def init_jobs(self, n, B, A, split=False, keep_fields=False, t_2=False):
    145         self.n = n
    146         self.B = B
    147         f_out = [0]*n + [1]
    148         self.jobs = []
    149         self.prestr = 'DSAGE_RESULT=enumerate_totallyreal_fields_prim(' + str(n) + ',' + str(B) + ','
    150 
    151         if split:
    152             for a0 in A:
    153                 T = tr_data(n, B, a0)
    154                 f_out = [0]*n + [1]
    155                 k_new = n-len(a0)
    156                 T.incr(f_out, 0, haltk=k_new)
    157                 while f_out[self.n] <> 0:
    158                     a = f_out[k_new:self.n+1]
    159                     # Dsage handles it all here.
    160                     job = self.D.eval(self.prestr + str(a) + ',return_seqs=True,keep_fields=' + str(keep_fields) + ',t_2=' + str(t_2) + ')', timeout = self.timeout)
    161                     self.jobs.append([a,job])
    162                     T.incr(f_out, haltk=k_new)
    163             self.k = k_new       
    164         else:
    165             for a in A:
    166                 job = self.D.eval(self.prestr + str(a) + ',return_seqs=True,keep_fields=' + str(keep_fields) + ',t_2=' + str(t_2) + ')', timeout = self.timeout)
    167                 self.jobs.append([a,job])
    168 
    169     def recover(self):
    170         jobs = self.D.get_my_jobs(True)
    171         find_str = '(' + str(self.n) + ',' + str(self.B)
    172         jobs_v = [j[0] for j in self.jobs]
    173         for i in range(len(jobs)):
    174             jc = jobs[i].code
    175             try:
    176                 jc.index(find_str)
    177                 v = eval(jc[jc.find('['):jc.find(']')+1])
    178                 self.jobs[jobs_v.index(v)][1] = jobs[i]
    179             except ValueError:
    180                 v = []
    181 
    182     def load_jobs(self, A, split=False):
    183         self.init_jobs(self.n, self.B, A, split)
    184 
    185     def restart_job(self, i, force=False, keep_fields=False, t_2=False):
    186         if force or self.jobs[i][1].status == 'completed':
    187             job = self.D.eval(self.prestr + str(self.jobs[i][0]) + ',return_seqs=True,keep_fields=' + str(keep_fields) + ',t_2=' + str(t_2) + ')', timeout = self.timeout)
    188             self.jobs[i][1] = job
    189 
    190     def restart_all_jobs(self, force=False):
    191         for i in range(len(self.jobs)):
    192             self.restart_job(i, force)
    193 
    194     def split_job(self, i, force=False, t_2=False):
    195         if force or self.jobs[i][1].output.find('computation timed out') <> -1:
    196             job = self.jobs.pop(i)
    197             T = tr_data(self.n, self.B, job[0])
    198             f_out = [0]*self.n + [1]
    199             k_new = self.n-len(job[0])
    200             T.incr(f_out, 0, haltk=k_new)
    201             while f_out[self.n] <> 0:
    202                 a = f_out[k_new:self.n+1]
    203                 # Dsage handles it all here.
    204                 job = self.D.eval(self.prestr + str(a) + ',return_seqs=True,keep_fields=' + str(keep_fields) + ',t_2=' + str(t_2) + ')', timeout = self.timeout)
    205                 self.jobs.append([a,job])
    206                 T.incr(f_out, haltk=k_new)
    207 
    208     def split_all_jobs(self, force=False):
    209         if force:
    210             for i in range(len(self.jobs)):
    211                 self.split_job(0,force)
    212         else:
    213             i = 0
    214             while i < len(self.jobs):
    215                 if self.jobs[i][1] <> '' and self.jobs[i][1].output.find('computation timed out') <> -1:
    216                     self.split_job(i,True)
    217                 else:
    218                     i += 1
    219 
    220     def status(self):
    221         r"""
    222         Prints the current status of all jobs.
    223         """
    224 
    225         for i in range(len(self.jobs)):
    226             if type(self.jobs[i][1]) <> str:
    227                 print self.jobs[i][0], self.jobs[i][1].status
    228 
    229     def just_save(self):
    230         r"""
    231         Pop any finished jobs and save the resulting data.
    232         """
    233 
    234         filename_start = str(self.n) + '/' + str(self.n) + '-' + str(self.B) + '-'
    235        
    236         i = 0
    237         # For each completed job, add the fields to the list.
    238         while i < len(self.jobs):
    239             if type(self.jobs[i][1]) <> str:
    240                 if self.jobs[i][1].status == 'completed' and not self.jobs[i][1].result in ['None', '']:
    241                     print "Saving job", i, "with", self.jobs[i][0]
    242                     job = self.jobs[i]
    243 
    244                     # Add the timings.
    245                     self.cputime += job[1].cpu_time
    246                     self.walltime += job[1].wall_time
    247 
    248                     fsock = open(filename_start + str(job[0]).replace(' ','') + '.out', 'w')
    249                     fsock.write("Cpu time = " + timestr(job[1].cpu_time) + "\n")
    250                     fsock.write("Wall time = " + timestr(job[1].wall_time) + "\n")
    251 
    252                     S = job[1].result
    253                     # Add the counts of polynomials checked.
    254                     for j in range(4):
    255                         self.counts[j] += S[0][j]
    256                     fsock.write("Counts: " + str(S[0]) + "\n")
    257                     fsock.write("Total number of fields: " + str(len(S[1])) + "\n\n")
    258 
    259                     # Save fields
    260                     S = S[1]
    261                     for j in range(len(S)):
    262                         fsock.write(str(S[j]) + "\n")
    263 
    264                     fsock.close()
    265                     self.jobs.pop(i)
    266 
    267                 # Otherwise, continue. 
    268                 # Note we do not add 1 to i if we just popped jobs!
    269                 else:
    270                     i += 1
    271             else:
    272                 i += 1
    273 
    274         fsock = open(filename_start + 'reload.dat', 'w')
    275         fsock.write(str([[self.jobs[i][0] for i in range(len(self.jobs))],
    276                          [[s[0], s[1].reverse().Vec()] for s in self.S],
    277                          self.counts, self.cputime, self.walltime]))
    278         fsock.close()
    279         print self.num_jobs(), "remaining..."
    280 
    281     def compile_fields(self, write_result=True):
    282         r"""
    283         Pop any finished jobs and compiles into the master list.
    284         If save_result == True, then save the output of the result.
    285         """
    286 
    287         filename_start = str(self.n) + '/' + str(self.n) + '-' + str(self.B) + '-'
    288 
    289         i = 0
    290         # For each completed job, add the fields to the list.
    291         while i < len(self.jobs):
    292             if type(self.jobs[i][1]) <> str:
    293                 # self.jobs[i][1].get_job()
    294                 if self.jobs[i][1].status == 'completed' and not self.jobs[i][1].result in ['None', '']:
    295                     print "Compiling job", i, "with", self.jobs[i][0]
    296                     job = self.jobs[i]
    297 
    298                     # Add the timings.
    299                     self.cputime += job[1].cpu_time
    300                     self.walltime += job[1].wall_time
    301 
    302                     if write_result:
    303                         fsock = open(filename_start + str(job[0]).replace(' ','') + '.out', 'w')
    304                         fsock.write("Cpu time = " + timestr(job[1].cpu_time) + "\n")
    305                         fsock.write("Wall time = " + timestr(job[1].wall_time) + "\n")
    306 
    307                     # Output from dsage comes as a string, so convert.
    308                     S = job[1].result
    309                     # Add the counts of polynomials checked.
    310                     for j in range(4):
    311                         self.counts[j] += S[0][j]
    312                     if write_result:
    313                         fsock.write("Counts: " + str(S[0]) + "\n")
    314                         fsock.write("Total number of fields: " + str(len(S[1])) + "\n\n")
    315 
    316                     # Convert the sequences to pari objects, and compile.
    317                     S = S[1]
    318                     for j in range(len(S)):
    319                         S[j][1] = pari(str(S[j][1])).Polrev()
    320                     self.S += S
    321                     if write_result:
    322                         for j in range(len(S)):
    323                             fsock.write(str(S[j]) + "\n")
    324 
    325                     fsock.close()
    326                     self.jobs.pop(i)
    327 
    328                 # Otherwise, continue. 
    329                 # Note we do not add 1 to i if we just popped jobs!
    330                 else:
    331                     i += 1
    332             else:
    333                 i += 1
    334      
    335         # Now check for copies of fields and isomorphic fields.
    336         self.S.sort()
    337         i = 0
    338         while i < len(self.S)-1:
    339             if self.S[i] == self.S[i+1]:
    340                 self.S.pop(i)
    341             else:
    342                 i += 1
    343         weed_fields(self.S)
    344 
    345         if write_result:
    346             fsock = open(filename_start + 'all.out', 'w')
    347             fsock.write("Cpu time: " + timestr(self.cputime) + "\n")
    348             fsock.write("Wall time: " + timestr(self.walltime) + "\n")
    349             fsock.write("Counts: " + str(self.counts) + "\n")
    350             fsock.write("Total number of fields: " + str(len(self.S)) + "\n\n")
    351 
    352             if len(self.jobs) > 0:
    353                 fsock.write("Incomplete jobs:\n")
    354                 for i in range(len(self.jobs)):
    355                     fsock.write(str(self.jobs[i][0]) + "\n")
    356                 fsock.write("\n")
    357 
    358             for j in range(len(self.S)):
    359                 fsock.write(str([self.S[j][0],self.S[j][1].reverse().Vec()]) + "\n")
    360             fsock.close()
    361 
    362             fsock = open(filename_start + 'reload.dat', 'w')
    363             fsock.write(str([[self.jobs[i][0] for i in range(len(self.jobs))],
    364                              [[s[0], s[1].reverse().Vec()] for s in self.S],
    365                              self.counts, self.cputime, self.walltime]))
    366             fsock.close()
    367             print self.num_jobs(), "remaining..."
    368 
    369     def reload(self, n, B, load=True):
    370         self.n = n
    371         self.B = B
    372         self.prestr = 'DSAGE_RESULT=enumerate_totallyreal_fields_prim(' + str(n) + ',' + str(B) + ','
    373         filename_start = str(n) + '/' + str(n) + '-' + str(B) + '-'
    374 
    375         fsock = open(filename_start + 'reload.dat', 'r')
    376         data = eval(fsock.read())
    377         A = data[0]
    378         self.S = data[1]
    379         for i in range(len(self.S)):
    380             self.S[i][1] = pari(self.S[i][1]).Polrev()
    381         self.counts = data[2]
    382         self.cputime = data[3]
    383         self.walltime = data[4]
    384         if load:
    385             self.load_jobs(A)
    386         else:
    387             self.jobs = [[a,''] for a in A]
    388 
    389     def wait_split_save(self):
    390         while True:
    391             time.sleep(self.timeout)
    392             self.compile_fields()
    393             self.split_all_jobs()
    394 
    395     def num_jobs(self):
    396         return len(self.jobs)
  • sage/rings/number_field/totallyreal_rel.py

    diff -r 201d3b2a6ae9 -r ae11a4bd7bec sage/rings/number_field/totallyreal_rel.py
    a b  
    1 
    2 """
     1r"""
    32Enumeration of Totally Real Fields: Relative Extensions
    43
     4This module contains functions to enumerate primitive extensions `L / K`, where
     5`K` is a given totally real number field, with given degree and small root
     6discriminant. This is a relative analogue of the problem described in
     7:mod:`sage.rings.number_field.totallyreal`, and we use a similar approach
     8based on a relative version of Hunter's theorem.
     9
     10In this first simple example, we compute the totally real quadratic
     11fields of `F = \QQ(\sqrt{2})` of discriminant `\le 2000`.
     12
     13::
     14
     15    sage: ZZx = ZZ['x']
     16    sage: F.<t> = NumberField(x^2-2)
     17    sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
     18    [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]
     19
     20There is indeed only one such extension, given by `F(\sqrt{5})`.
     21
     22Next, we list all totally real quadratic extensions of `\QQ(\sqrt 5)`
     23with root discriminant `\le 10`.
     24
     25::
     26
     27    sage: F.<t> = NumberField(x^2-5)
     28    sage: ls = enumerate_totallyreal_fields_rel(F, 2, 10^4)
     29    sage: ls # random (the second factor is platform-dependent)
     30    [[725, x^4 - x^3 - 3*x^2 + x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1],
     31     [1125, x^4 - x^3 - 4*x^2 + 4*x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1/2*t + 3/2],
     32     [1600, x^4 - 6*x^2 + 4, xF^2 - 2],
     33     [2000, x^4 - 5*x^2 + 5, xF^2 - 1/2*t - 5/2],
     34     [2225, x^4 - x^3 - 5*x^2 + 2*x + 4, xF^2 + (-1/2*t + 1/2)*xF - 3/2*t - 7/2],
     35     [2525, x^4 - 2*x^3 - 4*x^2 + 5*x + 5, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 5/2],
     36     [3600, x^4 - 2*x^3 - 7*x^2 + 8*x + 1, xF^2 - 3],
     37     [4225, x^4 - 9*x^2 + 4, xF^2 + (-1/2*t - 1/2)*xF - 3/2*t - 9/2],
     38     [4400, x^4 - 7*x^2 + 11, xF^2 - 1/2*t - 7/2],
     39     [4525, x^4 - x^3 - 7*x^2 + 3*x + 9, xF^2 + (-1/2*t - 1/2)*xF - 3],
     40     [5125, x^4 - 2*x^3 - 6*x^2 + 7*x + 11, xF^2 + (-1/2*t - 1/2)*xF - t - 4],
     41     [5225, x^4 - x^3 - 8*x^2 + x + 11, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 7/2],
     42     [5725, x^4 - x^3 - 8*x^2 + 6*x + 11, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 7/2],
     43     [6125, x^4 - x^3 - 9*x^2 + 9*x + 11, xF^2 + (-1/2*t + 1/2)*xF - t - 4],
     44     [7225, x^4 - 11*x^2 + 9, xF^2 + (-1)*xF - 4],
     45     [7600, x^4 - 9*x^2 + 19, xF^2 - 1/2*t - 9/2],
     46     [7625, x^4 - x^3 - 9*x^2 + 4*x + 16, xF^2 + (-1/2*t - 1/2)*xF - 4],
     47     [8000, x^4 - 10*x^2 + 20, xF^2 - t - 5],
     48     [8525, x^4 - 2*x^3 - 8*x^2 + 9*x + 19, xF^2 + (-1)*xF - 1/2*t - 9/2],
     49     [8725, x^4 - x^3 - 10*x^2 + 2*x + 19, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 9/2],
     50     [9225, x^4 - x^3 - 10*x^2 + 7*x + 19, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 9/2]]
     51    sage: [ f[0] for f in ls ]
     52    [725, 1125, 1600, 2000, 2225, 2525, 3600, 4225, 4400, 4525, 5125, 5225, 5725, 6125, 7225, 7600, 7625, 8000, 8525, 8725, 9225]
     53     
     54    sage: [NumberField(ZZx(x[1]), 't').is_galois() for x in ls]
     55    [False, True, True, True, False, False, True, True, False, False, False, False, False, True, True, False, False, True, False, False, False]   
     56
     57Eight out of 21 such fields are Galois (with Galois group `C_4`
     58or `C_2 \times C_2`); the others have have Galois closure of degree 8
     59(with Galois group `D_8`).
     60
     61Finally, we compute the cubic extensions of `\QQ(\zeta_7)^+` with
     62discriminant `\le 17 \times 10^9`.
     63
     64::
     65
     66    sage: F.<t> = NumberField(ZZx([1,-4,3,1]))
     67    sage: F.disc()
     68    49
     69    sage: enumerate_totallyreal_fields_rel(F, 3, 17*10^9) # not tested
     70    [[16240385609L, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]]    # 32 bit
     71    [[16240385609, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]]    # 64 bit
     72
    573AUTHORS:
    6     -- John Voight (2007-11-03):
    7         * Initial version.
     74
     75- John Voight (2007-11-03): Initial version.
    876"""
    977
    1078#***********************************************************************************************
     
    43111
    44112    INPUT:
    45113
    46         - `K` -- a totally real number field
     114    - `K` -- a totally real number field
     115    - `C` -- a list [[lower, upper], ...] of lower and upper bounds,
     116      for each embedding
    47117
    48         - `C` -- a list [[lower, upper], ...] of lower and upper bounds,
    49                  for each embedding
    50118
    51 
    52     EXAMPLES:
     119    EXAMPLES::
    53120
    54121        sage: x = polygen(QQ)
    55122        sage: K.<alpha> = NumberField(x^2-2)
     
    174241        Initialization routine (constructor).
    175242
    176243        INPUT:
    177         F -- number field, the base field
    178         m -- integer, the relative degree
    179         B -- integer, the discriminant bound
    180         a -- list (default: []), the coefficient list to begin with, where
    181              a[len(a)]*x^n + ... + a[0]x^(n-len(a))
     244       
     245        - ``F`` -- number field, the base field
     246        - ``m`` -- integer, the relative degree
     247        - ``B`` -- integer, the discriminant bound
     248        - ``a`` -- list (default: []), the coefficient list to begin with,
     249          corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``.
    182250
    183251        OUTPUT:
     252       
    184253        the data initialized to begin enumeration of totally real fields
    185254        with base field F, degree n, discriminant bounded by B, and starting
    186255        with coefficients a.
    187256
    188         EXAMPLES:
     257        EXAMPLES::
     258       
    189259            sage: F.<t> = NumberField(x^2-2)
    190260            sage: T = sage.rings.number_field.totallyreal_rel.tr_data_rel(F, 2, 2000)
    191261        """
     
    295365        polynomial.
    296366 
    297367        INPUT:
    298             f_out -- an integer sequence, to be written with the
    299                      coefficients of the next polynomial
    300             verbose -- boolean to print verbosely computational details
    301             haltk -- integer, the level at which to halt the inductive
    302                      coefficient bounds
     368       
     369        - ``f_out`` -- an integer sequence, to be written with the
     370          coefficients of the next polynomial
     371        - ``verbose`` -- boolean to print verbosely computational details
     372        - ``haltk`` -- integer, the level at which to halt the inductive
     373          coefficient bounds
    303374
    304375        OUTPUT:
     376       
    305377        the successor polynomial as a coefficient list.
     378       
     379        EXAMPLES:
     380       
     381        As this function is heavily used internally by the various enumeration
     382        routines, there is no separate test::
     383       
     384            sage: pass # not tested
    306385        """
    307386
    308387        import numpy
     
    564643def enumerate_totallyreal_fields_rel(F, m, B, a = [], verbose=0, return_seqs=False):
    565644    r"""
    566645    This function enumerates (primitive) totally real field extensions of
    567     degree $m>1$ of the totally real field F with discriminant $d \leq B$;
    568     optionally one can specify the first few coefficients, where the sequence $a$
     646    degree `m>1` of the totally real field F with discriminant `d \leq B`;
     647    optionally one can specify the first few coefficients, where the sequence ``a``
    569648    corresponds to a polynomial by
    570         $$ a[d]*x^n + ... + a[0]*x^(n-d) $$
    571     if length(a) = d+1, so in particular always a[d] = 1.
     649   
     650    ::
     651   
     652        a[d]*x^n + ... + a[0]*x^(n-d)
     653       
     654    if ``length(a) = d+1``, so in particular always ``a[d] = 1``.
    572655    If verbose == 1 (or 2), then print to the screen (really) verbosely; if
    573656    verbose is a string, then print verbosely to the file specified by verbose.
    574657    If return_seqs, then return the polynomials as sequences (for easier
     
    579662    seems in practice to give many imprimitive ones.
    580663
    581664    INPUT:
    582     F -- number field, the base field
    583     m -- integer, the degree
    584     B -- integer, the discriminant bound
    585     a -- list (default: []), the coefficient list to begin with
    586     verbose -- boolean or string (default: 0)
    587     return_seqs -- boolean (default: False)
     665   
     666    - ``F`` -- number field, the base field
     667    - ``m`` -- integer, the degree
     668    - ``B`` -- integer, the discriminant bound
     669    - ``a`` -- list (default: []), the coefficient list to begin with
     670    - ``verbose`` -- boolean or string (default: 0)
     671    - ``return_seqs`` -- boolean (default: False)
    588672
    589673    OUTPUT:
     674   
    590675    the list of fields with entries [d,fabs,f], where
    591       d is the discriminant, fabs is an absolute defining polynomial,
    592       and f is a defining polynomial relative to F,
     676    d is the discriminant, fabs is an absolute defining polynomial,
     677    and f is a defining polynomial relative to F,
    593678    sorted by discriminant.
    594679
    595     EXAMPLES:
    596     In this first simple example, we compute the totally real quadratic
    597     fields of Q(sqrt(2)) of discriminant <= 2000.
    598 
    599     sage: ZZx = ZZ['x']
    600     sage: F.<t> = NumberField(x^2-2)
    601     sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
    602     [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]
    603 
    604     There is indeed only one such extension, given by F(sqrt(5)).
    605 
    606     Next, we list all totally real quadratic extensions of Q(sqrt(5))
    607     with root discriminant <= 10.
    608 
    609     sage: F.<t> = NumberField(x^2-5)
    610     sage: ls = enumerate_totallyreal_fields_rel(F, 2, 10^4)
    611     sage: ls # random (the second factor is platform-dependent)
    612     [[725, x^4 - x^3 - 3*x^2 + x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1],
    613      [1125, x^4 - x^3 - 4*x^2 + 4*x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1/2*t + 3/2],
    614      [1600, x^4 - 6*x^2 + 4, xF^2 - 2],
    615      [2000, x^4 - 5*x^2 + 5, xF^2 - 1/2*t - 5/2],
    616      [2225, x^4 - x^3 - 5*x^2 + 2*x + 4, xF^2 + (-1/2*t + 1/2)*xF - 3/2*t - 7/2],
    617      [2525, x^4 - 2*x^3 - 4*x^2 + 5*x + 5, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 5/2],
    618      [3600, x^4 - 2*x^3 - 7*x^2 + 8*x + 1, xF^2 - 3],
    619      [4225, x^4 - 9*x^2 + 4, xF^2 + (-1/2*t - 1/2)*xF - 3/2*t - 9/2],
    620      [4400, x^4 - 7*x^2 + 11, xF^2 - 1/2*t - 7/2],
    621      [4525, x^4 - x^3 - 7*x^2 + 3*x + 9, xF^2 + (-1/2*t - 1/2)*xF - 3],
    622      [5125, x^4 - 2*x^3 - 6*x^2 + 7*x + 11, xF^2 + (-1/2*t - 1/2)*xF - t - 4],
    623      [5225, x^4 - x^3 - 8*x^2 + x + 11, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 7/2],
    624      [5725, x^4 - x^3 - 8*x^2 + 6*x + 11, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 7/2],
    625      [6125, x^4 - x^3 - 9*x^2 + 9*x + 11, xF^2 + (-1/2*t + 1/2)*xF - t - 4],
    626      [7225, x^4 - 11*x^2 + 9, xF^2 + (-1)*xF - 4],
    627      [7600, x^4 - 9*x^2 + 19, xF^2 - 1/2*t - 9/2],
    628      [7625, x^4 - x^3 - 9*x^2 + 4*x + 16, xF^2 + (-1/2*t - 1/2)*xF - 4],
    629      [8000, x^4 - 10*x^2 + 20, xF^2 - t - 5],
    630      [8525, x^4 - 2*x^3 - 8*x^2 + 9*x + 19, xF^2 + (-1)*xF - 1/2*t - 9/2],
    631      [8725, x^4 - x^3 - 10*x^2 + 2*x + 19, xF^2 + (-1/2*t - 1/2)*xF - 1/2*t - 9/2],
    632      [9225, x^4 - x^3 - 10*x^2 + 7*x + 19, xF^2 + (-1/2*t + 1/2)*xF - 1/2*t - 9/2]]
    633     sage: [ f[0] for f in ls ]
    634     [725, 1125, 1600, 2000, 2225, 2525, 3600, 4225, 4400, 4525, 5125, 5225, 5725, 6125, 7225, 7600, 7625, 8000, 8525, 8725, 9225]
    635      
    636     sage: [NumberField(ZZx(x[1]), 't').is_galois() for x in ls]
    637     [False, True, True, True, False, False, True, True, False, False, False, False, False, True, True, False, False, True, False, False, False]   
    638 
    639     Eight out of 21 such fields are Galois (with Galois group Z/4Z
    640     or Z/2Z + Z/2Z); the others have have Galois closure of degree 8
    641     (with Galois group D_8).
    642 
    643     Finally, we compute the cubic extensions of Q(zeta_7)^+ with
    644     discriminant <= 17*10^9.
    645 
    646     sage: F.<t> = NumberField(ZZx([1,-4,3,1]))
    647     sage: F.disc()
    648     49
    649     sage: enumerate_totallyreal_fields_rel(F, 3, 17*10^9) # not tested
    650     [[16240385609L, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]]    # 32 bit
    651     [[16240385609, x^9 - x^8 - 9*x^7 + 4*x^6 + 26*x^5 - 2*x^4 - 25*x^3 - x^2 + 7*x + 1, xF^3 + (-t^2 - 4*t + 1)*xF^2 + (t^2 + 3*t - 5)*xF + 3*t^2 + 11*t - 5]]    # 64 bit
    652 
    653     NOTES:
    654     We enumerate polynomials
    655         f(x) = x^n + a[n-1]*x^(n-1) + ... + a[0].
    656     A relative Hunter's theorem gives bounds on a[n-1] and a[n-2];
    657     then given a[n-1] and a[n-2], one can recursively compute bounds on
    658     a[n-3], ..., a[0] using the fact that the polynomial is totally real
    659     by looking at the zeros of successive derivatives and applying
    660     Rolle's theorem!
    661 
    662     See references in totallyreal.py.
     680    EXAMPLES::
     681   
     682        sage: ZZx = ZZ['x']
     683        sage: F.<t> = NumberField(x^2-2)
     684        sage: enumerate_totallyreal_fields_rel(F, 2, 2000)
     685        [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]]
    663686
    664687    AUTHORS:
     688   
    665689    - John Voight (2007-11-01)
    666690    """
    667691
     
    805829            K = F.extension(Fx([-1,6,-5,1]), 'tK')
    806830            Kabs = K.absolute_field('tKabs')
    807831            Kabs_pari = pari(Kabs.defining_polynomial())
    808             d = K.disc()
     832            d = K.absolute_discriminant()
    809833            if abs(d) <= B:
    810834                ng = Kabs_pari.polredabs()
    811835                ind = bisect.bisect_left(S, [d,ng])
     
    835859   
    836860def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False):
    837861    r"""
    838     Enumerates all totally real fields of degree n with discriminant <= B.
    839     See enumerate_totallyreal_fields_prim() for examples.
     862    Enumerates *all* totally real fields of degree `n` with discriminant `\le B`,
     863    primitive or otherwise.
     864   
     865    EXAMPLES::
     866   
     867        sage: enumerate_totallyreal_fields_all(4, 2000)
     868        [[725, x^4 - x^3 - 3*x^2 + x + 1],
     869        [1125, x^4 - x^3 - 4*x^2 + 4*x + 1],
     870        [1600, x^4 - 6*x^2 + 4],
     871        [1957, x^4 - 4*x^2 - x + 1],
     872        [2000, x^4 - 5*x^2 + 5]]
     873   
     874    In practice most of these will be found by :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim`, which is guaranteed to return all primitive fields but often returns many non-primitive ones as well. For instance, only one of the five fields in the example above is primitive, but :func:`~sage.rings.number_field.totallyreal.enumerate_totallyreal_fields_prim` finds four out of the five (the exception being `x^4 - 6x^2 + 4`).
    840875    """
    841876
    842877    S = []