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
is_primitive is computes integer prime factorization on every call #5535
Comments
comment:1
I think the It might be a good idea to ask somebody else how they feel about this patch because we introduce a neat way to shoot oneself in the foot. btw. when you add a patch you should add |
comment:2
I'm fine with the shoot-yourself-in-the-foot part of the patch... it seems sufficiently well documented. |
comment:3
BTW, I do agree with John Cremona's comment that for polynomials over a ring, "primitive" means something totally different, and something should be done to try to keep people from thinking that this tests for that kind of primitive (preferably more than just documentation). |
comment:4
Ryan, do you want to add some docs while you're on it to address John's complaint? |
comment:5
I added some verbiage to the is_primitive docstring to indicate that it's only useful for finite fields, and referenced the new trac #5561 for resolving its proper placement. Is this sufficient for a positive review? |
comment:6
This looks ok to me, though I think you could delete the second paragraph of the docstring (it's a bit too detailed). For the code itself one could also use the (generic) order_from_multiple() function like this:
since the order_from_multiple() function (which I wrote) already takes the list of prime divisors of n as a parameter, computing it if it is not given. I just tried that on a poly of degree 257 over GF(2) and it worked fine (I was impressed at Sage's ability to factor the 78-digit number There seems to be quite a large literature on finding primitive polynomials which may include better tests of primitivity. I'll take a look at some of those when I'm back at work. |
comment:7
One more comment: NTL has efficient routines for modular exponentiation modulo polynomials over GF(p) which could be used to find the order of X modulo f(X) and hence test primitivity of f: see http://www.shoup.net/ntl/doc/ZZ_pX.txt. This would entirely independent of the improvement implemented in this patch, of course. |
comment:8
I'll give this a positive review if two things are changed: (1) replace n = p ** self.degree() - 1 by n = q ** self.degree() - 1 where q = self.base_ring().order(), which is the same as at present for polynomials defined over prime fields, but now gives a correct answer for polynomials defined over non-prime finite fields; (2) put in tests for k=self.base_ring() that k.is_field() and k.is_finite(), perhaps raising a NotImplementedError, since otherwise the result is rather random:
|
comment:9
Thanks for the excellent suggestions. I replaced most of the existing code with Let me know if I can fix anything else. When this patch receives a positive review, I plan to implement cremona's suggestion for #5561 by replacing the sanity check with the proper ring-theoretic primitivity check (since he came up with a 3-line solution to the problem :-). |
comment:10
Positive review! I have made some cosmetic changes, only to the docstring and NotImplemented message, and added some more relevant tests. The second patch replaces the first, and (also) applies to 3.4. |
comment:11
Merged trac_5535_is_primitive_avoid_duplicate_factorizations.2.patch in Sage 3.4.1.alpha0. Cheers, Michael |
comment:12
Replying to @rhinton:
Is it possible for you to give some system/architecture information of the machine you used to obtain the above timing statistics? It would also be good to include the actual code that produces those timing improvements. What I'm looking for are a "before" and an "after" sections to clearly show the timing improvements in your patch. |
comment:13
For future reference, I am running a Pentium 4, 2.4 GHz with 2 GB of RAM. Here is some sample code I used to measure the performance difference on my system.
The actual speedup, of course, depends on how many times you're calling is_primitive for the same degree (if you have to call prime_divisors() for each degree) and the actual degrees. Typically speedups will be greater for higher degrees. |
The current (generic) code for is_primitive in rings/polynomial/polynomial_element.pyx is
Note that the integer n and its prime divisors are calculated as part of the algorithm. This calculation can be lengthy for large n, and can dominate the running time of the algorithm.
The proposed patch adds optional arguments to is_primitive to provide the results of these calculations -- useful for is_primitive tests for multiple polynomials of the same degree.
CC: @malb @JohnCremona
Component: algebra
Issue created by migration from https://trac.sagemath.org/ticket/5535
The text was updated successfully, but these errors were encountered: