From af19b6ab6e748751286f15b88dcd0ba755cd916d Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Wed, 2 Oct 2024 22:18:43 +0200 Subject: [PATCH 01/13] Add declaration for lg2prec and prec2lg --- cypari2/paridecl.pxd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cypari2/paridecl.pxd b/cypari2/paridecl.pxd index 29cb8ef8..9be7aed0 100644 --- a/cypari2/paridecl.pxd +++ b/cypari2/paridecl.pxd @@ -5106,6 +5106,7 @@ cdef extern from *: # PARI headers already included by types.pxd void killblock(GEN x) GEN leading_coeff(GEN x) void lg_increase(GEN x) + long lg2prec(long x) long lgcols(GEN x) long lgpol(GEN x) GEN matpascal(long n) @@ -5195,6 +5196,7 @@ cdef extern from *: # PARI headers already included by types.pxd GEN polx_zx(long sv) GEN powii(GEN x, GEN n) GEN powIs(long n) + long prec2lg(long x) long prec2nbits(long x) double prec2nbits_mul(long x, double y) long prec2ndec(long x) From e362eeef90292a1b525bfba31e92784e3257de44 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Fri, 4 Oct 2024 21:44:51 +0200 Subject: [PATCH 02/13] Adapt to precision changes in pari 2.17 Since 2.17 pari stores the precision in bits instead of words. Port cypari2 to work with it: - Rename prec_bits_to_words to prec_bits_to_pari and outsource it to upstream's nbits2prec, so it works with all pari versions - Remove unused and no longer needed prec_words_to_bits and prec_words_to_dec functions - Use upstream's LOWDEFAULTPREC as default precision --- autogen/args.py | 2 +- autogen/generator.py | 2 +- cypari2/gen.pyx | 18 +++++------ cypari2/pari_instance.pxd | 3 +- cypari2/pari_instance.pyx | 66 +++++---------------------------------- cypari2/types.pxd | 1 + 6 files changed, 21 insertions(+), 71 deletions(-) diff --git a/autogen/args.py b/autogen/args.py index cd840080..4f2ac3ef 100644 --- a/autogen/args.py +++ b/autogen/args.py @@ -308,7 +308,7 @@ def always_default(self): def get_argument_name(self, namesiter): return "precision" def c_convert_code(self): - s = " {name} = prec_bits_to_words({name})\n" + s = " {name} = prec_bits_to_pari({name})\n" return s.format(name=self.name) class PariArgumentBitprec(PariArgumentClass): diff --git a/autogen/generator.py b/autogen/generator.py index 048adceb..e4b85a77 100644 --- a/autogen/generator.py +++ b/autogen/generator.py @@ -149,7 +149,7 @@ def bnfinit(P, long flag=0, tech=None, long precision=0): cdef GEN _tech = NULL if _have_tech: _tech = (tech).g - precision = prec_bits_to_words(precision) + precision = prec_bits_to_pari(precision) cdef GEN _ret = bnfinit0(_P, flag, _tech, precision) return new_gen(_ret) diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx index a1092449..dc2d80db 100644 --- a/cypari2/gen.pyx +++ b/cypari2/gen.pyx @@ -66,7 +66,7 @@ from .types cimport * from .string_utils cimport to_string, to_bytes from .paripriv cimport * from .convert cimport PyObject_AsGEN, gen_to_integer -from .pari_instance cimport (prec_bits_to_words, +from .pari_instance cimport (prec_bits_to_pari, default_bitprec, get_var) from .stack cimport (new_gen, new_gens2, new_gen_noclear, clone_gen, clear_stack, reset_avma, @@ -647,7 +647,7 @@ cdef class Gen(Gen_base): if m is not None: t0 = t0.Mod(m) sig_on() - return new_gen(gpow(t0.g, t1.g, prec_bits_to_words(0))) + return new_gen(gpow(t0.g, t1.g, prec_bits_to_pari(0))) def __neg__(self): sig_on() @@ -2926,7 +2926,7 @@ cdef class Gen(Gen_base): 54.9711779448622 """ sig_on() - return new_gen(bernreal(self, prec_bits_to_words(precision))) + return new_gen(bernreal(self, prec_bits_to_pari(precision))) def besselk(nu, x, unsigned long precision=0): """ @@ -2963,7 +2963,7 @@ cdef class Gen(Gen_base): """ cdef Gen t0 = objtogen(x) sig_on() - return new_gen(kbessel(nu.g, t0.g, prec_bits_to_words(precision))) + return new_gen(kbessel(nu.g, t0.g, prec_bits_to_pari(precision))) def eint1(x, long n=0, unsigned long precision=0): r""" @@ -2991,9 +2991,9 @@ cdef class Gen(Gen_base): """ sig_on() if n <= 0: - return new_gen(eint1(x.g, prec_bits_to_words(precision))) + return new_gen(eint1(x.g, prec_bits_to_pari(precision))) else: - return new_gen(veceint1(x.g, stoi(n), prec_bits_to_words(precision))) + return new_gen(veceint1(x.g, stoi(n), prec_bits_to_pari(precision))) log_gamma = Gen_base.lngamma @@ -3026,7 +3026,7 @@ cdef class Gen(Gen_base): -0.400459056163451 """ sig_on() - return new_gen(polylog0(m, x.g, flag, prec_bits_to_words(precision))) + return new_gen(polylog0(m, x.g, flag, prec_bits_to_pari(precision))) def sqrtn(x, n, unsigned long precision=0): r""" @@ -3090,7 +3090,7 @@ cdef class Gen(Gen_base): cdef GEN ans, zetan cdef Gen t0 = objtogen(n) sig_on() - ans = gsqrtn(x.g, t0.g, &zetan, prec_bits_to_words(precision)) + ans = gsqrtn(x.g, t0.g, &zetan, prec_bits_to_pari(precision)) return new_gens2(ans, zetan) def ffprimroot(self): @@ -4609,7 +4609,7 @@ cdef class Gen(Gen_base): elif typ(g0) == t_RFRAC: g0 = rfrac_to_ser(g0, n+4) - cdef GEN r = ellwp0(self.g, g0, flag, prec_bits_to_words(precision)) + cdef GEN r = ellwp0(self.g, g0, flag, prec_bits_to_pari(precision)) if flag == 1 and have_ellwp_flag1_bug(): # Work around ellwp() bug: double the second element set_gel(r, 2, gmulgs(gel(r, 2), 2)) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index f2394870..528db5c7 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -3,8 +3,7 @@ cimport cython from .gen cimport Gen -cpdef long prec_bits_to_words(unsigned long prec_in_bits) noexcept -cpdef long prec_words_to_bits(long prec_in_words) noexcept +cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept cpdef long default_bitprec() noexcept cdef class Pari_auto: diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 65d705ad..1e8e3eae 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -301,7 +301,7 @@ from .closure cimport _pari_init_closure # Default precision (in PARI words) for the PARI library interface, # when no explicit precision is given and the inputs are exact. -cdef long prec = prec_bits_to_words(53) +cdef long prec = prec_bits_to_pari(53) ################################################################# @@ -341,7 +341,7 @@ def prec_dec_to_bits(long prec_in_dec): return int(prec_in_dec*log_10 + 1.0) # Add one to round up -cpdef long prec_bits_to_words(unsigned long prec_in_bits) noexcept: +cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: r""" Convert from precision expressed in bits to pari real precision expressed in words. Note: this rounds up to the nearest word, @@ -350,46 +350,18 @@ cpdef long prec_bits_to_words(unsigned long prec_in_bits) noexcept: Examples: - >>> from cypari2.pari_instance import prec_bits_to_words + >>> from cypari2.pari_instance import prec_bits_to_pari >>> import sys >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_bits_to_words(70) == (5 if bitness == '32' else 4) + >>> prec_bits_to_pari(70) == (5 if bitness == '32' else 4) True >>> ans32 = [(32, 3), (64, 4), (96, 5), (128, 6), (160, 7), (192, 8), (224, 9), (256, 10)] >>> ans64 = [(32, 3), (64, 3), (96, 4), (128, 4), (160, 5), (192, 5), (224, 6), (256, 6)] - >>> [(32*n, prec_bits_to_words(32*n)) for n in range(1, 9)] == (ans32 if bitness == '32' else ans64) + >>> [(32*n, prec_bits_to_pari(32*n)) for n in range(1, 9)] == (ans32 if bitness == '32' else ans64) True """ - if not prec_in_bits: - return prec - cdef unsigned long wordsize = BITS_IN_LONG - - # This equals ceil(prec_in_bits/wordsize) + 2 - return (prec_in_bits - 1)//wordsize + 3 - - -cpdef long prec_words_to_bits(long prec_in_words) noexcept: - r""" - Convert from pari real precision expressed in words to precision - expressed in bits. Note: this adjusts for the two codewords of a - pari real, and is architecture-dependent. - - Examples: - - >>> from cypari2.pari_instance import prec_words_to_bits - >>> import sys - >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_words_to_bits(10) == (256 if bitness == '32' else 512) - True - - >>> ans32 = [(3, 32), (4, 64), (5, 96), (6, 128), (7, 160), (8, 192), (9, 224)] - >>> ans64 = [(3, 64), (4, 128), (5, 192), (6, 256), (7, 320), (8, 384), (9, 448)] # 64-bit - >>> [(n, prec_words_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) - True - """ - # see user's guide to the pari library, page 10 - return (prec_in_words - 2) * BITS_IN_LONG + return max(LOWDEFAULTPREC, nbits2prec(prec_in_bits)) cpdef long default_bitprec() noexcept: @@ -402,7 +374,7 @@ cpdef long default_bitprec() noexcept: >>> default_bitprec() 64 """ - return (prec - 2) * BITS_IN_LONG + return LOWDEFAULTPREC def prec_dec_to_words(long prec_in_dec): @@ -424,29 +396,7 @@ def prec_dec_to_words(long prec_in_dec): >>> [(n, prec_dec_to_words(n)) for n in range(10, 90, 10)] == (ans32 if bitness == '32' else ans64) True """ - return prec_bits_to_words(prec_dec_to_bits(prec_in_dec)) - - -def prec_words_to_dec(long prec_in_words): - r""" - Convert from precision expressed in words to precision expressed in - decimal. Note: this adjusts for the two codewords of a pari real, - and is architecture-dependent. - - Examples: - - >>> from cypari2.pari_instance import prec_words_to_dec - >>> import sys - >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_words_to_dec(5) == (28 if bitness == '32' else 57) - True - - >>> ans32 = [(3, 9), (4, 19), (5, 28), (6, 38), (7, 48), (8, 57), (9, 67)] - >>> ans64 = [(3, 19), (4, 38), (5, 57), (6, 77), (7, 96), (8, 115), (9, 134)] - >>> [(n, prec_words_to_dec(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) - True - """ - return prec_bits_to_dec(prec_words_to_bits(prec_in_words)) + return prec_bits_to_pari(prec_dec_to_bits(prec_in_dec)) # Callbacks from PARI to print stuff using sys.stdout.write() instead diff --git a/cypari2/types.pxd b/cypari2/types.pxd index 9ee4fe67..48571cf8 100644 --- a/cypari2/types.pxd +++ b/cypari2/types.pxd @@ -52,6 +52,7 @@ cdef extern from "pari/pari.h": t_INFINITY int BITS_IN_LONG + int LOWDEFAULTPREC long DEFAULTPREC # 64 bits precision long MEDDEFAULTPREC # 128 bits precision long BIGDEFAULTPREC # 192 bits precision From 594b44b5820ca3e97bba5490cb076a223d15fb44 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 5 Oct 2024 20:36:42 +0200 Subject: [PATCH 03/13] Optimize --- cypari2/pari_instance.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 1e8e3eae..4a8e8dc5 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -361,7 +361,7 @@ cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: >>> [(32*n, prec_bits_to_pari(32*n)) for n in range(1, 9)] == (ans32 if bitness == '32' else ans64) True """ - return max(LOWDEFAULTPREC, nbits2prec(prec_in_bits)) + return nbits2prec(prec_in_bits) or LOWDEFAULTPREC cpdef long default_bitprec() noexcept: From f43a1035900b2928b70e566d19967cc97bd8ba77 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 5 Oct 2024 20:42:19 +0200 Subject: [PATCH 04/13] Fix default precision with pari <=2.15 --- cypari2/pari_instance.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 4a8e8dc5..12ef60dd 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -374,7 +374,7 @@ cpdef long default_bitprec() noexcept: >>> default_bitprec() 64 """ - return LOWDEFAULTPREC + return prec2nbits(LOWDEFAULTPREC) def prec_dec_to_words(long prec_in_dec): From 40a65d97ee45935cd110b587cf7e0ba52c6647ac Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 5 Oct 2024 20:43:07 +0200 Subject: [PATCH 05/13] Remove prec_dec_to_words too --- cypari2/pari_instance.pyx | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 12ef60dd..3f66184b 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -377,28 +377,6 @@ cpdef long default_bitprec() noexcept: return prec2nbits(LOWDEFAULTPREC) -def prec_dec_to_words(long prec_in_dec): - r""" - Convert from precision expressed in decimal to precision expressed - in words. Note: this rounds up to the nearest word, adjusts for the - two codewords of a pari real, and is architecture-dependent. - - Examples: - - >>> from cypari2.pari_instance import prec_dec_to_words - >>> import sys - >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_dec_to_words(38) == (6 if bitness == '32' else 4) - True - - >>> ans32 = [(10, 4), (20, 5), (30, 6), (40, 7), (50, 8), (60, 9), (70, 10), (80, 11)] - >>> ans64 = [(10, 3), (20, 4), (30, 4), (40, 5), (50, 5), (60, 6), (70, 6), (80, 7)] # 64-bit - >>> [(n, prec_dec_to_words(n)) for n in range(10, 90, 10)] == (ans32 if bitness == '32' else ans64) - True - """ - return prec_bits_to_pari(prec_dec_to_bits(prec_in_dec)) - - # Callbacks from PARI to print stuff using sys.stdout.write() instead # of C library functions like puts(). cdef PariOUT python_pariOut From 3612d39e75e829c4dc45010b569279f757c9b289 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 5 Oct 2024 23:48:05 +0200 Subject: [PATCH 06/13] Fix default precision with pari<=2.15 --- cypari2/pari_instance.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 3f66184b..43ee3c70 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -361,7 +361,9 @@ cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: >>> [(32*n, prec_bits_to_pari(32*n)) for n in range(1, 9)] == (ans32 if bitness == '32' else ans64) True """ - return nbits2prec(prec_in_bits) or LOWDEFAULTPREC + if not prec_in_bits: + return prec + return nbits2prec(prec_in_bits) cpdef long default_bitprec() noexcept: From 248f4800febc14e360aa7cf9952d998bb719a679 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 6 Oct 2024 22:50:27 +0200 Subject: [PATCH 07/13] Restore prec_words_to_bits (renamed to prec_pari_to_bits) for backwards compatibility --- cypari2/pari_instance.pxd | 1 + cypari2/pari_instance.pyx | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index 528db5c7..2dccd471 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -4,6 +4,7 @@ cimport cython from .gen cimport Gen cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept +cpdef long prec_pari_to_bits(long prec_pari) noexcept cpdef long default_bitprec() noexcept cdef class Pari_auto: diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 43ee3c70..42279195 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -366,6 +366,25 @@ cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: return nbits2prec(prec_in_bits) +cpdef long prec_pari_to_bits(long prec_pari) noexcept: + r""" + Convert from pari real precision to precision + expressed in bits. Note: this adjusts for the two codewords of a + pari real, and is architecture-dependent. + Examples: + >>> from cypari2.pari_instance import prec_words_to_bits + >>> import sys + >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' + >>> prec_words_to_bits(10) == (256 if bitness == '32' else 512) + True + >>> ans32 = [(3, 32), (4, 64), (5, 96), (6, 128), (7, 160), (8, 192), (9, 224)] + >>> ans64 = [(3, 64), (4, 128), (5, 192), (6, 256), (7, 320), (8, 384), (9, 448)] # 64-bit + >>> [(n, prec_words_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) + True + """ + return prec2nbits(prec_pari) + + cpdef long default_bitprec() noexcept: r""" Return the default precision in bits. From 38fc2860cdc9ad15c0b33f4f5b3d9233ec858328 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 6 Oct 2024 23:06:10 +0200 Subject: [PATCH 08/13] Rename prec_words_to_bits in tests --- cypari2/pari_instance.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 42279195..5c2cfe16 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -372,14 +372,14 @@ cpdef long prec_pari_to_bits(long prec_pari) noexcept: expressed in bits. Note: this adjusts for the two codewords of a pari real, and is architecture-dependent. Examples: - >>> from cypari2.pari_instance import prec_words_to_bits + >>> from cypari2.pari_instance import prec_pari_to_bits >>> import sys >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_words_to_bits(10) == (256 if bitness == '32' else 512) + >>> prec_pari_to_bits(10) == (256 if bitness == '32' else 512) True >>> ans32 = [(3, 32), (4, 64), (5, 96), (6, 128), (7, 160), (8, 192), (9, 224)] >>> ans64 = [(3, 64), (4, 128), (5, 192), (6, 256), (7, 320), (8, 384), (9, 448)] # 64-bit - >>> [(n, prec_words_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) + >>> [(n, prec_pari_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) True """ return prec2nbits(prec_pari) From 18dbad68305141c108adccdbc28c81c2fcf8bdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 30 Oct 2024 23:33:51 -0300 Subject: [PATCH 09/13] fix doctests for pari 2.17 --- autogen/doc.py | 16 ++++++++-------- cypari2/gen.pyx | 2 ++ cypari2/pari_instance.pyx | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/autogen/doc.py b/autogen/doc.py index 711827b3..c71e7c6f 100644 --- a/autogen/doc.py +++ b/autogen/doc.py @@ -289,7 +289,7 @@ def get_rest_doc(function): >>> from autogen.doc import get_rest_doc >>> print(get_rest_doc("teichmuller")) Teichmüller character of the :math:`p`-adic number :math:`x`, i.e. the unique - :math:`(p-1)`-th root of unity congruent to :math:`x / p^{v_p(x)}` modulo :math:`p`... + :math:`(p-1)`-th root of unity congruent to :math:`x / p^{v_...(x)}` modulo :math:`p`... :: @@ -300,24 +300,24 @@ def get_rest_doc(function): .. MATH:: f(x) = \exp (-i\pi/24).\eta ((x+1)/2)/\eta (x) {such that} - j = (f^{24}-16)^3/f^{24}, + j = (f^{24}-16)^.../f^{24}, where :math:`j` is the elliptic :math:`j`-invariant (see the function :literal:`ellj`). If :math:`flag = 1`, returns .. MATH:: - f_1(x) = \eta (x/2)/\eta (x) {such that} - j = (f_1^{24}+16)^3/f_1^{24}. + f_...(x) = \eta (x/2)/\eta (x) {such that} + j = (f_...^{24}+16)^.../f_...^{24}. Finally, if :math:`flag = 2`, returns .. MATH:: - f_2(x) = \sqrt{2}\eta (2x)/\eta (x) {such that} - j = (f_2^{24}+16)^3/f_2^{24}. + f_...(x) = \sqrt{2}\eta (2x)/\eta (x) {such that} + j = (f_...^{24}+16)^.../f_...^{24}. - Note the identities :math:`f^8 = f_1^8+f_2^8` and :math:`ff_1f_2 = \sqrt2`. + Note the identities :math:`f^... = f_...^...+f_...^...` and :math:`ff_...f_... = \sqrt2`. :: @@ -333,7 +333,7 @@ def get_rest_doc(function): .. MATH:: \sum - (x_i or y_i) 2^i + (x_... or y_...) 2^... See ``bitand`` (in the PARI manual) for the behavior for negative arguments. """ diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx index dc2d80db..ef049c25 100644 --- a/cypari2/gen.pyx +++ b/cypari2/gen.pyx @@ -902,6 +902,7 @@ cdef class Gen(Gen_base): >>> x = pari('x') + >>> pari.setrand(1) >>> (x**2 - 65).bnfinit().bnf_get_fu() [Mod(x - 8, x^2 - 65)] >>> (x**4 - x**2 + 1).bnfinit().bnf_get_fu() @@ -951,6 +952,7 @@ cdef class Gen(Gen_base): >>> import warnings >>> with warnings.catch_warnings(record=True) as w: ... warnings.simplefilter('always') + ... pari.setrand(1) ... funits = (x**2 - 65).bnfinit().bnfunit() ... assert len(w) == 1 ... assert issubclass(w[0].category, DeprecationWarning) diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 5c2cfe16..7a27e5fb 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -235,9 +235,9 @@ Verify that ``nfroots()`` (which has an unusual signature with a non-default argument following a default argument) works: >>> pari.nfroots(x='x^4 - 1') -[-1, 1] +[-1, 1]... >>> pari.nfroots(pari.nfinit('t^2 + 1'), "x^4 - 1") -[-1, 1, Mod(-t, t^2 + 1), Mod(t, t^2 + 1)] +[-1, 1, Mod(-t, t^2 + 1), Mod(t, t^2 + 1)]... Reset default precision for the following tests: From 722513be15c1b457c9f615a8ed45a0ef0267a155 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Thu, 31 Oct 2024 19:30:34 +0100 Subject: [PATCH 10/13] Drop prec_pari_to_bits again --- cypari2/pari_instance.pxd | 1 - cypari2/pari_instance.pyx | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index 2dccd471..528db5c7 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -4,7 +4,6 @@ cimport cython from .gen cimport Gen cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept -cpdef long prec_pari_to_bits(long prec_pari) noexcept cpdef long default_bitprec() noexcept cdef class Pari_auto: diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 5c2cfe16..43ee3c70 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -366,25 +366,6 @@ cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: return nbits2prec(prec_in_bits) -cpdef long prec_pari_to_bits(long prec_pari) noexcept: - r""" - Convert from pari real precision to precision - expressed in bits. Note: this adjusts for the two codewords of a - pari real, and is architecture-dependent. - Examples: - >>> from cypari2.pari_instance import prec_pari_to_bits - >>> import sys - >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_pari_to_bits(10) == (256 if bitness == '32' else 512) - True - >>> ans32 = [(3, 32), (4, 64), (5, 96), (6, 128), (7, 160), (8, 192), (9, 224)] - >>> ans64 = [(3, 64), (4, 128), (5, 192), (6, 256), (7, 320), (8, 384), (9, 448)] # 64-bit - >>> [(n, prec_pari_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) - True - """ - return prec2nbits(prec_pari) - - cpdef long default_bitprec() noexcept: r""" Return the default precision in bits. From 9ac41da70afde14376b3e3747f6b475588af4053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Fri, 1 Nov 2024 17:57:55 -0300 Subject: [PATCH 11/13] define DEFAULT_BITPREC, use nbits2prec() --- autogen/args.py | 10 +++------- autogen/generator.py | 4 ++-- autogen/parser.py | 2 +- cypari2/gen.pyx | 33 +++++++++++++++++---------------- cypari2/pari_instance.pxd | 6 ++++++ cypari2/pari_instance.pyx | 2 +- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/autogen/args.py b/autogen/args.py index 4f2ac3ef..02c57b9d 100644 --- a/autogen/args.py +++ b/autogen/args.py @@ -304,11 +304,11 @@ def _typerepr(self): def ctype(self): return "long" def always_default(self): - return "0" + return "DEFAULT_BITPREC" def get_argument_name(self, namesiter): return "precision" def c_convert_code(self): - s = " {name} = prec_bits_to_pari({name})\n" + s = " {name} = nbits2prec({name})\n" return s.format(name=self.name) class PariArgumentBitprec(PariArgumentClass): @@ -317,13 +317,9 @@ def _typerepr(self): def ctype(self): return "long" def always_default(self): - return "0" + return "DEFAULT_BITPREC" def get_argument_name(self, namesiter): return "precision" - def c_convert_code(self): - s = " if not {name}:\n" - s += " {name} = default_bitprec()\n" - return s.format(name=self.name) class PariArgumentSeriesPrec(PariArgumentClass): def _typerepr(self): diff --git a/autogen/generator.py b/autogen/generator.py index e4b85a77..41547237 100644 --- a/autogen/generator.py +++ b/autogen/generator.py @@ -139,7 +139,7 @@ def handle_pari_function(self, function, cname, prototype="", help="", obsolete= ... help=r"bnfinit(P,{flag=0},{tech=[]}): compute...", ... **{"class":"basic", "section":"number_fields"}) GEN bnfinit0(GEN, long, GEN, long) - def bnfinit(P, long flag=0, tech=None, long precision=0): + def bnfinit(P, long flag=0, tech=None, long precision=DEFAULT_BITPREC): ... cdef bint _have_tech = (tech is not None) if _have_tech: @@ -149,7 +149,7 @@ def bnfinit(P, long flag=0, tech=None, long precision=0): cdef GEN _tech = NULL if _have_tech: _tech = (tech).g - precision = prec_bits_to_pari(precision) + precision = nbits2prec(precision) cdef GEN _ret = bnfinit0(_P, flag, _tech, precision) return new_gen(_ret) diff --git a/autogen/parser.py b/autogen/parser.py index d910946d..a7fe02f0 100644 --- a/autogen/parser.py +++ b/autogen/parser.py @@ -109,7 +109,7 @@ def parse_prototype(proto, help, initial_args=[]): >>> parse_prototype(proto, help) ([GEN x, GEN* r=NULL], GEN) >>> parse_prototype("lp", "foo()", [str("TEST")]) - (['TEST', prec precision=0], long) + (['TEST', prec precision=DEFAULT_BITPREC], long) """ # Use the help string just for the argument names. # "names" should be an iterator over the argument names. diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx index ef049c25..d910ae59 100644 --- a/cypari2/gen.pyx +++ b/cypari2/gen.pyx @@ -66,8 +66,7 @@ from .types cimport * from .string_utils cimport to_string, to_bytes from .paripriv cimport * from .convert cimport PyObject_AsGEN, gen_to_integer -from .pari_instance cimport (prec_bits_to_pari, - default_bitprec, get_var) +from .pari_instance cimport DEFAULT_BITPREC, get_var from .stack cimport (new_gen, new_gens2, new_gen_noclear, clone_gen, clear_stack, reset_avma, remove_from_pari_stack, move_gens_to_heap) @@ -647,7 +646,7 @@ cdef class Gen(Gen_base): if m is not None: t0 = t0.Mod(m) sig_on() - return new_gen(gpow(t0.g, t1.g, prec_bits_to_pari(0))) + return new_gen(gpow(t0.g, t1.g, nbits2prec(DEFAULT_BITPREC))) def __neg__(self): sig_on() @@ -2913,7 +2912,7 @@ cdef class Gen(Gen_base): sig_on() return new_gen(bernfrac(self)) - def bernreal(self, unsigned long precision=0): + def bernreal(self, unsigned long precision=DEFAULT_BITPREC): r""" The Bernoulli number `B_x`, as for the function bernfrac, but `B_x` is returned as a real number (with the current @@ -2928,9 +2927,9 @@ cdef class Gen(Gen_base): 54.9711779448622 """ sig_on() - return new_gen(bernreal(self, prec_bits_to_pari(precision))) + return new_gen(bernreal(self, nbits2prec(precision))) - def besselk(nu, x, unsigned long precision=0): + def besselk(nu, x, unsigned long precision=DEFAULT_BITPREC): """ nu.besselk(x): K-Bessel function (modified Bessel function of the second kind) of index nu, which can be complex, and argument @@ -2965,9 +2964,9 @@ cdef class Gen(Gen_base): """ cdef Gen t0 = objtogen(x) sig_on() - return new_gen(kbessel(nu.g, t0.g, prec_bits_to_pari(precision))) + return new_gen(kbessel(nu.g, t0.g, nbits2prec(precision))) - def eint1(x, long n=0, unsigned long precision=0): + def eint1(x, long n=0, unsigned long precision=DEFAULT_BITPREC): r""" x.eint1(n): exponential integral E1(x): @@ -2993,13 +2992,14 @@ cdef class Gen(Gen_base): """ sig_on() if n <= 0: - return new_gen(eint1(x.g, prec_bits_to_pari(precision))) + return new_gen(eint1(x.g, nbits2prec(precision))) else: - return new_gen(veceint1(x.g, stoi(n), prec_bits_to_pari(precision))) + return new_gen(veceint1(x.g, stoi(n), nbits2prec(precision))) log_gamma = Gen_base.lngamma - def polylog(x, long m, long flag=0, unsigned long precision=0): + def polylog(x, long m, long flag=0, + unsigned long precision=DEFAULT_BITPREC): """ x.polylog(m,flag=0): m-th polylogarithm of x. flag is optional, and can be 0: default, 1: D_m -modified m-th polylog of x, 2: @@ -3028,9 +3028,9 @@ cdef class Gen(Gen_base): -0.400459056163451 """ sig_on() - return new_gen(polylog0(m, x.g, flag, prec_bits_to_pari(precision))) + return new_gen(polylog0(m, x.g, flag, nbits2prec(precision))) - def sqrtn(x, n, unsigned long precision=0): + def sqrtn(x, n, unsigned long precision=DEFAULT_BITPREC): r""" x.sqrtn(n): return the principal branch of the n-th root of x, i.e., the one such that @@ -3092,7 +3092,7 @@ cdef class Gen(Gen_base): cdef GEN ans, zetan cdef Gen t0 = objtogen(n) sig_on() - ans = gsqrtn(x.g, t0.g, &zetan, prec_bits_to_pari(precision)) + ans = gsqrtn(x.g, t0.g, &zetan, nbits2prec(precision)) return new_gens2(ans, zetan) def ffprimroot(self): @@ -4533,7 +4533,8 @@ cdef class Gen(Gen_base): g = polint(self.g, t0.g, t1.g, &dy) return new_gens2(g, dy) - def ellwp(self, z='z', long n=20, long flag=0, unsigned long precision=0): + def ellwp(self, z='z', long n=20, long flag=0, + unsigned long precision=DEFAULT_BITPREC): """ Return the value or the series expansion of the Weierstrass `P`-function at `z` on the lattice `self` (or the lattice @@ -4611,7 +4612,7 @@ cdef class Gen(Gen_base): elif typ(g0) == t_RFRAC: g0 = rfrac_to_ser(g0, n+4) - cdef GEN r = ellwp0(self.g, g0, flag, prec_bits_to_pari(precision)) + cdef GEN r = ellwp0(self.g, g0, flag, nbits2prec(precision)) if flag == 1 and have_ellwp_flag1_bug(): # Work around ellwp() bug: double the second element set_gel(r, 2, gmulgs(gel(r, 2), 2)) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index 528db5c7..805f8868 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -6,6 +6,12 @@ from .gen cimport Gen cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept cpdef long default_bitprec() noexcept +cdef extern from *: + """ + #define DEFAULT_BITPREC prec2nbits(DEFAULTPREC) + """ + long DEFAULT_BITPREC + cdef class Pari_auto: pass diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 74e1059e..58952e2c 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -376,7 +376,7 @@ cpdef long default_bitprec() noexcept: >>> default_bitprec() 64 """ - return prec2nbits(LOWDEFAULTPREC) + return DEFAULT_BITPREC # Callbacks from PARI to print stuff using sys.stdout.write() instead From d831d597de2079f2102aab2da29faebe03b78870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Fri, 1 Nov 2024 17:59:55 -0300 Subject: [PATCH 12/13] Drop prec_bits_to_pari --- cypari2/pari_instance.pxd | 1 - cypari2/pari_instance.pyx | 29 ----------------------------- 2 files changed, 30 deletions(-) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index 805f8868..d56f2c2d 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -3,7 +3,6 @@ cimport cython from .gen cimport Gen -cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept cpdef long default_bitprec() noexcept cdef extern from *: diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index 58952e2c..cfb8ecc3 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -299,10 +299,6 @@ from .stack cimport (new_gen, new_gen_noclear, clear_stack, from .handle_error cimport _pari_init_error_handling from .closure cimport _pari_init_closure -# Default precision (in PARI words) for the PARI library interface, -# when no explicit precision is given and the inputs are exact. -cdef long prec = prec_bits_to_pari(53) - ################################################################# # conversions between various real precision models @@ -341,31 +337,6 @@ def prec_dec_to_bits(long prec_in_dec): return int(prec_in_dec*log_10 + 1.0) # Add one to round up -cpdef long prec_bits_to_pari(unsigned long prec_in_bits) noexcept: - r""" - Convert from precision expressed in bits to pari real precision - expressed in words. Note: this rounds up to the nearest word, - adjusts for the two codewords of a pari real, and is - architecture-dependent. - - Examples: - - >>> from cypari2.pari_instance import prec_bits_to_pari - >>> import sys - >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' - >>> prec_bits_to_pari(70) == (5 if bitness == '32' else 4) - True - - >>> ans32 = [(32, 3), (64, 4), (96, 5), (128, 6), (160, 7), (192, 8), (224, 9), (256, 10)] - >>> ans64 = [(32, 3), (64, 3), (96, 4), (128, 4), (160, 5), (192, 5), (224, 6), (256, 6)] - >>> [(32*n, prec_bits_to_pari(32*n)) for n in range(1, 9)] == (ans32 if bitness == '32' else ans64) - True - """ - if not prec_in_bits: - return prec - return nbits2prec(prec_in_bits) - - cpdef long default_bitprec() noexcept: r""" Return the default precision in bits. From 137caa8d45e39f103c19a7d29f85a8d158ecdbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sat, 2 Nov 2024 12:55:54 -0300 Subject: [PATCH 13/13] Restore prec_words_to_bits as deprecated function This is needed to support sagemath < 10.5. --- cypari2/pari_instance.pxd | 2 ++ cypari2/pari_instance.pyx | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/cypari2/pari_instance.pxd b/cypari2/pari_instance.pxd index d56f2c2d..d6a75a7f 100644 --- a/cypari2/pari_instance.pxd +++ b/cypari2/pari_instance.pxd @@ -3,6 +3,8 @@ cimport cython from .gen cimport Gen +# DEPRECATED INTERNAL FUNCTION used (incorrectly) in sagemath < 10.5 +cpdef long prec_words_to_bits(long prec_in_words) noexcept cpdef long default_bitprec() noexcept cdef extern from *: diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx index cfb8ecc3..3e21a7da 100644 --- a/cypari2/pari_instance.pyx +++ b/cypari2/pari_instance.pyx @@ -337,6 +337,36 @@ def prec_dec_to_bits(long prec_in_dec): return int(prec_in_dec*log_10 + 1.0) # Add one to round up +cpdef long prec_words_to_bits(long prec_in_words) noexcept: + r""" + Deprecated internal function. Used (incorrectly) in sagemath < 10.5. + + Convert from pari real precision expressed in words to precision + expressed in bits. Note: this adjusts for the two codewords of a + pari real, and is architecture-dependent. + + Examples: + + >>> from cypari2.pari_instance import prec_words_to_bits + >>> import sys + >>> import warnings + >>> warnings.simplefilter("ignore") + >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' + >>> prec_words_to_bits(10) == (256 if bitness == '32' else 512) + True + + >>> ans32 = [(3, 32), (4, 64), (5, 96), (6, 128), (7, 160), (8, 192), (9, 224)] + >>> ans64 = [(3, 64), (4, 128), (5, 192), (6, 256), (7, 320), (8, 384), (9, 448)] # 64-bit + >>> [(n, prec_words_to_bits(n)) for n in range(3, 10)] == (ans32 if bitness == '32' else ans64) + True + """ + from warnings import warn + warn("'prec_words_to_bits` in cypari2 is internal and deprecated", + DeprecationWarning) + # see user's guide to the pari library, page 10 + return (prec_in_words - 2) * BITS_IN_LONG + + cpdef long default_bitprec() noexcept: r""" Return the default precision in bits.