#10635 closed enhancement (fixed)
refactor polynomial_element.pyx factor function
Reported by: | was | Owned by: | AlexGhitza |
---|---|---|---|
Priority: | minor | Milestone: | sage-4.7.2 |
Component: | basic arithmetic | Keywords: | sd32 |
Cc: | Merged in: | sage-4.7.2.alpha3 | |
Authors: | Christopher Hall | Reviewers: | Mariah Lenox, William Stein, Simon Spicer |
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
The "factor" function in polynomial_element.pyx needs to be refactored, because it has to be modified every time a new interesting base ring gets added to Sage.
Instead of importing a ton of different rings, the function should just call a method on the base ring, e.g.,
def _factor_univariate_polynomial(self, f): ...
Since the code in factor is for generic polynomials, it doesn't use their internal representation, so this should be fine. It just turns out that factoring algorithms depend a huge amount on the base ring, and polynomials get created over tons of different bases (but there are far less classes that derive from "polynomial").
I suggest for this ticket, at a minimum we add a quick "hasattr" check at the top of the current factor function, then leave the existing code. Then new code can be written to use this. In the near future somebody can move most of the imports and cases out the current factor function, so it becomes very short, and the code gets put in the right place.
A major motivation for this is that people create their own new rings R in external code that depends on sage, and want to be able to factor polynomials over R. They do *not* define a new class for polynomials over R. It seems silly for them to have to patch the core sage library to get factorization functionality.
Apply
to the Sage library.
Attachments (3)
Change History (18)
comment:1 follow-up: ↓ 13 Changed 8 years ago by
comment:2 Changed 8 years ago by
- Status changed from new to needs_review
The patch addresses issue (1) and is for Sage 4.6.2.
comment:3 Changed 8 years ago by
- Reviewers set to Mariah Lenox
- Status changed from needs_review to needs_info
Patch applied to sage-4.7.1.alpha2, then did 'sage -b', then 'make testlong'. All tests passed. Positive review!
cjh - you need to add your name to the author field.
comment:4 Changed 8 years ago by
- Status changed from needs_info to needs_review
comment:5 Changed 8 years ago by
- Status changed from needs_review to needs_work
The patch should have an example that illustrates that each added capability actually works. That could be a class created in a docstring, or a small demo class added to the source code with an example.
comment:6 Changed 8 years ago by
- Reviewers changed from Mariah Lenox to Mariah Lenox, William Stein
comment:7 Changed 8 years ago by
- Status changed from needs_work to needs_review
comment:8 Changed 8 years ago by
- Reviewers changed from Mariah Lenox, William Stein to Mariah Lenox, William Stein, Simon Spicer
- Status changed from needs_review to positive_review
Yep, looks fine. Test pass, code works, couldn't even find a typo. Note that this latest patch only sets it up so that if a base ring has a native _factor_univariate_polynomial()
or _roots_univariate_polynomial()
method, then those will be used instead of the generic factor()
and roots()
method in polynomial_element.pyx.
The ring-specific functionality of these two methods still needs to be moved across to their respective files; to address this I've created patch #11731.
comment:9 Changed 8 years ago by
- Keywords sd32 added
comment:10 Changed 8 years ago by
- Description modified (diff)
comment:11 Changed 8 years ago by
- Merged in set to sage-4.7.2.alpha3
- Resolution set to fixed
- Status changed from positive_review to closed
Changed 8 years ago by
Reviewer patch to fix doctest error on some systems (e.g. x86). Apply on top of other patch.
comment:12 Changed 8 years ago by
- Description modified (diff)
I've attached a reviewer patch fixing a doctest error in a factorization.
(The order of the factors changes, depending on the sign of a "zero" term in the polynomial which is one factor. The example now looks a bit ugly, but I don't want to wait until we have zero_at()
methods for all kinds of domains, and just tagging the whole doctest "# random
" would also be odd, IMHO. Note that it previously didn't fail on all 32-bit systems, e.g. not 32-bit SPARC, and tagging the results "# 32-bit
" and "# 64-bit
" would have been inadequate anyway, since the machine word width is completely unrelated, i.e., that the test failed on x86 processors only is just a weird coincidence.)
comment:13 in reply to: ↑ 1 Changed 8 years ago by
Factorization over function fields (provided by #9054) uses the function defined in this ticket (_factor_univariate_polynomial). However, in some cases it requires a parameter proof=False to work. So, the easy solution for #9054 was to add the default parameter proof=True to polynomial_element.factor() and pass it on to _factor_univariate_polynomial. So, to make #9054 work with this ticket, should we just pass on all *args and kwargs to _factor_univariate_polynomial? I do not understand what you mean by 'universally' but I guess it's related to this question.
Replying to cjh:
(3) Consider whether options such as 'multiplicities=False' should really be options to .univariate_polynomial_factor() or whether they can be handled 'universally'.
comment:14 Changed 8 years ago by
I opened a ticket for the function field case: #12100
As someone interested in this change, let me chime in with a few suggestions of my own.
(1) A similar refactoring should be done for roots(). It's true factor() can be used to find roots, but that's not necessarily the best approach. This suggests the names ._univariate_polynomial_x for x=factor,roots,etc.
(2) So-called 'modular' gcd algorithms give a real boost to rings where applicable, so it would be nice to let x=gcd in (1).
(3) Consider whether options such as 'multiplicities=False' should really be options to .univariate_polynomial_factor() or whether they can be handled 'universally'.