Skip to content

Commit c85882b

Browse files
author
Release Manager
committed
gh-35847: Integer.{perfect_power,is_prime_power,is_irreducible}: Handle easy cases without PARI <!-- Please provide a concise, informative and self-explanatory title. --> <!-- Don't put issue numbers in the title. Put it in the Description below. --> <!-- For example, instead of "Fixes #12345", use "Add a new method to multiply two integers" --> ### 📚 Description <!-- Describe your changes here in detail. --> Taking care of small primes and powers of two. <!-- Why is this change required? What problem does it solve? --> In particular, this allows us to set up `GF(2)` without pulling in PARI, and avoids many `# optional` tags in `sage.combinat.designs` and `sage.combinat.posets`. <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> - Part of: #29705 - Cherry-picked from: #35095 <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #35847 Reported by: Matthias Köppe Reviewer(s): Jonathan Kliem, Matthias Köppe
2 parents 1ea6ce9 + d2c9c5e commit c85882b

File tree

1 file changed

+47
-6
lines changed

1 file changed

+47
-6
lines changed

src/sage/rings/integer.pyx

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,23 +4812,44 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
48124812
48134813
sage: 144.perfect_power() # optional - sage.libs.pari
48144814
(12, 2)
4815-
sage: 1.perfect_power() # optional - sage.libs.pari
4815+
sage: 1.perfect_power()
48164816
(1, 1)
4817-
sage: 0.perfect_power() # optional - sage.libs.pari
4817+
sage: 0.perfect_power()
48184818
(0, 1)
4819-
sage: (-1).perfect_power() # optional - sage.libs.pari
4819+
sage: (-1).perfect_power()
48204820
(-1, 1)
48214821
sage: (-8).perfect_power() # optional - sage.libs.pari
48224822
(-2, 3)
4823-
sage: (-4).perfect_power() # optional - sage.libs.pari
4823+
sage: (-4).perfect_power()
48244824
(-4, 1)
48254825
sage: (101^29).perfect_power() # optional - sage.libs.pari
48264826
(101, 29)
48274827
sage: (-243).perfect_power() # optional - sage.libs.pari
48284828
(-3, 5)
48294829
sage: (-64).perfect_power() # optional - sage.libs.pari
48304830
(-4, 3)
4831+
4832+
TESTS::
4833+
4834+
sage: 4.perfect_power()
4835+
(2, 2)
4836+
sage: 256.perfect_power()
4837+
(2, 8)
48314838
"""
4839+
cdef long n
4840+
# Fast PARI-free path
4841+
if mpz_fits_slong_p(self.value):
4842+
n = mpz_get_si(self.value)
4843+
if -8 < n < 4:
4844+
return self, one
4845+
if n >= 4:
4846+
if not (n & 1):
4847+
if mpz_popcount(self.value) == 1:
4848+
return smallInteger(2), smallInteger(mpz_sizeinbase(self.value, 2) - 1)
4849+
if n < 1000:
4850+
if _small_primes_table[n >> 1]:
4851+
return self, one
4852+
48324853
parians = self.__pari__().ispower()
48334854
return Integer(parians[1]), Integer(parians[0])
48344855

@@ -5164,11 +5185,32 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
51645185
sage: n = 150607571^14
51655186
sage: n.is_prime_power() # optional - sage.libs.pari
51665187
True
5188+
5189+
TESTS::
5190+
5191+
sage: 2.is_prime_power(get_data=True)
5192+
(2, 1)
5193+
sage: 4.is_prime_power(get_data=True)
5194+
(2, 2)
5195+
sage: 512.is_prime_power(get_data=True)
5196+
(2, 9)
51675197
"""
5198+
cdef long n
5199+
51685200
if mpz_sgn(self.value) <= 0:
51695201
return (self, zero) if get_data else False
51705202

51715203
if mpz_fits_slong_p(self.value):
5204+
# Fast PARI-free path
5205+
n = mpz_get_si(self.value)
5206+
if not (n & 1):
5207+
if mpz_popcount(self.value) != 1:
5208+
return (self, zero) if get_data else False
5209+
return (smallInteger(2), smallInteger(mpz_sizeinbase(self.value, 2) - 1)) if get_data else True
5210+
if n < 1000:
5211+
if _small_primes_table[n >> 1]:
5212+
return (self, one) if get_data else True
5213+
51725214
global pari_is_prime_power
51735215
if pari_is_prime_power is None:
51745216
try:
@@ -5178,7 +5220,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
51785220
if pari_is_prime_power is not None:
51795221
return pari_is_prime_power(self, get_data)
51805222

5181-
cdef long n
51825223
if proof is None:
51835224
from sage.structure.proof.proof import get_flag
51845225
proof = get_flag(proof, "arithmetic")
@@ -5362,7 +5403,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
53625403
True
53635404
"""
53645405
cdef Integer n = self if self >= 0 else -self
5365-
return n.__pari__().isprime()
5406+
return n.is_prime(proof=True)
53665407

53675408
def is_pseudoprime(self):
53685409
r"""

0 commit comments

Comments
 (0)