diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 4cff85207e2..456007de9e3 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -1,4 +1,3 @@ -# sage_setup: distribution = sagemath-pari # sage.doctest: needs sage.libs.pari r""" Interface to the GP calculator of PARI/GP @@ -142,14 +141,18 @@ ########################################################################## import os +import sage.interfaces.abc + from sage.env import DOT_SAGE -from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement -from sage.misc.verbose import verbose from sage.interfaces.tab_completion import ExtraTabCompletion from sage.libs.pari.all import pari -import sage.rings.complex_mpfr from sage.misc.instancedoc import instancedoc -import sage.interfaces.abc +from sage.misc.lazy_import import lazy_import +from sage.misc.verbose import verbose + +lazy_import('sage.rings.cc', 'CC') + +from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement class Gp(ExtraTabCompletion, Expect): @@ -987,7 +990,7 @@ def _complex_double_(self, CDF): """ # Retrieving values from another computer algebra system is # slow anyway, right? - cc_val = self._complex_mpfr_field_(sage.rings.complex_mpfr.ComplexField()) + cc_val = self._complex_mpfr_field_(CC) return CDF(cc_val) def __len__(self): diff --git a/src/sage/libs/pari/__init__.py b/src/sage/libs/pari/__init__.py index 95b93560892..44d159ef3c1 100644 --- a/src/sage/libs/pari/__init__.py +++ b/src/sage/libs/pari/__init__.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.real_mpfr """ Interface between Sage and PARI @@ -51,6 +52,7 @@ functions). For instance, if we want to use the PARI library to compute ``sqrt(pi)`` with a precision of 100 bits:: + sage: # needs sage.symbolic sage: R = RealField(100) sage: s = R(pi); s 3.1415926535897932384626433833 diff --git a/src/sage/libs/pari/convert_gmp.pyx b/src/sage/libs/pari/convert_gmp.pyx index 4a38bd5f527..8be1dad5cb9 100644 --- a/src/sage/libs/pari/convert_gmp.pyx +++ b/src/sage/libs/pari/convert_gmp.pyx @@ -172,7 +172,7 @@ cdef Gen rational_matrix(mpq_t** B, long nr, long nc) noexcept: EXAMPLES:: - sage: matrix(QQ,2,[1..6]).__pari__() # indirect doctest + sage: matrix(QQ,2,[1..6]).__pari__() # indirect doctest # needs sage.modules [1, 2, 3; 4, 5, 6] """ sig_on() diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index 7ee32b27b28..3f21ae46ab4 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -27,16 +27,30 @@ from sage.libs.pari.convert_gmp cimport INT_to_mpz, new_gen_from_mpz_t, new_gen_ from sage.ext.stdsage cimport PY_NEW from sage.libs.gmp.mpz cimport mpz_fits_slong_p, mpz_sgn, mpz_get_ui, mpz_set, mpz_set_si, mpz_set_ui from sage.libs.gmp.mpq cimport mpq_denref, mpq_numref +from sage.misc.lazy_import import LazyImport from sage.rings.integer cimport smallInteger -from sage.rings.real_mpfr import RealField -from sage.rings.complex_mpfr import ComplexField -from sage.rings.number_field.number_field import QuadraticField -from sage.matrix.args cimport (MatrixArgs, MA_ENTRIES_SEQ_SEQ, - MA_ENTRIES_SEQ_FLAT, MA_ENTRIES_CALLABLE, - MA_ENTRIES_UNKNOWN, MA_ENTRIES_SCALAR) -from sage.rings.padics.factory import Qp from sage.rings.infinity import Infinity +try: + from sage.rings.real_mpfr import RealField + from sage.rings.complex_mpfr import ComplexField +except ImportError: + pass + +try: + from sage.rings.number_field.number_field import QuadraticField +except ImportError: + pass +else: + QQi = QuadraticField(-1, 'i') + +try: + from sage.rings.padics.factory import Qp +except ImportError: + pass + +pari_typ_to_entries_type = LazyImport('sage.libs.pari.convert_sage_matrix', 'pari_typ_to_entries_type') + cpdef gen_to_sage(Gen z, locals=None) noexcept: """ @@ -117,15 +131,15 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: 15 sage: z = pari('1.234'); z 1.234000000000000000000000000000000000000000000000000000000000000000000 - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.real_mpfr 1.234000000000000000000000000000000000000000000000000000000000000000000000000 - sage: a.parent() + sage: a.parent() # needs sage.rings.real_mpfr Real Field with 256 bits of precision sage: pari.set_real_precision(15) 70 - sage: a = gen_to_sage(pari('1.234')); a + sage: a = gen_to_sage(pari('1.234')); a # needs sage.rings.real_mpfr 1.23400000000000000 - sage: a.parent() + sage: a.parent() # needs sage.rings.real_mpfr Real Field with 64 bits of precision For complex numbers, the parent depends on the PARI type:: @@ -134,37 +148,37 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: 3 + I sage: z.type() 't_COMPLEX' - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.number_field i + 3 - sage: a.parent() + sage: a.parent() # needs sage.rings.number_field Number Field in i with defining polynomial x^2 + 1 with i = 1*I sage: z = pari('(3+I)/2'); z 3/2 + 1/2*I - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.number_field 1/2*i + 3/2 - sage: a.parent() + sage: a.parent() # needs sage.rings.number_field Number Field in i with defining polynomial x^2 + 1 with i = 1*I sage: z = pari('1.0 + 2.0*I'); z 1.00000000000000 + 2.00000000000000*I - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.real_mpfr 1.00000000000000000 + 2.00000000000000000*I - sage: a.parent() + sage: a.parent() # needs sage.rings.real_mpfr Complex Field with 64 bits of precision sage: z = pari('1 + 1.0*I'); z 1 + 1.00000000000000*I - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.real_mpfr 1.00000000000000000 + 1.00000000000000000*I - sage: a.parent() + sage: a.parent() # needs sage.rings.real_mpfr Complex Field with 64 bits of precision sage: z = pari('1.0 + 1*I'); z 1.00000000000000 + I - sage: a = gen_to_sage(z); a + sage: a = gen_to_sage(z); a # needs sage.rings.real_mpfr 1.00000000000000000 + 1.00000000000000000*I - sage: a.parent() + sage: a.parent() # needs sage.rings.real_mpfr Complex Field with 64 bits of precision Converting polynomials:: @@ -179,6 +193,7 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: sage: parent(gen_to_sage(f, {'x': x, 'y': y})) Multivariate Polynomial Ring in x, y over Rational Field + sage: # needs sage.symbolic sage: x,y = SR.var('x,y') sage: gen_to_sage(f, {'x': x, 'y': y}) 2/3*x^3 + x + y - 5/7 @@ -192,6 +207,7 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: Converting vectors:: + sage: # needs sage.rings.number_field sage.rings.real_mpfr sage: z1 = pari('[-3, 2.1, 1+I]'); z1 [-3, 2.10000000000000, 1 + I] sage: z2 = pari('[1.0*I, [1,2]]~'); z2 @@ -224,6 +240,8 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: sage: z = pari('[1,2;3,4]') sage: z.type() 't_MAT' + + sage: # needs sage.modules sage: a = gen_to_sage(z); a [1 2] [3 4] @@ -232,6 +250,7 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: Conversion of p-adics:: + sage: # needs sage.rings.padics sage: z = pari('569 + O(7^8)'); z 2 + 4*7 + 4*7^2 + 7^3 + O(7^8) sage: a = gen_to_sage(z); a @@ -294,20 +313,14 @@ cpdef gen_to_sage(Gen z, locals=None) noexcept: C = ComplexField(sage_prec) return C(R(real), R(imag)) else: - K = QuadraticField(-1, 'i') - return K([gen_to_sage(real), gen_to_sage(imag)]) + return QQi([gen_to_sage(real), gen_to_sage(imag)]) elif t == t_VEC or t == t_COL: return [gen_to_sage(x, locals) for x in z.python_list()] elif t == t_VECSMALL: return z.python_list_small() elif t == t_MAT: - nc = lg(g) - 1 - nr = 0 if nc == 0 else lg(gel(g,1)) - 1 - ma = MatrixArgs.__new__(MatrixArgs) - ma.nrows = nr - ma.ncols = nc - ma.entries = [gen_to_sage(z[i,j], locals) for i in range(nr) for j in range(nc)] - return ma.matrix() + from .convert_sage_matrix import gen_to_sage_matrix + return gen_to_sage_matrix(z, locals) elif t == t_PADIC: p = z.padicprime() K = Qp(Integer(p), precp(g)) @@ -330,7 +343,7 @@ cpdef set_integer_from_gen(Integer self, Gen x) noexcept: r""" EXAMPLES:: - sage: [Integer(pari(x)) for x in [1, 2^60, 2., GF(3)(1), GF(9,'a')(2)]] + sage: [Integer(pari(x)) for x in [1, 2^60, 2., GF(3)(1), GF(9,'a')(2)]] # needs sage.rings.finite_rings [1, 1152921504606846976, 2, 1, 2] sage: Integer(pari(2.1)) # indirect doctest Traceback (most recent call last): @@ -390,7 +403,7 @@ cpdef set_rational_from_gen(Rational self, Gen x) noexcept: r""" EXAMPLES:: - sage: [Rational(pari(x)) for x in [1, 1/2, 2^60, 2., GF(3)(1), GF(9,'a')(2)]] + sage: [Rational(pari(x)) for x in [1, 1/2, 2^60, 2., GF(3)(1), GF(9,'a')(2)]] # needs sage.rings.finite_rings [1, 1/2, 1152921504606846976, 2, 1, 2] sage: Rational(pari(2.1)) # indirect doctest Traceback (most recent call last): @@ -576,83 +589,3 @@ cpdef list pari_prime_range(long c_start, long c_stop, bint py_ints=False) noexc res.append(z) NEXT_PRIME_VIADIFF(p, pari_prime_ptr) return res - - -def pari_typ_to_entries_type(MatrixArgs self): - """ - Determine the ``entries_type`` of a :class:`sage.matrix.args.MatrixArgs` - with PARI entries. - - This will modify the entries. - - TESTS: - - ``MA_ENTRIES_SEQ_SEQ``:: - - sage: from sage.libs.pari.convert_sage import pari_typ_to_entries_type - sage: from sage.matrix.args import MatrixArgs - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")) - sage: 0x10_03 == pari_typ_to_entries_type(ma) - True - - ``MA_ENTRIES_SEQ_FLAT``:: - - sage: ma = MatrixArgs(QQ, entries=pari("[1,2]")) - sage: 0x10_04 == pari_typ_to_entries_type(ma) - True - sage: ma = MatrixArgs(QQ, entries=pari(vector([1,2]))) - sage: 0x10_04 == pari_typ_to_entries_type(ma) - True - sage: ma = MatrixArgs(QQ, entries=pari(matrix(2, range(4))[0])) - sage: 0x10_04 == pari_typ_to_entries_type(ma) - True - - ``MA_ENTRIES_CALLABLE``:: - - sage: ma = MatrixArgs(QQ, entries=pari(lambda x: x)) - sage: 0x13_06 == pari_typ_to_entries_type(ma) - True - - ``MA_ENTRIES_SCALAR``:: - - sage: ma = MatrixArgs(QQ, entries=pari(1/2)) - sage: 0x17_02 == pari_typ_to_entries_type(ma) - True - - ``MA_ENTRIES_UNKNOWN``:: - - sage: ma = MatrixArgs(QQ, entries=pari('"2"')) - sage: 0 == pari_typ_to_entries_type(ma) - True - - A second call gives an error:: - - sage: ma = MatrixArgs(QQ, entries=pari("[1,2]")) - sage: 0x10_04 == pari_typ_to_entries_type(ma) - True - sage: 0x10_04 == pari_typ_to_entries_type(ma) - Traceback (most recent call last): - ... - ValueError: entries are not a PARI generator - """ - if not isinstance(self.entries, Gen): - raise ValueError("entries are not a PARI generator") - cdef long t = typ((self.entries).g) - if t == t_MAT: - R = self.base - if R is None: - self.entries = self.entries.Col().sage() - else: - self.entries = [[R(x) for x in v] - for v in self.entries.mattranspose()] - return MA_ENTRIES_SEQ_SEQ - elif t in [t_VEC, t_COL, t_VECSMALL, t_LIST]: - self.entries = self.entries.sage() - return MA_ENTRIES_SEQ_FLAT - elif t == t_CLOSURE: - return MA_ENTRIES_CALLABLE - elif t == t_STR: - return MA_ENTRIES_UNKNOWN - else: - self.entries = self.entries.sage() - return MA_ENTRIES_SCALAR diff --git a/src/sage/libs/pari/convert_sage_complex_double.pyx b/src/sage/libs/pari/convert_sage_complex_double.pyx index d4022c62a0f..b97c3831c75 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pyx +++ b/src/sage/libs/pari/convert_sage_complex_double.pyx @@ -1,3 +1,5 @@ +# sage.doctest: needs sage.rings.complex_double + from cysignals.signals cimport sig_on, sig_off from sage.libs.gsl.complex cimport * @@ -25,7 +27,7 @@ cpdef ComplexDoubleElement pari_to_cdf(Gen g) noexcept: Traceback (most recent call last): ... PariError: overflow in t_REAL->double conversion - sage: CDF(pari(x^2 + 5)) + sage: CDF(pari(x^2 + 5)) # needs sage.symbolic Traceback (most recent call last): ... PariError: incorrect type in gtofp (t_POL) diff --git a/src/sage/libs/pari/convert_sage_matrix.pyx b/src/sage/libs/pari/convert_sage_matrix.pyx new file mode 100644 index 00000000000..dd14eb17abf --- /dev/null +++ b/src/sage/libs/pari/convert_sage_matrix.pyx @@ -0,0 +1,105 @@ +# sage_setup: distribution = sagemath-pari +# sage.doctest: needs sage.modules + +from cypari2.gen cimport Gen +from cypari2.types cimport (GEN, typ, t_INT, t_FRAC, t_REAL, t_COMPLEX, + t_INTMOD, t_PADIC, t_INFINITY, t_VEC, t_COL, + t_VECSMALL, t_MAT, t_STR, + lg, precp) +from cypari2.paridecl cimport * + +from sage.matrix.args cimport (MatrixArgs, MA_ENTRIES_SEQ_SEQ, + MA_ENTRIES_SEQ_FLAT, MA_ENTRIES_CALLABLE, + MA_ENTRIES_UNKNOWN, MA_ENTRIES_SCALAR) + +from .convert_sage cimport gen_to_sage + +def gen_to_sage_matrix(Gen z, locals=None): + cdef GEN g = z.g + nc = lg(g) - 1 + nr = 0 if nc == 0 else lg(gel(g,1)) - 1 + ma = MatrixArgs.__new__(MatrixArgs) + ma.nrows = nr + ma.ncols = nc + ma.entries = [gen_to_sage(z[i,j], locals) for i in range(nr) for j in range(nc)] + return ma.matrix() + + +def pari_typ_to_entries_type(MatrixArgs self): + """ + Determine the ``entries_type`` of a :class:`sage.matrix.args.MatrixArgs` + with PARI entries. + + This will modify the entries. + + TESTS: + + ``MA_ENTRIES_SEQ_SEQ``:: + + sage: from sage.libs.pari.convert_sage import pari_typ_to_entries_type + sage: from sage.matrix.args import MatrixArgs + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")) + sage: 0x10_03 == pari_typ_to_entries_type(ma) + True + + ``MA_ENTRIES_SEQ_FLAT``:: + + sage: ma = MatrixArgs(QQ, entries=pari("[1,2]")) + sage: 0x10_04 == pari_typ_to_entries_type(ma) + True + sage: ma = MatrixArgs(QQ, entries=pari(vector([1,2]))) + sage: 0x10_04 == pari_typ_to_entries_type(ma) + True + sage: ma = MatrixArgs(QQ, entries=pari(matrix(2, range(4))[0])) + sage: 0x10_04 == pari_typ_to_entries_type(ma) + True + + ``MA_ENTRIES_CALLABLE``:: + + sage: ma = MatrixArgs(QQ, entries=pari(lambda x: x)) + sage: 0x13_06 == pari_typ_to_entries_type(ma) + True + + ``MA_ENTRIES_SCALAR``:: + + sage: ma = MatrixArgs(QQ, entries=pari(1/2)) + sage: 0x17_02 == pari_typ_to_entries_type(ma) + True + + ``MA_ENTRIES_UNKNOWN``:: + + sage: ma = MatrixArgs(QQ, entries=pari('"2"')) + sage: 0 == pari_typ_to_entries_type(ma) + True + + A second call gives an error:: + + sage: ma = MatrixArgs(QQ, entries=pari("[1,2]")) + sage: 0x10_04 == pari_typ_to_entries_type(ma) + True + sage: 0x10_04 == pari_typ_to_entries_type(ma) + Traceback (most recent call last): + ... + ValueError: entries are not a PARI generator + """ + if not isinstance(self.entries, Gen): + raise ValueError("entries are not a PARI generator") + cdef long t = typ((self.entries).g) + if t == t_MAT: + R = self.base + if R is None: + self.entries = self.entries.Col().sage() + else: + self.entries = [[R(x) for x in v] + for v in self.entries.mattranspose()] + return MA_ENTRIES_SEQ_SEQ + elif t in [t_VEC, t_COL, t_VECSMALL, t_LIST]: + self.entries = self.entries.sage() + return MA_ENTRIES_SEQ_FLAT + elif t == t_CLOSURE: + return MA_ENTRIES_CALLABLE + elif t == t_STR: + return MA_ENTRIES_UNKNOWN + else: + self.entries = self.entries.sage() + return MA_ENTRIES_SCALAR diff --git a/src/sage/libs/pari/convert_sage_real_mpfr.pxd b/src/sage/libs/pari/convert_sage_real_mpfr.pxd new file mode 100644 index 00000000000..a7674309255 --- /dev/null +++ b/src/sage/libs/pari/convert_sage_real_mpfr.pxd @@ -0,0 +1,6 @@ +from cypari2.gen cimport Gen + +from sage.rings.real_mpfr cimport RealNumber + +cpdef Gen new_gen_from_real_mpfr_element(RealNumber self) +cpdef bint set_real_mpfr_element_from_gen(RealNumber self, Gen x) diff --git a/src/sage/libs/pari/convert_sage_real_mpfr.pyx b/src/sage/libs/pari/convert_sage_real_mpfr.pyx new file mode 100644 index 00000000000..119944a5209 --- /dev/null +++ b/src/sage/libs/pari/convert_sage_real_mpfr.pyx @@ -0,0 +1,107 @@ +# sage.doctest: needs sage.rings.real_mpfr + +from cypari2.stack cimport new_gen +from cypari2.paridecl cimport * +from cysignals.signals cimport sig_on, sig_off + +from sage.libs.gmp.mpz cimport * +from sage.libs.mpfr cimport * +from sage.libs.mpfr.types cimport mpfr_t, mpfr_prec_t +from sage.rings.real_mpfr cimport RealField_class, RealField + + +cpdef Gen new_gen_from_real_mpfr_element(RealNumber self): + + # This uses interfaces of MPFR and PARI which are documented + # (and not marked subject-to-change). It could be faster + # by using internal interfaces of MPFR, which are documented + # as subject-to-change. + + if mpfr_nan_p(self.value) or mpfr_inf_p(self.value): + raise ValueError('cannot convert NaN or infinity to Pari float') + + # wordsize for PARI + cdef unsigned long wordsize = sizeof(long)*8 + + cdef mpfr_prec_t prec + prec = (self._parent)._prec + + # We round up the precision to the nearest multiple of wordsize. + cdef int rounded_prec + rounded_prec = (self.prec() + wordsize - 1) & ~(wordsize - 1) + + # Yes, assigning to self works fine, even in Cython. + if rounded_prec > prec: + self = RealField(rounded_prec)(self) + + cdef mpz_t mantissa + cdef mp_exp_t exponent + cdef GEN pari_float + + sig_on() + if mpfr_zero_p(self.value): + pari_float = real_0_bit(-rounded_prec) + else: + # Now we can extract the mantissa, and it will be normalized + # (the most significant bit of the most significant word will be 1). + mpz_init(mantissa) + exponent = mpfr_get_z_exp(mantissa, self.value) + + # Create a PARI REAL + pari_float = cgetr(2 + rounded_prec / wordsize) + pari_float[1] = evalexpo(exponent + rounded_prec - 1) + evalsigne(mpfr_sgn(self.value)) + mpz_export(&pari_float[2], NULL, 1, wordsize // 8, 0, 0, mantissa) + mpz_clear(mantissa) + + return new_gen(pari_float) + + +cpdef bint set_real_mpfr_element_from_gen(RealNumber self, Gen x): + r""" + EXAMPLES:: + + sage: rt2 = sqrt(pari('2.0')) + sage: rt2 + 1.41421356237310 + sage: rt2.sage() + 1.41421356237309505 + sage: rt2.sage().prec() + 64 + sage: pari(rt2.sage()) == rt2 + True + sage: for i in range(100, 200): + ....: assert(sqrt(pari(i)) == pari(sqrt(pari(i)).sage())) + sage: (-3.1415).__pari__().sage() + -3.14150000000000000 + """ + cdef GEN g = x.g + + if typ((x).g) != t_REAL: + return False + + cdef int sgn + sgn = signe(g) + + if sgn == 0: + mpfr_set_ui(self.value, 0, MPFR_RNDN) + return True + + cdef int wordsize = 8 * sizeof(long) + + cdef mpz_t mantissa + mpz_init(mantissa) + mpz_import(mantissa, lg(g) - 2, 1, wordsize/8, 0, 0, &g[2]) + + cdef mp_exp_t exponent = expo(g) + + # Round to nearest for best results when setting a low-precision + # MPFR from a high-precision GEN + mpfr_set_z(self.value, mantissa, MPFR_RNDN) + mpfr_mul_2si(self.value, self.value, exponent - wordsize * (lg(g) - 2) + 1, MPFR_RNDN) + + if sgn < 0: + mpfr_neg(self.value, self.value, MPFR_RNDN) + + mpz_clear(mantissa) + + return True diff --git a/src/sage/libs/pari/tests.py b/src/sage/libs/pari/tests.py index 97d1ec95893..5605d232d9e 100644 --- a/src/sage/libs/pari/tests.py +++ b/src/sage/libs/pari/tests.py @@ -10,17 +10,17 @@ Creating PARI objects:: - sage: pari(Matrix(2,2,range(4))) + sage: pari(Matrix(2,2,range(4))) # needs sage.modules [0, 1; 2, 3] - sage: pari(x^2-3) + sage: pari(x^2-3) # needs sage.symbolic x^2 - 3 The following example caused Sage to crash before :trac:`20630`:: sage: R. = QQ[] - sage: K. = NumberField(theta^2 + 1) - sage: K.absolute_polynomial().galois_group(pari_group=True) + sage: K. = NumberField(theta^2 + 1) # needs sage.rings.number_field + sage: K.absolute_polynomial().galois_group(pari_group=True) # needs sage.groups sage.rings.number_field PARI group [2, -1, 1, "S2"] of degree 2 Before :trac:`15654`, this used to take a very long time. @@ -28,9 +28,9 @@ sage: pari.allocatemem(200000) PARI stack size set to 200000 bytes, maximum size set to ... - sage: x = polygen(ZpFM(3,10)) - sage: pol = ((x-1)^50 + x) - sage: pari(pol).poldisc() + sage: x = polygen(ZpFM(3,10)) # needs sage.rings.padics + sage: pol = ((x-1)^50 + x) # needs sage.rings.padics + sage: pari(pol).poldisc() # needs sage.rings.padics 2*3 + 3^4 + 2*3^6 + 3^7 + 2*3^8 + 2*3^9 + O(3^10) This used to give the wrong answer before :trac:`23259`:: @@ -59,21 +59,22 @@ Number fields:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) sage: K. = NumberField(x^4 - 4*x^2 + 1) sage: pari(K).nf_get_pol() y^4 - 4*y^2 + 1 sage: L. = K.extension(x^2 - 5) - sage: pari(L).nf_get_pol() # Absolute + sage: pari(L).nf_get_pol() # Absolute y^8 - 28*y^6 + 208*y^4 - 408*y^2 + 36 - sage: L.pari_rnf().nf_get_pol() # Relative + sage: L.pari_rnf().nf_get_pol() # Relative x^2 - 5 - sage: K.pari_nf().nf_get_pol() y^4 - 4*y^2 + 1 sage: K.pari_bnf().nf_get_pol() y^4 - 4*y^2 + 1 + sage: # needs sage.rings.number_field sage: K. = QuadraticField(-65) sage: G = K.pari_bnf().bnf_get_gen(); G [[3, 2; 0, 1], [2, 1; 0, 1]] @@ -82,23 +83,23 @@ Conversions:: + sage: # needs sage.rings.number_field sage: K. = QuadraticField(-1) sage: F = pari(K).idealfactor(K.ideal(5)); F [[5, [-2, 1]~, 1, 1, [2, -1; 1, 2]], 1; [5, [2, 1]~, 1, 1, [-2, -1; 1, -2]], 1] sage: F[0,0].pr_get_p() 5 - - sage: K. = QuadraticField(-1) sage: J = pari(K).idealstar(K.ideal(4*i + 2)) sage: J.bid_get_cyc() [4, 2] - sage: int(pari(RealField(63)(2^63-1))) + sage: int(pari(RealField(63)(2^63 - 1))) # needs sage.rings.real_mpfr 9223372036854775807 # 32-bit 9223372036854775807 # 64-bit - sage: int(pari(RealField(63)(2^63+2))) + sage: int(pari(RealField(63)(2^63 + 2))) # needs sage.rings.real_mpfr 9223372036854775810 + sage: # needs sage.rings.padics sage: K = Qp(11,5) sage: x = K(11^-10 + 5*11^-7 + 11^-6) sage: y = pari(x) @@ -107,8 +108,9 @@ sage: y.padicprime().type() 't_INT' + sage: # needs sage.rings.finite_rings sage: x = polygen(GF(3)) - sage: k. = GF(9, modulus=x^2+1) + sage: k. = GF(9, modulus=x^2 + 1) sage: b = pari(a).ffprimroot() sage: b # random a + 1 @@ -125,20 +127,21 @@ Conversion from matrices and vectors is supported:: - sage: a = pari(matrix(2,3,[1,2,3,4,5,6])); a, a.type() + sage: a = pari(matrix(2,3,[1,2,3,4,5,6])); a, a.type() # needs sage.modules ([1, 2, 3; 4, 5, 6], 't_MAT') - sage: v = vector([1.2, 3.4, 5.6]) - sage: pari(v) + sage: v = vector([1.2, 3.4, 5.6]) # needs sage.modules + sage: pari(v) # needs sage.modules [1.20000000000000, 3.40000000000000, 5.60000000000000] Some more exotic examples:: + sage: # needs sage.rings.number_field sage: K. = NumberField(polygen(QQ)^3 - 2) sage: pari(K) [y^3 - 2, [1, 1], -108, 1, [[1, 1.25992104989487, 1.58740105196820; 1, -0.629960524947437 + 1.09112363597172*I, -0.793700525984100 - 1.37472963699860*I], [1, 1.25992104989487, 1.58740105196820; 1, 0.461163111024285, -2.16843016298270; 1, -1.72108416091916, 0.581029111014503], [16, 20, 25; 16, 7, -35; 16, -28, 9], [3, 0, 0; 0, 0, 6; 0, 6, 0], [6, 0, 0; 0, 6, 0; 0, 0, 3], [2, 0, 0; 0, 0, 1; 0, 1, 0], [2, [0, 0, 2; 1, 0, 0; 0, 1, 0]], [2, 3]], [1.25992104989487, -0.629960524947437 + 1.09112363597172*I], [1, y, y^2], [1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 0, 0, 0, 0, 2, 0, 2, 0; 0, 1, 0, 1, 0, 0, 0, 0, 2; 0, 0, 1, 0, 1, 0, 1, 0, 0]] - sage: E = EllipticCurve('37a1') - sage: pari(E) + sage: E = EllipticCurve('37a1') # needs sage.schemes + sage: pari(E) # needs sage.schemes [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]] Deprecation checks:: @@ -405,6 +408,8 @@ -1 sage: pari(3/4).ceil() 1 + + sage: # needs sage.symbolic sage: x = SR.symbol('x') sage: pari(x).ceil() x @@ -493,6 +498,8 @@ [1, 2, 4] sage: pari([[1.1,2.2],[3.3,4.4]]).floor() [[1, 2], [3, 4]] + + sage: # needs sage.symbolic sage: x = SR.symbol('x') sage: pari(x).floor() x @@ -500,6 +507,7 @@ x + 1 sage: pari(x^2+5*x+2.5).floor() x^2 + 5*x + 2.50000000000000 + sage: pari('"hello world"').floor() Traceback (most recent call last): ... @@ -507,7 +515,7 @@ sage: pari(1.75).frac() 0.750000000000000 - sage: pari(sqrt(2)).frac() + sage: pari(sqrt(2)).frac() # needs sage.symbolic 0.414213562373095 sage: pari('sqrt(-2)').frac() Traceback (most recent call last): @@ -516,7 +524,7 @@ sage: pari('1+2*I').imag() 2 - sage: pari(sqrt(-2)).imag() + sage: pari(sqrt(-2)).imag() # needs sage.symbolic 1.41421356237310 sage: pari('x+I').imag() 1 @@ -536,13 +544,13 @@ sage: b.lift() -17*x^2 - 3*x - sage: pari(pi).sign() + sage: pari(pi).sign() # needs sage.symbolic 1 sage: pari(0).sign() 0 sage: pari(-1/2).sign() -1 - sage: pari(SR(I)).sign() + sage: pari(SR(I)).sign() # needs sage.symbolic Traceback (most recent call last): ... PariError: incorrect type in gsigne (t_COMPLEX) @@ -705,16 +713,16 @@ 1.04719755119660 sage: pari(1.1).acos() 0.443568254385115*I - sage: C. = ComplexField() - sage: pari(1.1+i).acos() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1.1+i).acos() # needs sage.rings.real_mpfr 0.849343054245252 - 1.09770986682533*I sage: pari(2).acosh() 1.31695789692482 sage: pari(0).acosh() 1.57079632679490*I - sage: C. = ComplexField() - sage: pari(i).acosh() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(i).acosh() # needs sage.rings.real_mpfr 0.881373587019543 + 1.57079632679490*I sage: pari(2).agm(2) @@ -723,12 +731,12 @@ 0 sage: pari(1).agm(2) 1.45679103104691 - sage: C. = ComplexField() - sage: pari(1+i).agm(-3) + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).agm(-3) # needs sage.rings.real_mpfr -0.964731722290876 + 1.15700282952632*I - sage: C. = ComplexField() - sage: pari(2+i).arg() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(2+i).arg() # needs sage.rings.real_mpfr 0.463647609000806 sage: pari(pari(0.5).sin()).asin() @@ -738,14 +746,14 @@ sage: pari(2).asinh() 1.44363547517881 - sage: C. = ComplexField() - sage: pari(2+i).asinh() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(2+i).asinh() # needs sage.rings.real_mpfr 1.52857091948100 + 0.427078586392476*I sage: pari(1).atan() 0.785398163397448 - sage: C. = ComplexField() - sage: pari(1.5+i).atan() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1.5+i).atan() # needs sage.rings.real_mpfr 1.10714871779409 + 0.255412811882995*I sage: pari(0).atanh() @@ -763,6 +771,8 @@ 0.412710032209716 sage: pari(2).besseli(3) 2.24521244092995 + + sage: # needs sage.rings.real_mpfr sage: C. = ComplexField() sage: pari(2).besseli(3+i) 1.12539407613913 + 2.08313822670661*I @@ -772,37 +782,37 @@ sage: pari(1.5).cos() 0.0707372016677029 - sage: C. = ComplexField() - sage: pari(1+i).cos() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).cos() # needs sage.rings.real_mpfr 0.833730025131149 - 0.988897705762865*I sage: pari('x+O(x^8)').cos() 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 + O(x^9) sage: pari(1.5).cosh() 2.35240961524325 - sage: C. = ComplexField() - sage: pari(1+i).cosh() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).cosh() # needs sage.rings.real_mpfr 0.833730025131149 + 0.988897705762865*I sage: pari('x+O(x^8)').cosh() 1 + 1/2*x^2 + 1/24*x^4 + 1/720*x^6 + ...O(...) sage: pari(5).cotan() -0.295812915532746 - sage: x = RR(pi) + sage: x = RR(pi) # needs sage.symbolic sage: pari(x).cotan() # random -8.17674825 E15 sage: pari(1).dilog() 1.64493406684823 - sage: C. = ComplexField() - sage: pari(1+i).dilog() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).dilog() # needs sage.rings.real_mpfr 0.616850275068085 + 1.46036211675312*I sage: pari(1).erfc() 0.157299207050285 - sage: C. = ComplexField() - sage: pari(i).eta() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(i).eta() # needs sage.rings.real_mpfr 0.998129069925959 sage: pari(0).exp() @@ -816,8 +826,8 @@ 1.00000000000000 sage: pari(5).gamma() 24.0000000000000 - sage: C. = ComplexField() - sage: pari(1+i).gamma() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).gamma() # needs sage.rings.real_mpfr 0.498015668118356 - 0.154949828301811*I sage: pari(-1).gamma() Traceback (most recent call last): @@ -828,23 +838,23 @@ 1.32934038817914 sage: pari(5).gammah() 52.3427777845535 - sage: C. = ComplexField() - sage: pari(1+i).gammah() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).gammah() # needs sage.rings.real_mpfr 0.575315188063452 + 0.0882106775440939*I sage: pari(1).hyperu(2,3) 0.333333333333333 - sage: C. = ComplexField() - sage: pari(1+i).incgam(3-i) + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).incgam(3-i) # needs sage.rings.real_mpfr -0.0458297859919946 + 0.0433696818726677*I sage: pari(1).incgamc(2) 0.864664716763387 sage: pari(5).log() 1.60943791243410 - sage: C. = ComplexField() - sage: pari(i).log() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(i).log() # needs sage.rings.real_mpfr 0.E-19 + 1.57079632679490*I sage: pari(100).lngamma() @@ -857,14 +867,14 @@ sage: pari(1).sin() 0.841470984807897 - sage: C. = ComplexField() - sage: pari(1+i).sin() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).sin() # needs sage.rings.real_mpfr 1.29845758141598 + 0.634963914784736*I sage: pari(0).sinh() 0.E-19 - sage: C. = ComplexField() - sage: pari(1+i).sinh() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(1+i).sinh() # needs sage.rings.real_mpfr 0.634963914784736 + 1.29845758141598*I sage: pari(2).sqrt() @@ -877,14 +887,14 @@ sage: pari(2).tan() -2.18503986326152 - sage: C. = ComplexField() - sage: pari(i).tan() + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: pari(i).tan() # needs sage.rings.real_mpfr 0.761594155955765*I sage: pari(1).tanh() 0.761594155955765 - sage: C. = ComplexField() - sage: z = pari(i); z + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: z = pari(i); z # needs sage.rings.real_mpfr 1.00000000000000*I sage: result = z.tanh() sage: result.real() <= 1e-18 @@ -901,6 +911,7 @@ sage: pari(0.5).thetanullk(1) 0.548978532560341 + sage: # needs sage.rings.real_mpfr sage: C. = ComplexField() sage: pari(i).weber() 1.18920711500272 @@ -911,8 +922,8 @@ sage: pari(2).zeta() 1.64493406684823 - sage: x = RR(pi)^2/6 - sage: pari(x) + sage: x = RR(pi)^2/6 # needs sage.symbolic + sage: pari(x) # needs sage.symbolic 1.64493406684823 sage: pari(3).zeta() 1.20205690315959 @@ -966,6 +977,7 @@ sage: pari('[1,2,3; 4,5,6; 7,8,9]').mathnf() [6, 1; 3, 1; 0, 1] + sage: # needs sage.modules sage: M = matrix([[1,2,3],[4,5,6],[7,8,11]]) sage: d = M.det() sage: pari(M).mathnfmod(d) @@ -976,6 +988,7 @@ sage: pari(M).mathnfmod(12) [1, 0, 0; 0, 2, 0; 0, 0, 6] + sage: # needs sage.modules sage: M = matrix([[1,0,0],[0,2,0],[0,0,6]]) sage: pari(M).mathnfmodid(6) [1, 0, 0; 0, 2, 0; 0, 0, 6] @@ -1007,6 +1020,7 @@ Quadratic forms:: + sage: # needs sage.modules sage: A = Matrix(3,3,[1,2,3,2,5,5,3,5,11]) sage: A.is_positive_definite() True @@ -1029,6 +1043,7 @@ 10, 5.00000000000000000, [ 1 2 0 1 -1] ] + sage: # needs sage.modules sage: M = diagonal_matrix([1,1,-1]) sage: P = M.__pari__().qfparam([0,1,-1]); P [0, -2, 0; 1, 0, -1; -1, 0, -1] @@ -1042,6 +1057,7 @@ sage: 48^2 + 55^2 == 73^2 True + sage: # needs sage.modules sage: M = diagonal_matrix([1,2,3,4,-5]) sage: M.__pari__().qfsolve() [0, 1, -1, 0, -1]~ @@ -1087,6 +1103,7 @@ sage: pari(10).eulerphi() 4 + sage: # needs sage.symbolic sage: x = SR.symbol('x') sage: pari(10).gcd(15) 5 @@ -1153,6 +1170,7 @@ sage: pari(2003).ffinit(3) Mod(1, 2003)*x^3 + Mod(1, 2003)*x^2 + Mod(1993, 2003)*x + Mod(1995, 2003) + sage: # needs sage.rings.finite_rings sage: k. = GF(2^12) sage: g = pari(a).ffprimroot() sage: (g^1234).fflog(g) @@ -1167,6 +1185,7 @@ sage: (b^555).fflog(b, (ord, ord.factor()) ) 555 + sage: # needs sage.rings.finite_rings sage: k. = GF(5^80) sage: g = pari(a).ffprimroot() sage: g.fforder() @@ -1178,6 +1197,7 @@ p-adic functions:: + sage: # needs sage.rings.padics sage: K = Qp(11,5) sage: x = K(11^-10 + 5*11^-7 + 11^-6) sage: y = pari(x) @@ -1201,10 +1221,10 @@ [0, 1/2, 0, -3/4, 0, 2, -3/2, 0, -9/16, 40, -116, 117/4, 256000/117, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]] sage: pari([0,0.5,0,-0.75,0]).ellinit() [0, 0.500000000000000, 0, -0.750000000000000, 0, 2.00000000000000, -1.50000000000000, 0, -0.562500000000000, 40.0000000000000, -116.000000000000, 29.2500000000000, 2188.03418803419, Vecsmall([0]), [Vecsmall([64, 1])], [0, 0, 0, 0]] - sage: pari([0,SR(I),0,1,0]).ellinit() + sage: pari([0,SR(I),0,1,0]).ellinit() # needs sage.symbolic [0, I, 0, 1, 0, 4*I, 2, 0, -1, -64, 352*I, -80, 16384/5, Vecsmall([0]), [Vecsmall([64, 0])], [0, 0, 0, 0]] - sage: x = SR.symbol('x') - sage: pari([0,x,0,2*x,1]).ellinit() + sage: x = SR.symbol('x') # needs sage.symbolic + sage: pari([0,x,0,2*x,1]).ellinit() # needs sage.symbolic [0, x, 0, 2*x, 1, 4*x, 4*x, 4, -4*x^2 + 4*x, 16*x^2 - 96*x, -64*x^3 + 576*x^2 - 864, 64*x^4 - 576*x^3 + 576*x^2 - 432, (256*x^6 - 4608*x^5 + 27648*x^4 - 55296*x^3)/(4*x^4 - 36*x^3 + 36*x^2 - 27), Vecsmall([0]), [Vecsmall([64, 0])], [0, 0, 0, 0]] sage: e = pari([0,1,1,-2,0]).ellinit() @@ -1233,6 +1253,8 @@ sage: e = pari([0, 5, 2, -1, 1]).ellinit() sage: e.ellglobalred() [20144, [1, -2, 0, -1], 1, [2, 4; 1259, 1], [[4, 2, 0, 1], [1, 5, 0, 1]]] + + sage: # needs sage.schemes sage: e = pari(EllipticCurve('17a').a_invariants()).ellinit() sage: e.ellglobalred() [17, [1, 0, 0, 0], 4, Mat([17, 1]), [[1, 8, 0, 4]]] @@ -1251,8 +1273,9 @@ sage: e.ellak(0) 0 + sage: # needs sage.schemes sage: E = EllipticCurve('389a1') - sage: pari(E).ellanalyticrank() + sage: pari(E).ellanalyticrank() # needs sage.rings.number_field [2, 1.51863300057685] sage: e = pari([0, -1, 1, -10, -20]).ellinit() @@ -1291,6 +1314,7 @@ sage: om.elleisnum(100) 2.15314248576078 E50 + sage: # needs sage.schemes sage: e = pari([0,0,0,0,1]).ellinit() sage: e.elllocalred(7) [0, 1, [1, 0, 0, 0], 1] @@ -1331,6 +1355,7 @@ sage: e.elllocalred(3) [2, -10, [1, 0, 0, 0], 4] + sage: # needs sage.schemes sage: e = pari(EllipticCurve('65a1').a_invariants()).ellinit() sage: e.ellorder([0,0]) 2 @@ -1340,11 +1365,11 @@ sage: e = pari([0,1,1,-2,0]).ellinit() sage: e.ellordinate(0) [0, -1] - sage: e.ellordinate(SR(I)) + sage: e.ellordinate(SR(I)) # needs sage.symbolic [0.582203589721741 - 1.38606082464177*I, -1.58220358972174 + 1.38606082464177*I] - sage: e.ellordinate(SR(I), precision=128)[0].sage() + sage: e.ellordinate(SR(I), precision=128)[0].sage() # needs sage.symbolic 0.58220358972174117723338947874993600727 - 1.3860608246417697185311834209833653345*I - sage: e.ellordinate(1+3*5^1+O(5^3)) + sage: e.ellordinate(1+3*5^1+O(5^3)) # needs sage.rings.padics [4*5 + 5^2 + O(5^3), 4 + 3*5^2 + O(5^3)] sage: e.ellordinate('z+2*z^2+O(z^4)') [-2*z - 7*z^2 - 23*z^3 + O(z^4), -1 + 2*z + 7*z^2 + 23*z^3 + O(z^4)] @@ -1365,9 +1390,9 @@ [0] sage: e.ellmul(p, 2) [1/4, -7/8] - sage: q = e.ellmul(p, SR(1+I)); q + sage: q = e.ellmul(p, SR(1+I)); q # needs sage.symbolic [-2*I, 1 + I] - sage: e.ellmul(q, SR(1-I)) + sage: e.ellmul(q, SR(1-I)) # needs sage.symbolic [1/4, -7/8] sage: for D in [-7, -8, -11, -12, -16, -19, -27, -28]: # long time (1s) ....: hcpol = hilbert_class_polynomial(D) @@ -1397,6 +1422,7 @@ sage: e.ellrootno(1009) 1 + sage: # needs sage.rings.real_mpfr sage: e = pari([0,0,0,1,0]).ellinit() sage: C. = ComplexField() sage: e.ellsigma(2+i) @@ -1409,26 +1435,26 @@ sage: e = pari([0,0,0,1,0]).ellinit() sage: e.ellzeta(1) 1.06479841295883 - sage: C. = ComplexField() - sage: e.ellzeta(i-1) + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: e.ellzeta(i-1) # needs sage.rings.real_mpfr -0.350122658523049 - 0.350122658523049*I sage: e = pari([0,0,0,1,0]).ellinit() - sage: C. = ComplexField() - sage: e.ellztopoint(1+i) + sage: C. = ComplexField() # needs sage.rings.real_mpfr + sage: e.ellztopoint(1+i) # needs sage.rings.real_mpfr [0.E-... - 1.02152286795670*I, -0.149072813701096 - 0.149072813701096*I] sage: e.ellztopoint(0) [0] - sage: pari(SR(I)).ellj() + sage: pari(SR(I)).ellj() # needs sage.symbolic 1728.00000000000 - sage: pari(SR(3*I)).ellj() + sage: pari(SR(3*I)).ellj() # needs sage.symbolic 153553679.396729 sage: pari('quadgen(-3)').ellj() 0.E-54 sage: pari('quadgen(-7)').ellj(precision=256).sage() -3375.000000000000000000000000000000000000000000000000000000000000000000000000 - sage: pari(SR(-I)).ellj() + sage: pari(SR(-I)).ellj() # needs sage.symbolic Traceback (most recent call last): ... PariError: domain error in modular function: Im(argument) <= 0 @@ -1497,16 +1523,17 @@ General number fields:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2 - 1/8) - sage: pari(x^2 - 2).factornf(K.pari_polynomial("a")) + sage: K. = NumberField(x^2 - 1/8) # needs sage.rings.number_field + sage: pari(x^2 - 2).factornf(K.pari_polynomial("a")) # needs sage.rings.number_field doctest:...: DeprecationWarning: the PARI/GP function factornf is obsolete (2016-08-08) [x + Mod(-a, a^2 - 2), 1; x + Mod(a, a^2 - 2), 1] - sage: K. = QuadraticField(-23) - sage: p = K.primes_above(3)[0] - sage: K.pari_bnf().bnrclassno(p._pari_bid_()) + sage: K. = QuadraticField(-23) # needs sage.rings.number_field + sage: p = K.primes_above(3)[0] # needs sage.rings.number_field + sage: K.pari_bnf().bnrclassno(p._pari_bid_()) # needs sage.rings.number_field 3 + sage: # needs sage.symbolic sage: x = SR.symbol('x') sage: P = pari(x^6 + 108) sage: G = P.galoisinit() @@ -1515,6 +1542,7 @@ sage: len(G[5]) == prod(G[7]) True + sage: # needs sage.symbolic sage: G = pari(x^6 + 108).galoisinit() sage: G.galoispermtopol(G[5]) [x, 1/12*x^4 - 1/2*x, -1/12*x^4 - 1/2*x, 1/12*x^4 + 1/2*x, -1/12*x^4 + 1/2*x, -x] @@ -1523,6 +1551,7 @@ sage: G.galoispermtopol(G[5][1:4]) [1/12*x^4 - 1/2*x, -1/12*x^4 - 1/2*x, 1/12*x^4 + 1/2*x] + sage: # needs sage.symbolic sage: G = pari(x^4 + 1).galoisinit() sage: G.galoisfixedfield(G[5][1], flag=2) [y^2 - 2, Mod(-x^3 + x, x^4 + 1), [x^2 - y*x + 1, x^2 + y*x + 1]] @@ -1537,6 +1566,7 @@ sage: list(L[0][1]) [3, 2] + sage: # needs sage.symbolic sage: G = pari(x^6 + 108).galoisinit() sage: G.galoisisabelian() 0 @@ -1546,6 +1576,7 @@ sage: H.galoisisabelian(flag=1) 1 + sage: # needs sage.symbolic sage: G = pari(x^6 + 108).galoisinit() sage: L = G.galoissubgroups() sage: G.galoisisnormal(L[0]) @@ -1553,18 +1584,20 @@ sage: G.galoisisnormal(L[2]) 0 + sage: # needs sage.rings.number_field sage: F = QuadraticField(5, 'alpha') sage: nf = F.__pari__() sage: P = F.ideal(F.gen()) sage: Q = F.ideal(2) - sage: moduli = pari.matrix(2,2,[P.pari_prime(),4,Q.pari_prime(),4]) + sage: moduli = pari.matrix(2,2,[P.pari_prime(),4,Q.pari_prime(),4]) # needs sage.symbolic sage: residues = pari.vector(2,[0,1]) - sage: b = F(nf.idealchinese(moduli,residues)) - sage: b.valuation(P) >= 4 + sage: b = F(nf.idealchinese(moduli,residues)) # needs sage.symbolic + sage: b.valuation(P) >= 4 # needs sage.symbolic True sage: (b-1).valuation(Q) >= 2 True + sage: # needs sage.symbolic sage: F = NumberField(x^3-2, 'alpha') sage: nf = F.__pari__() sage: x = pari('[1, -1, 2]~') @@ -1573,17 +1606,19 @@ 1 sage: y = pari('[2, -2, 4]~') - sage: nf.idealcoprime(x, y) + sage: nf.idealcoprime(x, y) # needs sage.rings.number_field [5/43, 9/43, -1/43]~ + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) sage: K. = NumberField(x^2 + 1) sage: L = K.pari_nf().ideallist(100) - sage: L[0] # One ideal of norm 1. + sage: L[0] # One ideal of norm 1. # needs sage.symbolic [[1, 0; 0, 1]] - sage: L[64] # 4 ideals of norm 65. + sage: L[64] # 4 ideals of norm 65. # needs sage.symbolic [[65, 8; 0, 1], [65, 47; 0, 1], [65, 18; 0, 1], [65, 57; 0, 1]] + sage: # needs sage.rings.number_field sage: F = NumberField(x^3-2, 'alpha') sage: nf = F.__pari__() sage: I = pari('[1, -1, 2]~') @@ -1591,12 +1626,14 @@ sage: nf.ideallog(5, bid) [25]~ + sage: # needs sage.rings.number_field sage: K. = QuadraticField(-1) sage: F = pari(K).idealprimedec(5); F [[5, [-2, 1]~, 1, 1, [2, -1; 1, 2]], [5, [2, 1]~, 1, 1, [-2, -1; 1, -2]]] sage: F[0].pr_get_p() 5 + sage: # needs sage.rings.number_field sage: x = polygen(ZZ) sage: F = NumberField(x^3 - 2, 'alpha') sage: nf = F.__pari__() @@ -1604,6 +1641,7 @@ sage: nf.idealstar(I) [[[43, 9, 5; 0, 1, 0; 0, 0, 1], [0]], [42, [42]], [Mat([[43, [9, 1, 0]~, 1, 1, [-5, 2, -18; -9, -5, 2; 1, -9, -5]], 1]), Mat([[43, [9, 1, 0]~, 1, 1, [-5, 2, -18; -9, -5, 2; 1, -9, -5]], 1])], [[[[42], [3], [43, 9, 5; 0, 1, 0; 0, 0, 1], [[[-14, -8, 20]~, [1, 34, 38], [43, [9, 1, 0]~, 1, 1, [-5, 2, -18; -9, -5, 2; 1, -9, -5]]]~, 3, [42, [2, 1; 3, 1; 7, 1]]]]], [[], Vecsmall([])]], [Mat(1)]] + sage: # needs sage.rings.number_field sage: x = polygen(QQ) sage: K. = NumberField(x^3 - 17) sage: Kpari = K.pari_nf() @@ -1616,12 +1654,14 @@ sage: Kpari.getattr('zk') * pari("[3/2, -5, 0]~") -5/3*y^2 + 5/3*y - 1/6 + sage: # needs sage.rings.number_field sage: k. = NumberField(x^2 + 5) sage: x = 10 sage: y = a + 1 sage: pari(k).nfeltdiveuc(x, y) [2, -2]~ + sage: # needs sage.rings.number_field sage: x = polygen(ZZ) sage: k. = NumberField(x^2 + 5) sage: I = k.ideal(a) @@ -1641,6 +1681,7 @@ sage: nf.nfgaloisconj() [-x, x]~ + sage: # needs sage.rings.number_field sage: x = polygen(QQ) sage: K. = NumberField(x^3 - x + 1) sage: pari(K).nfhilbert(t, t + 2) @@ -1652,6 +1693,7 @@ sage: pari(K).nfhilbert(t, t + 2, P.pari_prime()) 1 + sage: # needs sage.rings.number_field sage: F. = NumberField(x^2-x-1) sage: Fp = pari(F) sage: A = matrix(F,[[1,2,a,3],[3,0,a+2,0],[0,0,a,2],[3+a,a,0,1]]) @@ -1684,6 +1726,7 @@ ... PariError: incorrect type in checknf [please apply nfinit()] (t_REAL) + sage: # needs sage.rings.number_field sage: F = NumberField(x^3-2,'alpha') sage: G = NumberField(x^3-2,'beta') sage: F.__pari__().nfisisom(G.__pari__()) @@ -1743,6 +1786,7 @@ ... PariError: domain error in quadray: isfundamental(D) = 0 + sage: # needs sage.rings.number_field sage.symbolic sage: x = SR.symbol('x') sage: F = NumberField(x^3-2,'alpha') sage: F.__pari__()[0].nfdisc() @@ -1771,6 +1815,7 @@ sage: from cypari2 import Pari sage: pari = Pari() + sage: # needs sage.symbolic sage: f = pari('(2/3)*x^3 + x - 5/7 + y'); f 2/3*x^3 + x + (y - 5/7) sage: var('x,y') diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index c389feb1bc2..b69db0fb5a6 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -1305,7 +1305,7 @@ cdef class MatrixArgs: return MA_ENTRIES_NDARRAY return MA_ENTRIES_SCALAR if isinstance(self.entries, Gen): # PARI object - from sage.libs.pari.convert_sage import pari_typ_to_entries_type + from sage.libs.pari.convert_sage_matrix import pari_typ_to_entries_type return pari_typ_to_entries_type(self) if isinstance(self.entries, MatrixArgs): # Prevent recursion diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index c8a27ac7aec..6e2412afac7 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -59,7 +59,12 @@ from sage.rings.integer_ring import ZZ cimport gmpy2 gmpy2.import_gmpy2() -# Some objects that are note imported at startup in order to break +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () + +# Some objects that are not imported at startup in order to break # circular imports NumberFieldElement_quadratic = None AlgebraicNumber_base = None @@ -929,7 +934,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): if isinstance(real, ComplexNumber): real, imag = (real).real(), (real).imag() - elif isinstance(real, sage.libs.pari.all.pari_gen): + elif isinstance(real, pari_gen): real, imag = real.real(), real.imag() elif isinstance(real, (list, tuple)): re, imag = real diff --git a/src/sage/rings/real_lazy.pyx b/src/sage/rings/real_lazy.pyx index 54a84e4920a..e765cdfe801 100644 --- a/src/sage/rings/real_lazy.pyx +++ b/src/sage/rings/real_lazy.pyx @@ -49,9 +49,13 @@ from sage.rings.integer import Integer cdef QQ, RR, CC, RealField, ComplexField from sage.rings.rational_field import QQ -from sage.rings.real_mpfr import RR, RealField -from sage.rings.complex_mpfr import ComplexField -from sage.rings.cc import CC + +try: + from sage.rings.real_mpfr import RR, RealField + from sage.rings.complex_mpfr import ComplexField + from sage.rings.cc import CC +except ImportError: + pass cdef _QQx = None @@ -814,7 +818,6 @@ cdef class LazyFieldElement(FieldElement): try: return self.eval(complex) except Exception: - from .complex_mpfr import ComplexField return complex(self.eval(ComplexField(53))) cpdef eval(self, R) noexcept: diff --git a/src/sage/rings/real_mpfr.pxd b/src/sage/rings/real_mpfr.pxd index 5d44208f339..f89ec9557fd 100644 --- a/src/sage/rings/real_mpfr.pxd +++ b/src/sage/rings/real_mpfr.pxd @@ -1,10 +1,8 @@ -from sage.libs.mpfr.types cimport mpfr_rnd_t, mpfr_t +from sage.libs.mpfr.types cimport mpfr_rnd_t, mpfr_t, mpfr_prec_t cimport sage.rings.ring cimport sage.rings.abc cimport sage.structure.element -from cypari2.types cimport GEN -from sage.libs.mpfr.types cimport mpfr_prec_t cdef class RealNumber(sage.structure.element.RingElement) # forward decl @@ -26,7 +24,6 @@ cdef class RealNumber(sage.structure.element.RingElement): cpdef _mul_(self, other) noexcept cpdef _mod_(self, right) noexcept cdef _set(self, x, int base) noexcept - cdef _set_from_GEN_REAL(self, GEN g) noexcept cdef RealNumber abs(RealNumber self) noexcept cpdef RealField(mpfr_prec_t prec=*, int sci_not=*, rnd=*) noexcept diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 9117dfcd4ce..d98a977d935 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -142,10 +142,6 @@ import sage.misc.weak_dict import operator -from cypari2.paridecl cimport * -from cypari2.gen cimport Gen -from cypari2.stack cimport new_gen - from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.rings.integer cimport Integer @@ -155,6 +151,7 @@ from sage.categories.map cimport Map from sage.rings.real_double cimport RealDoubleElement +import sage.rings.abc import sage.rings.rational_field import sage.rings.infinity @@ -164,6 +161,11 @@ from sage.arith.numerical_approx cimport digits_to_bits from sage.arith.constants cimport M_LN2_LN10 from sage.arith.long cimport is_small_python_int +try: + from cypari2 import Gen + from sage.libs.pari.convert_sage_real_mpfr import new_gen_from_real_mpfr_element, set_real_mpfr_element_from_gen +except ImportError: + Gen = () cimport gmpy2 gmpy2.import_gmpy2() @@ -743,9 +745,8 @@ cdef class RealField_class(sage.rings.abc.RealField): return RRtoRR(S, self) elif QQ.has_coerce_map_from(S): return QQtoRR(QQ, self) * QQ._internal_coerce_map_from(S) - from sage.rings.qqbar import AA from sage.rings.real_lazy import RLF - if S is AA or S is RLF: + if isinstance(S, sage.rings.abc.AlgebraicRealField) or S is RLF: return self.convert_method_map(S, "_mpfr_") return self._coerce_map_via([RLF], S) @@ -1456,7 +1457,6 @@ cdef class RealNumber(sage.structure.element.RingElement): # This should not be called except when the number is being created. # Real Numbers are supposed to be immutable. cdef RealField_class parent - cdef Gen _gen parent = self._parent if isinstance(x, RealNumber): if isinstance(x, RealLiteral): @@ -1470,9 +1470,8 @@ cdef class RealNumber(sage.structure.element.RingElement): mpfr_set_z(self.value, (x).value, parent.rnd) elif isinstance(x, Rational): mpfr_set_q(self.value, (x).value, parent.rnd) - elif isinstance(x, Gen) and typ((x).g) == t_REAL: - _gen = x - self._set_from_GEN_REAL(_gen.g) + elif isinstance(x, Gen) and set_real_mpfr_element_from_gen(self, x): + pass elif isinstance(x, int): x = Integer(x) mpfr_set_z(self.value, (x).value, parent.rnd) @@ -1504,49 +1503,6 @@ cdef class RealNumber(sage.structure.element.RingElement): else: raise TypeError("unable to convert {!r} to a real number".format(s)) - cdef _set_from_GEN_REAL(self, GEN g) noexcept: - """ - EXAMPLES:: - - sage: rt2 = sqrt(pari('2.0')) - sage: rt2 - 1.41421356237310 - sage: rt2.sage() - 1.41421356237309505 - sage: rt2.sage().prec() - 64 - sage: pari(rt2.sage()) == rt2 - True - sage: for i in range(100, 200): - ....: assert(sqrt(pari(i)) == pari(sqrt(pari(i)).sage())) - sage: (-3.1415).__pari__().sage() - -3.14150000000000000 - """ - cdef int sgn - sgn = signe(g) - - if sgn == 0: - mpfr_set_ui(self.value, 0, MPFR_RNDN) - return - - cdef int wordsize = 8 * sizeof(long) - - cdef mpz_t mantissa - mpz_init(mantissa) - mpz_import(mantissa, lg(g) - 2, 1, wordsize/8, 0, 0, &g[2]) - - cdef mp_exp_t exponent = expo(g) - - # Round to nearest for best results when setting a low-precision - # MPFR from a high-precision GEN - mpfr_set_z(self.value, mantissa, MPFR_RNDN) - mpfr_mul_2si(self.value, self.value, exponent - wordsize * (lg(g) - 2) + 1, MPFR_RNDN) - - if sgn < 0: - mpfr_neg(self.value, self.value, MPFR_RNDN) - - mpz_clear(mantissa) - def __reduce__(self): """ EXAMPLES:: @@ -3370,48 +3326,7 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: RR(a) << (sys.maxsize-3)/4 0.500000000000000 """ - # This uses interfaces of MPFR and PARI which are documented - # (and not marked subject-to-change). It could be faster - # by using internal interfaces of MPFR, which are documented - # as subject-to-change. - - if mpfr_nan_p(self.value) or mpfr_inf_p(self.value): - raise ValueError('cannot convert NaN or infinity to Pari float') - - # wordsize for PARI - cdef unsigned long wordsize = sizeof(long)*8 - - cdef mpfr_prec_t prec - prec = (self._parent)._prec - - # We round up the precision to the nearest multiple of wordsize. - cdef int rounded_prec - rounded_prec = (self.prec() + wordsize - 1) & ~(wordsize - 1) - - # Yes, assigning to self works fine, even in Cython. - if rounded_prec > prec: - self = RealField(rounded_prec)(self) - - cdef mpz_t mantissa - cdef mp_exp_t exponent - cdef GEN pari_float - - sig_on() - if mpfr_zero_p(self.value): - pari_float = real_0_bit(-rounded_prec) - else: - # Now we can extract the mantissa, and it will be normalized - # (the most significant bit of the most significant word will be 1). - mpz_init(mantissa) - exponent = mpfr_get_z_exp(mantissa, self.value) - - # Create a PARI REAL - pari_float = cgetr(2 + rounded_prec / wordsize) - pari_float[1] = evalexpo(exponent + rounded_prec - 1) + evalsigne(mpfr_sgn(self.value)) - mpz_export(&pari_float[2], NULL, 1, wordsize // 8, 0, 0, mantissa) - mpz_clear(mantissa) - - return new_gen(pari_float) + return new_gen_from_real_mpfr_element(self) def _mpmath_(self, prec=None, rounding=None): """ @@ -3431,7 +3346,6 @@ cdef class RealNumber(sage.structure.element.RingElement): from sage.libs.mpmath.all import make_mpf return make_mpf(mpfr_to_mpfval(self.value)) - def sign_mantissa_exponent(self): r""" Return the sign, mantissa, and exponent of ``self``.