Ticket #10677: 10677_pari_rnf.patch

File 10677_pari_rnf.patch, 26.4 KB (added by jdemeyer, 11 years ago)
  • sage/libs/pari/decl.pxi

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1295882808 -3600
    # Node ID 18b156825c52cf3c8bc91065194261dc7c0c8d9d
    # Parent  3b2a754c812c40ddde6d247f0148a7a91fd624f8
    #10677: Improve PARI interface for relative number fields
    
    diff -r 3b2a754c812c -r 18b156825c52 sage/libs/pari/decl.pxi
    a b  
    415415    void    checkrnf(GEN rnf)
    416416    GEN     galoisapply(GEN nf, GEN aut, GEN x)
    417417    GEN     polgalois(GEN x, long prec)
    418     GEN     get_bnf(GEN x,int *t)
     418    GEN     get_bnf(GEN x, long *t)
    419419    GEN     get_bnfpol(GEN x, GEN *bnf, GEN *nf)
    420     GEN     get_nf(GEN x,int *t)
     420    GEN     get_nf(GEN x, long *t)
    421421    GEN     get_nfpol(GEN x, GEN *nf)
    422422    GEN     glambdak(GEN nfz, GEN s, long prec)
    423423    GEN     gsmith(GEN x)
     
    695695
    696696    # buch4.c
    697697
    698     GEN     bnfisnorm(GEN bnf,GEN x,long flag,long PREC)
     698    GEN     bnfisnorm(GEN bnf, GEN x, long flag)
    699699    GEN     rnfisnorm(GEN S, GEN x, long flag)
     700    GEN     rnfisnorminit(GEN T, GEN relpol, int galois)
    700701    GEN     bnfissunit(GEN bnf,GEN suni,GEN x)
    701702    GEN     bnfsunit(GEN bnf,GEN s,long PREC)
    702703    long    nfhilbert(GEN bnf,GEN a,GEN b)
  • sage/libs/pari/gen.pxd

    diff -r 3b2a754c812c -r 18b156825c52 sage/libs/pari/gen.pxd
    a b  
    1212    cdef gen new_gen_noclear(self, GEN x)
    1313    cdef gen pari(self, object x)
    1414    cdef GEN _deepcopy_to_python_heap(self, GEN x, pari_sp* address)
    15     cdef int get_var(self, v)
     15    cdef long get_var(self, v)
     16    cdef GEN get_nf(self) except NULL
    1617
    1718cimport sage.structure.parent_base
    1819
     
    3435    cdef GEN deepcopy_to_python_heap(self, GEN x, pari_sp* address)
    3536    cdef gen new_ref(self, GEN g, gen parent)
    3637    cdef gen _empty_vector(self, long n)
    37     cdef int get_var(self, v)
     38    cdef long get_var(self, v)
    3839    cdef GEN toGEN(self, x, int i) except NULL   
    3940    cdef GEN integer_matrix_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0
    4041    cdef GEN integer_matrix_permuted_for_hnf_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0
  • sage/libs/pari/gen.pyx

    diff -r 3b2a754c812c -r 18b156825c52 sage/libs/pari/gen.pyx
    a b  
    597597        sig_on()
    598598        return P.new_gen(gaddsg(1, self.g))
    599599
    600     def _mod(gen self, gen other):
    601         sig_on()
    602         return P.new_gen(gmod(self.g, other.g))
    603 
    604600    def __mod__(self, other):
    605         if isinstance(self, gen) and isinstance(other, gen):
    606             return self._mod(other)
     601        cdef gen selfgen
     602        cdef gen othergen
     603        if isinstance(other, gen) and isinstance(self, gen):
     604            selfgen = self
     605            othergen = other
     606            sig_on()
     607            return P.new_gen(gmod(selfgen.g, othergen.g))
    607608        return sage.structure.element.bin_op(self, other, operator.mod)
    608609
    609610    def __pow__(self, n, m):
     
    643644        t0GEN(str(self) + '.' + str(attr))
    644645        sig_on()
    645646        return self.new_gen(t0)
    646    
     647
     648    def mod(self):
     649        """
     650        Given an INTMOD or POLMOD ``Mod(a,m)``, return the modulus `m`.
     651
     652        EXAMPLES::
     653
     654            sage: pari(4).Mod(5).mod()
     655            5
     656            sage: pari("Mod(x, x*y)").mod()
     657            y*x
     658            sage: pari("[Mod(4,5)]").mod()
     659            Traceback (most recent call last):
     660            ...
     661            TypeError: Not an INTMOD or POLMOD in mod()
     662        """
     663        if typ(self.g) != t_INTMOD and typ(self.g) != t_POLMOD:
     664            raise TypeError("Not an INTMOD or POLMOD in mod()")
     665        sig_on()
     666        # The hardcoded 1 below refers to the position in the internal
     667        # representation of a INTMOD or POLDMOD where the modulus is
     668        # stored.
     669        return self.new_gen(gel(self.g, 1))
     670
     671    cdef GEN get_nf(self) except NULL:
     672        """
     673        Given a PARI object `self`, convert it to a proper PARI number
     674        field (nf) structure.
     675
     676        INPUT:
     677
     678        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     679                      ``bnfinit()`` or ``bnrinit()``.
     680
     681        TESTS:
     682
     683        We test this indirectly through `nf_get_pol()`::
     684
     685            sage: x = polygen(QQ)
     686            sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
     687            sage: K.pari_nf().nf_get_pol()
     688            x^4 - 4*x^2 + 1
     689            sage: K.pari_bnf().nf_get_pol()
     690            x^4 - 4*x^2 + 1
     691            sage: bnr = pari("K = bnfinit(x^4 - 4*x^2 + 1); bnrinit(K, 2*x)")
     692            sage: bnr.nf_get_pol()
     693            x^4 - 4*x^2 + 1
     694
     695        It does not work with ``rnfinit()`` or garbage input::
     696
     697            sage: K.extension(x^2 - 5, 'b').pari_rnf().nf_get_pol()
     698            Traceback (most recent call last):
     699            ...
     700            TypeError: Not a PARI number field
     701            sage: pari("[0]").nf_get_pol()
     702            Traceback (most recent call last):
     703            ...
     704            TypeError: Not a PARI number field
     705        """
     706        cdef GEN nf
     707        cdef long nftyp
     708        sig_on()
     709        nf = get_nf(self.g, &nftyp)
     710        sig_off()
     711        if not nf:
     712            raise TypeError("Not a PARI number field")
     713        return nf
     714
     715    def nf_get_pol(self):
     716        """
     717        Returns the defining polynomial of this number field.
     718
     719        INPUT:
     720
     721        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     722                      ``bnfinit()`` or ``bnrinit()``.
     723
     724        EXAMPLES::
     725           
     726            sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
     727            sage: pari(K).nf_get_pol()
     728            x^4 - 4*x^2 + 1
     729            sage: bnr = pari("K = bnfinit(x^4 - 4*x^2 + 1); bnrinit(K, 2*x)")
     730            sage: bnr.nf_get_pol()
     731            x^4 - 4*x^2 + 1
     732
     733        For relative extensions, we can only get the absolute polynomial,
     734        not the relative one::
     735
     736            sage: L.<b> = K.extension(x^2 - 5)
     737            sage: pari(L).nf_get_pol()   # Absolute polynomial
     738            x^8 - 28*x^6 + 208*x^4 - 408*x^2 + 36
     739            sage: L.pari_rnf().nf_get_pol()
     740            Traceback (most recent call last):
     741            ...
     742            TypeError: Not a PARI number field
     743        """
     744        cdef GEN nf = self.get_nf()
     745        sig_on()
     746        return self.new_gen(nf_get_pol(nf))
     747
    647748    def nf_get_diff(self):
    648749        """
    649750        Returns the different of this number field as a PARI ideal.
    650751       
     752        INPUT:
     753
     754        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     755                      ``bnfinit()`` or ``bnrinit()``.
     756
    651757        EXAMPLES::
    652758           
    653759            sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
    654760            sage: pari(K).nf_get_diff()
    655761            [12, 0, 0, 0; 0, 12, 8, 0; 0, 0, 4, 0; 0, 0, 0, 4]
    656762        """
     763        cdef GEN nf = self.get_nf()
    657764        sig_on()
    658765        # Very bad code, but there doesn't seem to be a better way
    659         return self.new_gen(gel(gel(self.g, 5), 5))
     766        return self.new_gen(gel(gel(nf, 5), 5))
    660767
    661768    def nf_get_sign(self):
    662769        """
     
    664771        Python ints representing the number of real embeddings and pairs
    665772        of complex embeddings of this number field, respectively.
    666773       
     774        INPUT:
     775
     776        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     777                      ``bnfinit()`` or ``bnrinit()``.
     778
    667779        EXAMPLES::
    668780           
    669781            sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
     
    677789        """
    678790        cdef long r1
    679791        cdef long r2
    680         sig_on()
    681         nf_get_sign(self.g, &r1, &r2)
    682         sig_off()
     792        cdef GEN nf = self.get_nf()
     793        nf_get_sign(nf, &r1, &r2)
    683794        return [r1, r2]
    684795
    685796    def nf_get_zk(self):
     
    687798        Returns a vector with a `\ZZ`-basis for the ring of integers of
    688799        this number field. The first element is always `1`.
    689800       
     801        INPUT:
     802
     803        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     804                      ``bnfinit()`` or ``bnrinit()``.
     805
    690806        EXAMPLES::
    691807           
    692808            sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
    693809            sage: pari(K).nf_get_zk()
    694810            [1, x, x^3 - 4*x, x^2 - 2]
    695811        """
    696         sig_on()
    697         return self.new_gen(nf_get_zk(self.g))
     812        cdef GEN nf = self.get_nf()
     813        sig_on()
     814        return self.new_gen(nf_get_zk(nf))
    698815
    699816    def bnf_get_cyc(self):
    700817        """
     
    65546671        sig_on()
    65556672        return self.new_gen(bnfisintnorm(self.g, t0))
    65566673
     6674    def bnfisnorm(self, x, long flag=0):
     6675        t0GEN(x)
     6676        sig_on()
     6677        return self.new_gen(bnfisnorm(t0, self.g, flag))
     6678
    65576679    def bnfisprincipal(self, x, long flag=1):
    65586680        t0GEN(x)
    65596681        sig_on()
     
    72067328    def rnfeltabstorel(self, x):
    72077329        t0GEN(x)
    72087330        sig_on()
    7209         polymodmod = self.new_gen(rnfelementabstorel(self.g, t0))
    7210         return polymodmod.centerlift().centerlift()
     7331        return self.new_gen(rnfelementabstorel(self.g, t0))
    72117332
    72127333    def rnfeltreltoabs(self, x):
    72137334        t0GEN(x)
     
    76267747        return self.new_gen(thueinit(self.g, flag, prec))
    76277748
    76287749
    7629 
    7630    
     7750    def rnfisnorminit(self, polrel, long flag=2):
     7751        t0GEN(polrel)
     7752        sig_on()
     7753        return self.new_gen(rnfisnorminit(self.g, t0, flag))
     7754
     7755    def rnfisnorm(self, T, long flag=0):
     7756        t0GEN(T)
     7757        sig_on()
     7758        return self.new_gen(rnfisnorm(t0, self.g, flag))
    76317759
    76327760    ###########################################
    76337761    # 8: Vectors, matrices, LINEAR ALGEBRA and sets
     
    81628290   
    81638291    def nextprime(gen self, bint add_one=0):
    81648292        """
    8165         nextprime(x): smallest pseudoprime = x
     8293        nextprime(x): smallest pseudoprime greater than or equal to `x`.
     8294        If ``add_one`` is non-zero, return the smallest pseudoprime
     8295        strictly greater than `x`.
    81668296       
    81678297        EXAMPLES::
    81688298       
    81698299            sage: pari(1).nextprime()
    81708300            2
     8301            sage: pari(2).nextprime()
     8302            2
     8303            sage: pari(2).nextprime(add_one = 1)
     8304            3
    81718305            sage: pari(2^100).nextprime()
    81728306            1267650600228229401496703205653
    81738307        """
     8308        sig_on()       
    81748309        if add_one:
    8175             sig_on()       
    81768310            return P.new_gen(gnextprime(gaddsg(1,self.g)))
    8177         #NOTE: This is much faster than MAGMA's NextPrime with Proof := False.
    8178         sig_on()       
    81798311        return P.new_gen(gnextprime(self.g))
    81808312
    8181     def subst(self, var, y):
    8182         """
     8313    def subst(self, var, z):
     8314        """
     8315        In ``self``, replace the variable ``var`` by the expression `z`.
     8316
    81838317        EXAMPLES::
    81848318       
    81858319            sage: x = pari("x"); y = pari("y")
     
    81988332            xyz^6 + 34*xyz^4 + 6*xyz^3 + 289*xyz^2 + 102*xyz + 9
    81998333        """
    82008334        cdef long n
    8201         n = P.get_var(var)       
    8202         t0GEN(y)
    8203         sig_on()       
     8335        n = P.get_var(var)
     8336        t0GEN(z)
     8337        sig_on()
    82048338        return P.new_gen(gsubst(self.g, n, t0))
    82058339
    82068340    def substpol(self, y, z):
     
    82098343        sig_on()
    82108344        return self.new_gen(gsubstpol(self.g, t0, t1))
    82118345
     8346    def nf_subst(self, z):
     8347        """
     8348        Given a PARI number field ``self``, return the same PARI
     8349        number field but in the variable ``z``.
     8350
     8351        INPUT:
     8352
     8353        - ``self`` -- A PARI number field being the output of ``nfinit()``,
     8354                      ``bnfinit()`` or ``bnrinit()``.
     8355
     8356        EXAMPLES::
     8357
     8358            sage: x = polygen(QQ)
     8359            sage: K = NumberField(x^2 + 5, 'a')
     8360
     8361        We can substitute in a PARI ``nf`` structure::
     8362
     8363            sage: Kpari = K.pari_nf()
     8364            sage: Kpari.nf_get_pol()
     8365            x^2 + 5
     8366            sage: Lpari = Kpari.nf_subst('a')
     8367            sage: Lpari.nf_get_pol()
     8368            a^2 + 5
     8369
     8370        We can also substitute in a PARI ``bnf`` structure::
     8371
     8372            sage: Kpari = K.pari_bnf()
     8373            sage: Kpari.nf_get_pol()
     8374            x^2 + 5
     8375            sage: Kpari.bnf_get_cyc()  # Structure of class group
     8376            [2]
     8377            sage: Lpari = Kpari.nf_subst('a')
     8378            sage: Lpari.nf_get_pol()
     8379            a^2 + 5
     8380            sage: Lpari.bnf_get_cyc()  # We still have a bnf after substituting
     8381            [2]
     8382        """
     8383        cdef GEN nf = self.get_nf()
     8384        t0GEN(z)
     8385        sig_on()
     8386        return P.new_gen(gsubst(self.g, nf_get_varn(nf), t0))
     8387
    82128388    def taylor(self, v=-1):
    82138389        sig_on()
    82148390        return self.new_gen(tayl(self.g, self.get_var(v), precdl))
     
    85198695
    85208696    def debug(gen self, long depth = -1):
    85218697        r"""
    8522         Show the internal structure of self (like \x in gp).
     8698        Show the internal structure of self (like the ``\x`` command in gp).
    85238699
    85248700        EXAMPLE::
    85258701
     
    85548730    cdef GEN _deepcopy_to_python_heap(self, GEN x, pari_sp* address):
    85558731        return P.deepcopy_to_python_heap(x, address)
    85568732
    8557     cdef int get_var(self, v):
     8733    cdef long get_var(self, v):
    85588734        return P.get_var(v)
    85598735
    85608736   
     
    91989374       
    91999375
    92009376
    9201     cdef int get_var(self, v):
     9377    cdef long get_var(self, v):
    92029378        """
    92039379        Converts a Python string into a PARI variable reference number. Or
    92049380        if v = -1, returns -1.
  • sage/rings/number_field/maps.py

    diff -r 3b2a754c812c -r 18b156825c52 sage/rings/number_field/maps.py
    a b  
    377377        # internally by an absolute polynomial over QQ.
    378378        alpha = self.__K(alpha)
    379379       
    380         # Pari doesn't return a valid relative polynomial from an
    381         # absolute one in the case of relative degree one, so we work
    382         # around it. (Bug submitted to Pari, fixed in svn unstable as
    383         # of 1/22/08 according to Karim Belabas. Trac #1891 is a
    384         # reminder to remove this workaround once we update Pari in
    385         # Sage.)
    386         if self.__K.relative_degree() == 1:
    387             # Let K/F be our relative extension, let z be the absolute
    388             # polynomial for K (which *need not* be the absolute
    389             # polynomial for F!), and let pol be the relative
    390             # polynomial for K/F. Then self.__rnf[10] returns a triple
    391             # z, a, k, where z is as above, a is a polynomial
    392             # representing the absolute generator gamma of F as a
    393             # polynomial in a root of z, and k is an integer
    394             # satisfying
    395             #     theta = beta + k*gamma
    396             # where theta is a root of z, and beta is a root of pol.
    397             #
    398             # Now f is a polynomial representing our element alpha as
    399             # a polynomial in theta. However, we need a polynomial g
    400             # representing alpha in terms of gamma, so we simply use
    401             # the relation above to write theta as a polynomial in
    402             # gamma, and then we can simply evaluate f at that
    403             # polynomial, and this is our g. The code below does
    404             # exactly this -- all the business with subst and
    405             # self.__x, self.__y is there to deal with Pari's
    406             # frustrating representation of relative number fields and
    407             # "variable priority."
    408             #
    409             f = alpha._pari_().lift()
    410             z, a, k = self.__rnf[10]
    411             beta = -self.__rnf[0][0] / self.__rnf[0][1]
    412             theta = beta + k*self.__y
    413             f_in_base = f.subst(self.__x, theta).lift().subst(self.__y, self.__x)
    414             return self.__V([self.__K.base_field()(f_in_base)])
    415 
    416380        # f is the absolute polynomial that defines this number field
    417381        # element
    418382        f = alpha.polynomial('x')
    419         g = self.__rnf.rnfeltabstorel(pari(f))
     383        g = self.__rnf.rnfeltabstorel(pari(f)).lift().lift()
    420384        # Now g is a relative polynomial that defines this element.
    421385        # This g is a polynomial in a pari variable x with
    422386        # coefficients polynomials in a variable y.  These
  • sage/rings/number_field/number_field.py

    diff -r 3b2a754c812c -r 18b156825c52 sage/rings/number_field/number_field.py
    a b  
    7676    sage: beta^10
    7777    27*beta0
    7878"""
    79 
    8079#*****************************************************************************
    8180#       Copyright (C) 2004, 2005, 2006, 2007 William Stein <wstein@gmail.com>
    8281#
    8382#  Distributed under the terms of the GNU General Public License (GPL)
    84 #
    85 #    This code is distributed in the hope that it will be useful,
    86 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    87 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    88 #    General Public License for more details.
    89 #
    90 #  The full text of the GPL is available at:
    91 #
     83#  as published by the Free Software Foundation; either version 2 of
     84#  the License, or (at your option) any later version.
    9285#                  http://www.gnu.org/licenses/
    9386#*****************************************************************************
    9487
     
    36053598        -  ``type`` - ``none``, ``gap``, or ``pari``. If None (the default),
    36063599           return an explicit group of automorphisms of self as a
    36073600           ``GaloisGroup_v2`` object.  Otherwise, return a ``GaloisGroup_v1``
    3608            wrapper object based on a Pari or Gap transitive group object, which
     3601           wrapper object based on a PARI or Gap transitive group object, which
    36093602           is quicker to compute, but rather less useful (in particular, it
    36103603           can't be made to act on self).  If type = 'gap', the database_gap
    36113604           package should be installed.
     
    38843877        .. note::
    38853878
    38863879           In the non-totally-real case, the LLL routine we call is
    3887            currently Pari's qflll(), which works with floating point
     3880           currently PARI's qflll(), which works with floating point
    38883881           approximations, and so the result is only as good as the
    3889            precision promised by Pari. The matrix returned will always
     3882           precision promised by PARI. The matrix returned will always
    38903883           be integral; however, it may only be only "almost" LLL-reduced
    38913884           when the precision is not sufficiently high.
    38923885       
     
    39633956        .. note::
    39643957
    39653958           In the non-totally-real case, the LLL routine we call is
    3966            currently Pari's qflll(), which works with floating point
     3959           currently PARI's qflll(), which works with floating point
    39673960           approximations, and so the result is only as good as the
    3968            precision promised by Pari. In particular, in this case,
     3961           precision promised by PARI. In particular, in this case,
    39693962           the returned matrix will *not* be integral, and may not
    39703963           have enough precision to recover the correct gram matrix
    39713964           (which is known to be integral for theoretical
     
    45544547            except AttributeError:
    45554548                pass
    45564549
    4557         # get Pari to compute the units
     4550        # get PARI to compute the units
    45584551        B = self.pari_bnf(proof).bnfunit()
    45594552        if proof:
    45604553            # cache the provable results and return them
  • sage/rings/number_field/number_field_element.pyx

    diff -r 3b2a754c812c -r 18b156825c52 sage/rings/number_field/number_field_element.pyx
    a b  
    1616  logarithmic heights.
    1717
    1818"""
    19 
    2019#*****************************************************************************
    2120#       Copyright (C) 2004, 2007 William Stein <wstein@gmail.com>
    2221#
    2322#  Distributed under the terms of the GNU General Public License (GPL)
    24 #
    25 #    This code is distributed in the hope that it will be useful,
    26 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    27 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    28 #    General Public License for more details.
    29 #
    30 #  The full text of the GPL is available at:
    31 #
     23#  as published by the Free Software Foundation; either version 2 of
     24#  the License, or (at your option) any later version.
    3225#                  http://www.gnu.org/licenses/
    3326#*****************************************************************************
    3427
     
    301294        else:
    302295            ppr = parent.polynomial_ring()
    303296
     297        cdef long i
    304298        if isinstance(f, pari_gen):
    305299            if f.type() in ["t_INT", "t_FRAC", "t_POL"]:
    306300                pass
    307301            elif f.type() == "t_POLMOD":
     302                # Check whether we are dealing with a *relative*
     303                # number field element
     304                if parent.is_relative():
     305                    # If the modulus is a polynomial with polynomial
     306                    # coefficients, then the element is relative.
     307                    fmod = f.mod()
     308                    for i from 0 <= i <= fmod.poldegree():
     309                        if fmod.polcoeff(i).type() in ["t_POL", "t_POLMOD"]:
     310                            # Convert relative element to absolute
     311                            f = parent.pari_rnf().rnfeltreltoabs(f)
     312                            break
    308313                f = f.lift()
    309314            else:
    310315                f = self.number_field().pari_nf().nfbasistoalg_lift(f)
     
    321326        (<Integer>ZZ(den))._to_ZZ(&self.__denominator)
    322327
    323328        num = f * den
    324         cdef long i
    325329        for i from 0 <= i <= num.degree():
    326330            (<Integer>ZZ(num[i]))._to_ZZ(&coeff)
    327331            ZZX_SetCoeff( self.__numerator, i, coeff )
     
    516520
    517521    def _pari_(self, var='x'):
    518522        r"""
    519         Convert self to a Pari element.
     523        Convert self to a PARI element.
    520524       
    521525        EXAMPLE::
    522526       
     
    11891193            sage: (a^4 + a^2 - 3*a + 2).sqrt()
    11901194            a^3 - a^2
    11911195       
    1192         ALGORITHM: Use Pari to factor `x^2` - ``self``
    1193         in K.
     1196        ALGORITHM: Use PARI to factor `x^2` - ``self`` in `K`.
    11941197        """
    11951198        # For now, use pari's factoring abilities
    11961199        R = self.number_field()['t']
     
    12201223            sage: K((a-3)^5).nth_root(5)
    12211224            a - 3
    12221225       
    1223         ALGORITHM: Use Pari to factor `x^n` - ``self``
    1224         in K.
     1226        ALGORITHM: Use PARI to factor `x^n` - ``self`` in `K`.
    12251227        """
    12261228        R = self.number_field()['t']
    12271229        if not self:
     
    31173119        this is an element of an absolute extension.
    31183120       
    31193121        The optional argument algorithm controls how the
    3120         characteristic polynomial is computed: 'pari' uses Pari,
     3122        characteristic polynomial is computed: 'pari' uses PARI,
    31213123        'sage' uses charpoly for Sage matrices.  The default value
    31223124        None means that 'pari' is used for small degrees (up to the
    31233125        value of the constant TUNE_CHARPOLY_NF, currently at 25),
     
    32983300            sage: L.<a, b> = NumberField([x^2 + 1, x^2 + 2])
    32993301            sage: type(a) # indirect doctest
    33003302            <type 'sage.rings.number_field.number_field_element.NumberFieldElement_relative'>
     3303
     3304        We can create relative number field elements from PARI::
     3305
     3306            sage: y = polygen(QQ)
     3307            sage: K.<a> = NumberField(y^2 + y + 1)
     3308            sage: x = polygen(K)
     3309            sage: L.<b> = NumberField(x^4 + a*x + 2)
     3310            sage: e = pari(a*b); e
     3311            Mod(-x^4 - 2, x^8 - x^5 + 4*x^4 + x^2 - 2*x + 4)
     3312            sage: L(e)  # Conversion from PARI absolute number field element
     3313            a*b
     3314            sage: e = L.pari_rnf().rnfeltabstorel(e); e
     3315            Mod(y*x, x^4 + y*x + 2)
     3316            sage: L(e)  # Conversion from PARI relative number field element
     3317            a*b
     3318
     3319        We test a relative number field element created "by hand"::
     3320
     3321            sage: e = pari("Mod(Mod(y, y^2 + y + 1)*x^2 + Mod(1, y^2 + y + 1), x^4 + y*x + 2)")
     3322            sage: L(e)
     3323            a*b^2 + 1
    33013324        """
    33023325        NumberFieldElement.__init__(self, parent, f)
    33033326
     
    35223545        polynomial over `\QQ`.
    35233546
    35243547        The optional argument algorithm controls how the
    3525         characteristic polynomial is computed: 'pari' uses Pari,
     3548        characteristic polynomial is computed: 'pari' uses PARI,
    35263549        'sage' uses charpoly for Sage matrices.  The default value
    35273550        None means that 'pari' is used for small degrees (up to the
    35283551        value of the constant TUNE_CHARPOLY_NF, currently at 25),
  • sage/rings/number_field/number_field_rel.py

    diff -r 3b2a754c812c -r 18b156825c52 sage/rings/number_field/number_field_rel.py
    a b  
    21472147            sage: L.<b> = K.extension(y^2 - a)
    21482148            sage: L.lift_to_base(b^4)
    21492149            a^2
     2150            sage: L.lift_to_base(b^6)
     2151            2
     2152            sage: L.lift_to_base(355/113)
     2153            355/113
    21502154            sage: L.lift_to_base(b)
    21512155            Traceback (most recent call last):
    21522156            ...
    21532157            ValueError: The element b is not in the base field
    21542158        """
    2155         poly_xy = self.pari_rnf().rnfeltabstorel( self(element)._pari_() )
    2156         str_poly = str(poly_xy)
    2157         if str_poly.find('x') >= 0:
     2159        polmodmod_xy = self.pari_rnf().rnfeltabstorel( self(element)._pari_() )
     2160        # polmodmod_xy is a POLMOD with POLMOD coefficients in general.
     2161        # These POLMOD coefficients represent elements of the base field K.
     2162        # We do two lifts so we get a polynomial. We need the simplify() to
     2163        # make PARI check which variables really appear in the resulting
     2164        # polynomial (otherwise we always have a polynomial in two variables
     2165        # even though not all variables actually occur).
     2166        r = polmodmod_xy.lift().lift().simplify()
     2167
     2168        # Special case: check whether the result is simply an integer or rational
     2169        if r.type() in ["t_INT", "t_FRAC"]:
     2170            return self.base_field()(r)
     2171        # Now we should have a polynomial in the variable y.
     2172        # Otherwise we're not in the base field.
     2173        if r.type() != "t_POL" or str(r.variable()) != 'y':
    21582174            raise ValueError, "The element %s is not in the base field"%element
    2159         # We convert to a string to avoid some serious nastiness with
    2160         # PARI polynomials secretely thinkining they are in more variables
    2161         # than they are.
    2162         f = QQ['y'](str_poly)
    2163         return self.base_field()(f.list())
     2175        return self.base_field()(r)
    21642176
    21652177    def relativize(self, alpha, names):
    21662178        r"""