diff --git a/src/sage/libs/pari/convert_sage.pxd b/src/sage/libs/pari/convert_sage.pxd index 263ac38a156..0a5969dc5db 100644 --- a/src/sage/libs/pari/convert_sage.pxd +++ b/src/sage/libs/pari/convert_sage.pxd @@ -11,3 +11,5 @@ cpdef Gen new_gen_from_rational(Rational self) cpdef pari_is_prime(Integer p) cpdef pari_is_prime_power(Integer q, bint get_data) +cpdef ulong pari_maxprime() +cpdef list pari_prime_range(long c_start, long c_stop, bint py_ints=False) diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index ba3f61b6da1..abee1fb141c 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -26,7 +26,8 @@ from cypari2.gen cimport objtogen from cypari2.stack cimport new_gen from .convert_gmp cimport INT_to_mpz, new_gen_from_mpz_t, new_gen_from_mpq_t, INTFRAC_to_mpq -from sage.libs.gmp.mpz cimport mpz_fits_slong_p, mpz_sgn, mpz_get_ui, mpz_set, mpz_set_si +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.rings.integer cimport smallInteger from sage.rings.all import RealField, ComplexField, QuadraticField @@ -527,3 +528,49 @@ cpdef pari_is_prime_power(Integer q, bint get_data): return (smallInteger(p), smallInteger(n)) if get_data else True else: return (q, smallInteger(0)) if get_data else False + + +cpdef ulong pari_maxprime(): + """ + Return to which limit PARI has computed the primes. + + EXAMPLES:: + + sage: from sage.libs.pari.convert_sage import pari_maxprime + sage: a = pari_maxprime() + sage: res = prime_range(2, 2*a) + sage: b = pari_maxprime() + sage: b >= 2*a + True + """ + return maxprime() + + +cpdef list pari_prime_range(long c_start, long c_stop, bint py_ints=False): + """ + Return a list of all primes between ``start`` and ``stop - 1``, inclusive. + + .. SEEALSO:: + + :func:`sage.rings.fast_arith.prime_range` + + TESTS:: + + sage: from sage.libs.pari.convert_sage import pari_prime_range + sage: pari_prime_range(2, 19) + [2, 3, 5, 7, 11, 13, 17] + """ + cdef long p = 0 + cdef byteptr pari_prime_ptr = diffptr + res = [] + while p < c_start: + NEXT_PRIME_VIADIFF(p, pari_prime_ptr) + while p < c_stop: + if py_ints: + res.append(p) + else: + z = PY_NEW(Integer) + mpz_set_ui(z.value, p) + res.append(z) + NEXT_PRIME_VIADIFF(p, pari_prime_ptr) + return res diff --git a/src/sage/rings/fast_arith.pyx b/src/sage/rings/fast_arith.pyx index d8485b70247..aecfdf6bb0f 100644 --- a/src/sage/rings/fast_arith.pyx +++ b/src/sage/rings/fast_arith.pyx @@ -36,11 +36,7 @@ Basic arithmetic with C integers # The int definitions from libc.math cimport sqrt -from sage.libs.gmp.mpz cimport mpz_set_ui -from sage.ext.stdsage cimport PY_NEW - -from sage.libs.pari.all import pari from sage.rings.integer cimport Integer cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): @@ -150,8 +146,6 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): - Robert Bradshaw (speedup using Pari prime table, py_ints option) """ cdef Integer z - cdef long c_start, c_stop, p - cdef byteptr pari_prime_ptr # input to pari.init_primes cannot be greater than 436273290 (hardcoded bound) DEF init_primes_max = 436273290 DEF small_prime_max = 436273009 # a prime < init_primes_max (preferably the largest) @@ -185,6 +179,8 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): algorithm = "pari_isprime" if algorithm == "pari_primes": + from sage.libs.pari.convert_sage import pari_maxprime, pari_prime_range + from sage.libs.pari import pari if max(start, stop or 0) > small_prime_max: raise ValueError('algorithm "pari_primes" is limited to primes larger than' @@ -192,35 +188,23 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): if stop is None: # In this case, "start" is really stop - c_start = 1 - c_stop = start + stop = start + start = 1 else: - c_start = start - c_stop = stop - if c_start < 1: - c_start = 1 - if c_stop <= c_start: + start = start + stop = stop + if start < 1: + start = 1 + if stop <= start: return [] - if maxprime() < c_stop: + if pari_maxprime() < stop: # Adding prime_gap_bound should be sufficient to guarantee an # additional prime, given that c_stop <= small_prime_max. - pari.init_primes(min(c_stop + prime_gap_bound, init_primes_max)) - assert maxprime() >= c_stop - - pari_prime_ptr = diffptr - p = 0 - res = [] - while p < c_start: - NEXT_PRIME_VIADIFF(p, pari_prime_ptr) - while p < c_stop: - if py_ints: - res.append(p) - else: - z = PY_NEW(Integer) - mpz_set_ui(z.value, p) - res.append(z) - NEXT_PRIME_VIADIFF(p, pari_prime_ptr) + pari.init_primes(min(stop + prime_gap_bound, init_primes_max)) + assert pari_maxprime() >= stop + + res = pari_prime_range(start, stop, py_ints) elif (algorithm == "pari_isprime") or (algorithm == "pari_primes"): from sage.arith.all import primes