Ticket #10677: 10677_pari_rnf.patch
File 10677_pari_rnf.patch, 26.4 KB (added by , 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 415 415 void checkrnf(GEN rnf) 416 416 GEN galoisapply(GEN nf, GEN aut, GEN x) 417 417 GEN polgalois(GEN x, long prec) 418 GEN get_bnf(GEN x, int*t)418 GEN get_bnf(GEN x, long *t) 419 419 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) 421 421 GEN get_nfpol(GEN x, GEN *nf) 422 422 GEN glambdak(GEN nfz, GEN s, long prec) 423 423 GEN gsmith(GEN x) … … 695 695 696 696 # buch4.c 697 697 698 GEN bnfisnorm(GEN bnf, GEN x,long flag,long PREC)698 GEN bnfisnorm(GEN bnf, GEN x, long flag) 699 699 GEN rnfisnorm(GEN S, GEN x, long flag) 700 GEN rnfisnorminit(GEN T, GEN relpol, int galois) 700 701 GEN bnfissunit(GEN bnf,GEN suni,GEN x) 701 702 GEN bnfsunit(GEN bnf,GEN s,long PREC) 702 703 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 12 12 cdef gen new_gen_noclear(self, GEN x) 13 13 cdef gen pari(self, object x) 14 14 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 16 17 17 18 cimport sage.structure.parent_base 18 19 … … 34 35 cdef GEN deepcopy_to_python_heap(self, GEN x, pari_sp* address) 35 36 cdef gen new_ref(self, GEN g, gen parent) 36 37 cdef gen _empty_vector(self, long n) 37 cdef intget_var(self, v)38 cdef long get_var(self, v) 38 39 cdef GEN toGEN(self, x, int i) except NULL 39 40 cdef GEN integer_matrix_GEN(self, mpz_t** B, Py_ssize_t nr, Py_ssize_t nc) except <GEN>0 40 41 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 597 597 sig_on() 598 598 return P.new_gen(gaddsg(1, self.g)) 599 599 600 def _mod(gen self, gen other):601 sig_on()602 return P.new_gen(gmod(self.g, other.g))603 604 600 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)) 607 608 return sage.structure.element.bin_op(self, other, operator.mod) 608 609 609 610 def __pow__(self, n, m): … … 643 644 t0GEN(str(self) + '.' + str(attr)) 644 645 sig_on() 645 646 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 647 748 def nf_get_diff(self): 648 749 """ 649 750 Returns the different of this number field as a PARI ideal. 650 751 752 INPUT: 753 754 - ``self`` -- A PARI number field being the output of ``nfinit()``, 755 ``bnfinit()`` or ``bnrinit()``. 756 651 757 EXAMPLES:: 652 758 653 759 sage: K.<a> = NumberField(x^4 - 4*x^2 + 1) 654 760 sage: pari(K).nf_get_diff() 655 761 [12, 0, 0, 0; 0, 12, 8, 0; 0, 0, 4, 0; 0, 0, 0, 4] 656 762 """ 763 cdef GEN nf = self.get_nf() 657 764 sig_on() 658 765 # 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)) 660 767 661 768 def nf_get_sign(self): 662 769 """ … … 664 771 Python ints representing the number of real embeddings and pairs 665 772 of complex embeddings of this number field, respectively. 666 773 774 INPUT: 775 776 - ``self`` -- A PARI number field being the output of ``nfinit()``, 777 ``bnfinit()`` or ``bnrinit()``. 778 667 779 EXAMPLES:: 668 780 669 781 sage: K.<a> = NumberField(x^4 - 4*x^2 + 1) … … 677 789 """ 678 790 cdef long r1 679 791 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) 683 794 return [r1, r2] 684 795 685 796 def nf_get_zk(self): … … 687 798 Returns a vector with a `\ZZ`-basis for the ring of integers of 688 799 this number field. The first element is always `1`. 689 800 801 INPUT: 802 803 - ``self`` -- A PARI number field being the output of ``nfinit()``, 804 ``bnfinit()`` or ``bnrinit()``. 805 690 806 EXAMPLES:: 691 807 692 808 sage: K.<a> = NumberField(x^4 - 4*x^2 + 1) 693 809 sage: pari(K).nf_get_zk() 694 810 [1, x, x^3 - 4*x, x^2 - 2] 695 811 """ 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)) 698 815 699 816 def bnf_get_cyc(self): 700 817 """ … … 6554 6671 sig_on() 6555 6672 return self.new_gen(bnfisintnorm(self.g, t0)) 6556 6673 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 6557 6679 def bnfisprincipal(self, x, long flag=1): 6558 6680 t0GEN(x) 6559 6681 sig_on() … … 7206 7328 def rnfeltabstorel(self, x): 7207 7329 t0GEN(x) 7208 7330 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)) 7211 7332 7212 7333 def rnfeltreltoabs(self, x): 7213 7334 t0GEN(x) … … 7626 7747 return self.new_gen(thueinit(self.g, flag, prec)) 7627 7748 7628 7749 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)) 7631 7759 7632 7760 ########################################### 7633 7761 # 8: Vectors, matrices, LINEAR ALGEBRA and sets … … 8162 8290 8163 8291 def nextprime(gen self, bint add_one=0): 8164 8292 """ 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`. 8166 8296 8167 8297 EXAMPLES:: 8168 8298 8169 8299 sage: pari(1).nextprime() 8170 8300 2 8301 sage: pari(2).nextprime() 8302 2 8303 sage: pari(2).nextprime(add_one = 1) 8304 3 8171 8305 sage: pari(2^100).nextprime() 8172 8306 1267650600228229401496703205653 8173 8307 """ 8308 sig_on() 8174 8309 if add_one: 8175 sig_on()8176 8310 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()8179 8311 return P.new_gen(gnextprime(self.g)) 8180 8312 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 8183 8317 EXAMPLES:: 8184 8318 8185 8319 sage: x = pari("x"); y = pari("y") … … 8198 8332 xyz^6 + 34*xyz^4 + 6*xyz^3 + 289*xyz^2 + 102*xyz + 9 8199 8333 """ 8200 8334 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() 8204 8338 return P.new_gen(gsubst(self.g, n, t0)) 8205 8339 8206 8340 def substpol(self, y, z): … … 8209 8343 sig_on() 8210 8344 return self.new_gen(gsubstpol(self.g, t0, t1)) 8211 8345 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 8212 8388 def taylor(self, v=-1): 8213 8389 sig_on() 8214 8390 return self.new_gen(tayl(self.g, self.get_var(v), precdl)) … … 8519 8695 8520 8696 def debug(gen self, long depth = -1): 8521 8697 r""" 8522 Show the internal structure of self (like \xin gp).8698 Show the internal structure of self (like the ``\x`` command in gp). 8523 8699 8524 8700 EXAMPLE:: 8525 8701 … … 8554 8730 cdef GEN _deepcopy_to_python_heap(self, GEN x, pari_sp* address): 8555 8731 return P.deepcopy_to_python_heap(x, address) 8556 8732 8557 cdef intget_var(self, v):8733 cdef long get_var(self, v): 8558 8734 return P.get_var(v) 8559 8735 8560 8736 … … 9198 9374 9199 9375 9200 9376 9201 cdef intget_var(self, v):9377 cdef long get_var(self, v): 9202 9378 """ 9203 9379 Converts a Python string into a PARI variable reference number. Or 9204 9380 if v = -1, returns -1. -
sage/rings/number_field/maps.py
diff -r 3b2a754c812c -r 18b156825c52 sage/rings/number_field/maps.py
a b 377 377 # internally by an absolute polynomial over QQ. 378 378 alpha = self.__K(alpha) 379 379 380 # Pari doesn't return a valid relative polynomial from an381 # absolute one in the case of relative degree one, so we work382 # around it. (Bug submitted to Pari, fixed in svn unstable as383 # of 1/22/08 according to Karim Belabas. Trac #1891 is a384 # reminder to remove this workaround once we update Pari in385 # Sage.)386 if self.__K.relative_degree() == 1:387 # Let K/F be our relative extension, let z be the absolute388 # polynomial for K (which *need not* be the absolute389 # polynomial for F!), and let pol be the relative390 # polynomial for K/F. Then self.__rnf[10] returns a triple391 # z, a, k, where z is as above, a is a polynomial392 # representing the absolute generator gamma of F as a393 # polynomial in a root of z, and k is an integer394 # satisfying395 # theta = beta + k*gamma396 # 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 as399 # a polynomial in theta. However, we need a polynomial g400 # representing alpha in terms of gamma, so we simply use401 # the relation above to write theta as a polynomial in402 # gamma, and then we can simply evaluate f at that403 # polynomial, and this is our g. The code below does404 # exactly this -- all the business with subst and405 # self.__x, self.__y is there to deal with Pari's406 # frustrating representation of relative number fields and407 # "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.__y413 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 416 380 # f is the absolute polynomial that defines this number field 417 381 # element 418 382 f = alpha.polynomial('x') 419 g = self.__rnf.rnfeltabstorel(pari(f)) 383 g = self.__rnf.rnfeltabstorel(pari(f)).lift().lift() 420 384 # Now g is a relative polynomial that defines this element. 421 385 # This g is a polynomial in a pari variable x with 422 386 # 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 76 76 sage: beta^10 77 77 27*beta0 78 78 """ 79 80 79 #***************************************************************************** 81 80 # Copyright (C) 2004, 2005, 2006, 2007 William Stein <wstein@gmail.com> 82 81 # 83 82 # 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. 92 85 # http://www.gnu.org/licenses/ 93 86 #***************************************************************************** 94 87 … … 3605 3598 - ``type`` - ``none``, ``gap``, or ``pari``. If None (the default), 3606 3599 return an explicit group of automorphisms of self as a 3607 3600 ``GaloisGroup_v2`` object. Otherwise, return a ``GaloisGroup_v1`` 3608 wrapper object based on a P arior Gap transitive group object, which3601 wrapper object based on a PARI or Gap transitive group object, which 3609 3602 is quicker to compute, but rather less useful (in particular, it 3610 3603 can't be made to act on self). If type = 'gap', the database_gap 3611 3604 package should be installed. … … 3884 3877 .. note:: 3885 3878 3886 3879 In the non-totally-real case, the LLL routine we call is 3887 currently P ari's qflll(), which works with floating point3880 currently PARI's qflll(), which works with floating point 3888 3881 approximations, and so the result is only as good as the 3889 precision promised by P ari. The matrix returned will always3882 precision promised by PARI. The matrix returned will always 3890 3883 be integral; however, it may only be only "almost" LLL-reduced 3891 3884 when the precision is not sufficiently high. 3892 3885 … … 3963 3956 .. note:: 3964 3957 3965 3958 In the non-totally-real case, the LLL routine we call is 3966 currently P ari's qflll(), which works with floating point3959 currently PARI's qflll(), which works with floating point 3967 3960 approximations, and so the result is only as good as the 3968 precision promised by P ari. In particular, in this case,3961 precision promised by PARI. In particular, in this case, 3969 3962 the returned matrix will *not* be integral, and may not 3970 3963 have enough precision to recover the correct gram matrix 3971 3964 (which is known to be integral for theoretical … … 4554 4547 except AttributeError: 4555 4548 pass 4556 4549 4557 # get P arito compute the units4550 # get PARI to compute the units 4558 4551 B = self.pari_bnf(proof).bnfunit() 4559 4552 if proof: 4560 4553 # 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 16 16 logarithmic heights. 17 17 18 18 """ 19 20 19 #***************************************************************************** 21 20 # Copyright (C) 2004, 2007 William Stein <wstein@gmail.com> 22 21 # 23 22 # 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. 32 25 # http://www.gnu.org/licenses/ 33 26 #***************************************************************************** 34 27 … … 301 294 else: 302 295 ppr = parent.polynomial_ring() 303 296 297 cdef long i 304 298 if isinstance(f, pari_gen): 305 299 if f.type() in ["t_INT", "t_FRAC", "t_POL"]: 306 300 pass 307 301 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 308 313 f = f.lift() 309 314 else: 310 315 f = self.number_field().pari_nf().nfbasistoalg_lift(f) … … 321 326 (<Integer>ZZ(den))._to_ZZ(&self.__denominator) 322 327 323 328 num = f * den 324 cdef long i325 329 for i from 0 <= i <= num.degree(): 326 330 (<Integer>ZZ(num[i]))._to_ZZ(&coeff) 327 331 ZZX_SetCoeff( self.__numerator, i, coeff ) … … 516 520 517 521 def _pari_(self, var='x'): 518 522 r""" 519 Convert self to a P arielement.523 Convert self to a PARI element. 520 524 521 525 EXAMPLE:: 522 526 … … 1189 1193 sage: (a^4 + a^2 - 3*a + 2).sqrt() 1190 1194 a^3 - a^2 1191 1195 1192 ALGORITHM: Use Pari to factor `x^2` - ``self`` 1193 in K. 1196 ALGORITHM: Use PARI to factor `x^2` - ``self`` in `K`. 1194 1197 """ 1195 1198 # For now, use pari's factoring abilities 1196 1199 R = self.number_field()['t'] … … 1220 1223 sage: K((a-3)^5).nth_root(5) 1221 1224 a - 3 1222 1225 1223 ALGORITHM: Use Pari to factor `x^n` - ``self`` 1224 in K. 1226 ALGORITHM: Use PARI to factor `x^n` - ``self`` in `K`. 1225 1227 """ 1226 1228 R = self.number_field()['t'] 1227 1229 if not self: … … 3117 3119 this is an element of an absolute extension. 3118 3120 3119 3121 The optional argument algorithm controls how the 3120 characteristic polynomial is computed: 'pari' uses P ari,3122 characteristic polynomial is computed: 'pari' uses PARI, 3121 3123 'sage' uses charpoly for Sage matrices. The default value 3122 3124 None means that 'pari' is used for small degrees (up to the 3123 3125 value of the constant TUNE_CHARPOLY_NF, currently at 25), … … 3298 3300 sage: L.<a, b> = NumberField([x^2 + 1, x^2 + 2]) 3299 3301 sage: type(a) # indirect doctest 3300 3302 <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 3301 3324 """ 3302 3325 NumberFieldElement.__init__(self, parent, f) 3303 3326 … … 3522 3545 polynomial over `\QQ`. 3523 3546 3524 3547 The optional argument algorithm controls how the 3525 characteristic polynomial is computed: 'pari' uses P ari,3548 characteristic polynomial is computed: 'pari' uses PARI, 3526 3549 'sage' uses charpoly for Sage matrices. The default value 3527 3550 None means that 'pari' is used for small degrees (up to the 3528 3551 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 2147 2147 sage: L.<b> = K.extension(y^2 - a) 2148 2148 sage: L.lift_to_base(b^4) 2149 2149 a^2 2150 sage: L.lift_to_base(b^6) 2151 2 2152 sage: L.lift_to_base(355/113) 2153 355/113 2150 2154 sage: L.lift_to_base(b) 2151 2155 Traceback (most recent call last): 2152 2156 ... 2153 2157 ValueError: The element b is not in the base field 2154 2158 """ 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': 2158 2174 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) 2164 2176 2165 2177 def relativize(self, alpha, names): 2166 2178 r"""