Repository navigation
gh-153222: Add math.integer.isprime() function - #160678
StanFromIreland wants to merge 4 commits into
Conversation
Draft implementation of prime-number functionality for the math.integer
module (deferred out of the initial PEP 791 scope), supporting integers
less than 2**64.
isprime() uses the deterministic Miller-Rabin test: bases {2, 7, 61}
below 4759123141, Jim Sinclair's seven bases up to 2**64 (verified
against the Feitsma-Galway list of base-2 strong pseudoprimes). The
result is exact for the whole supported range; larger arguments raise
OverflowError.
primes(start=2, stop=None) returns an iterator of the primes in
[start, stop), unbounded if stop is None.
Neither function is mirrored into the math namespace (PEP 791).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documentation build overview
|
| The following functions are provided by this module. | ||
| Unless stated otherwise below, | ||
| all return values are computed exactly and are integers. |
There was a problem hiding this comment.
I think this change is not required, no? isprime() returns an integer (boolean) and it's exact.
| Return ``True`` if *n* is a prime number, ``False`` otherwise. | ||
|
|
||
| A prime number is a natural number greater than 1 | ||
| that is not a product of two smaller natural numbers. | ||
| Negative numbers, ``0`` and ``1`` are not prime. | ||
|
|
||
| The argument must be less than 2\ :sup:`64`; | ||
| raises :exc:`OverflowError` otherwise. |
There was a problem hiding this comment.
I don't think it's an acceptable API.
- it isn't compatible with gmpy2 (is_prime() returns True for probable primes)
- can't be used as an alternative to gmpy2 in applications like SymPy or Mpmath, currently using own isprime() helpers.
I suggest using Miller-Rabin test without constraints on the number range. You can document that test is certain for integers < 2^64, perhaps as an implementation detail. Or introduce instead API like gmpy2.is_probab_prime (ternary logic: definitely prime, probably prime, or definitely composite).
|
For primality testing we should definitely use MR testing and make sure that we just do not limit ourselves to 64 bits. I think we should rather keep the other PR. |
This builds (and trims) on #153224.
As I suggest in #153224 (comment), it drops
math.integer.primes().And, the strong probable prime test now runs in Montgomery form. A context (inverse of
n mod 2**64,2**64 mod n, and the odd part ofn - 1) is computed once pern, and each modular multiplication costs two 64-bit high products instead of a 128-bit division. The reduction is then written subtractively so no intermediate exceeds 64 bits, which keepsnclose to 2**64. FLINT made the same change ton_is_primein flintlib/flint#2519 and reported 1.2x to 1.5x speedups for 33 to 64 bit inputs. Benchmarking ourisprimeon an optimised build (compared to the original PR), I get a nice speedup:Benchmark script
CC @mdickinson @tim-one