Skip to content

Conversation

@kylehofmann
Copy link
Contributor

The zero polynomial doesn't have a factorization or square-free factorization, so

PolynomialRing(GF(7), 'x').zero().factor()
PolynomialRing(GF(7), 'x').zero().squarefree_decomposition()

should raise errors instead of returning zero. This patch fixes this behavior.

@github-actions
Copy link

Documentation preview for this PR (built with commit e9b8e84; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

Copy link
Collaborator

@kwankyu kwankyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@vbraun vbraun merged commit a875710 into sagemath:develop Sep 29, 2024
vbraun pushed a commit to vbraun/sage that referenced this pull request Nov 2, 2024
sagemathgh-38722: Roots of polynomials mod n
    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

Presently, Sage implements root-finding over Z/n in a way that requires
time exponential in e, where e is the largest exponent of a prime
divisor of n.  For example, while Sage is capable of the following, it
takes 8 minutes and 40 seconds on the laptop I'm using:
```python
R.<x> = Zmod(2^30)[]
(x^2 - 1).roots(multiplicities=False)
```
This patch implements a better algorithm.  Like the present one, it uses
the Chinese Remainder Theorem to reduce to the case of prime powers.
Unlike the present algorithm, it finds roots modulo prime powers using
Hensel lifting.  When the root is non-singular mod p, it uses Newton
iteration and converges quadratically.  When the root is singular,
lifting is done one power at a time, and the running time is bounded by
the product of e and the maximum number of roots modulo any p^d with d ≤
e.  With this patch, the above code snippet takes 32 milliseconds; even
lifting modulo 2^1000 takes less than a second.

Depends on sagemath#38720.
    
URL: sagemath#38722
Reported by: Kyle Hofmann
Reviewer(s): Kyle Hofmann, Vincent Macri
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants