-
-
Notifications
You must be signed in to change notification settings - Fork 642
Speed up roots
when multiplicities=False
for polynomials over finite fields
#40494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
roots
when multiplicities=False
for polynomials over finite fields
67197e0
to
8c7d78e
Compare
In the worst case i.e. f is already a product of linear polynomials, how slow is the |
50b55f3
to
b992740
Compare
ehm, idrk, but my guess would be the difference would be more or less negligible in most cases |
Do some benchmark then? Also does this work when the modulus is more than 64 bits? I think normal |
yes, see the example in the description (also we don't do pow without a modulus) |
After some testing, the difference is < 1ms, should be fine? |
okay. Do add a test that would have been (very) slow before the change and fast (let's say <1s) after the change. You may want to Does this actually support polynomials over any finite fields (e.g. |
My current implementation only works for finite fields that are a quotient of ℤ |
I don't think that's true, exact same concept applies just raise to the actual order of the larger field. sage: p = random_prime(2**64)
sage: F = GF((p, 5))
sage: R.<x> = F[]
sage: f = R.random_element(degree=500)
sage: %time f.roots()
CPU times: user 5.04 s, sys: 10.1 ms, total: 5.05 s
Wall time: 5.04 s
[(1696449494167646524*z5^4 + 8871908504779766200*z5^3 + 75123468697369816*z5^2 + 8425597716018871725*z5 + 3317261663788709534,
1),
(12557525520458311272*z5^4 + 1975064827054420205*z5^3 + 11479291003439526237*z5^2 + 11561078139694077531*z5 + 7844731532039912253,
1)]
sage: %time (pow(x, F.order(), f)-x).gcd(f).roots()
CPU times: user 1.93 s, sys: 301 μs, total: 1.93 s
Wall time: 1.93 s
[(1696449494167646524*z5^4 + 8871908504779766200*z5^3 + 75123468697369816*z5^2 + 8425597716018871725*z5 + 3317261663788709534,
1),
(12557525520458311272*z5^4 + 1975064827054420205*z5^3 + 11479291003439526237*z5^2 + 11561078139694077531*z5 + 7844731532039912253,
1)] |
My implementation only works for finite fields that are a quotient of ℤ, respectively thats the only time its actually called AFAICT (as it is right now) |
and also the something like R = f.parent()
x = R.gen()
p = R.base_ring().order()
g = pow(x, p, f) - x
g = f.gcd(g)
return g._roots_from_factorization(g.factor(), False) could (i think?), work for all finite fields? |
You can use |
Did you investigate calling out to pari and using |
Using the polynomial from the test I wrote: sage: set_random_seed(31337)
sage: p = random_prime(2^128)
sage: R.<x> = GF(p)[]
sage: f = R.random_element(degree=5000)
sage: f.roots(multiplicities=False)
sage: %timeit pari.polrootsmod(f)
1.81 s ± 43.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
sage: %timeit (pow(x, F.order(), f)-x).gcd(f).roots()
388 ms ± 3.23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
sage: I also tried some other stuff, and while its faster than just |
8153cab
to
ab30868
Compare
- ``kwargs`` - ignored | ||
|
||
TESTS:: | ||
We can take the roots of a polynomial defined over a finite field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this documentation is incorrectly formatted (actually this wouldn't show up in the documentation anyway, but you should format it correctly regardless)
Search for TESTS:
in the code base for examples.
We can take the roots of a polynomial defined over a finite field | ||
|
||
We can take the roots of a polynomial defined over a finite field | ||
|
||
sage: set_random_seed(31337) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only add 4 spaces of indentation relative to the line above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i just adapted what i saw in src/sage/rings/finite_rings/integer_mod_ring.py
, is there some sort of style guide for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's just RST. See also sage coding_basics docs page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only add 4 spaces of indentation relative to the line above.
this comment is still unaddressed.
wait for someone to approve workflows (after the change above) I suppose. But otherwise looks reasonable. |
956831e
to
3db456e
Compare
3db456e
to
3d40a16
Compare
apart from https://github.com/sagemath/sage/pull/40494/files#r2248968501 , if tests pass (wait for someone to approve workflows…), should be good. remaining issues are negligible. |
3d40a16
to
fdabf03
Compare
Locally tests are happy except for:
this one with an ordering issue |
I suggest changing that test to
|
8914795
to
538d018
Compare
- Add `_roots_univariate_polynomial` to the finite field base class - `IntegerModRing`s will also use this method to speed up root finding for its polynomials
edit: not sure when/where but I had |
538d018
to
602c423
Compare
I said |
602c423
to
544519b
Compare
oopsie, fixed now 😅 |
Speed up
f.roots
whenmultiplicities=False
for univariate polynomials over finite fieldsroots
of polynomials over finite fields is slower than it could be #35556📝 Checklist
I have created tests covering the changes.Current tests still pass** one test fails because of ordering?
⌛ Dependencies