# HG changeset patch
# User Chris Hall <chall14@uwyo.edu> and William Stein <wstein@gmail.com>
# Date 1305045830 21600
# Node ID 5fc756b95966cbb64c7f6f06e1ac5dbade9126d9
# Parent 26318599b34dd9af6840a4f1e1adee629ff590d2
Trac 10635: added hooks in roots() and factor() for fieldprovided routines
diff git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
a

b


2477  2477  
2478  2478  sage: expand(F) 
2479  2479  2*x^10 + 2*x + 2*a 
 2480  
 2481  A new ring. In the example below, we add the special method 
 2482  _factor_univariate_polynomial to the base ring, and observe 
 2483  that this method is called instead to factor univariate 
 2484  polynomials over this ring. This facility can be used to 
 2485  easily extend polynomial factorization to work over new rings 
 2486  you introduce:: 
 2487  
 2488  sage: R.<x> = QQ[] 
 2489  sage: (x^2 + 1).factor() 
 2490  x^2 + 1 
 2491  sage: QQ._factor_univariate_polynomial = lambda f: f.change_ring(CDF).factor() 
 2492  sage: (x^2 + 1).factor() 
 2493  (x  ... + I) * (x  I) 
 2494  sage: del QQ._factor_univariate_polynomial 
2480  2495  
2481  2496  Arbitrary precision real and complex factorization:: 
2482  2497  
… 
… 

2587  2602  (5) * (x  16.00000000000000?) * (x  5.000000000000000?) * (x  1.959674775249769?) * (x + 2.959674775249769?) * (x^2  2.854101966249685?*x + 15.47213595499958?) * (x^2 + 1.909830056250526?*x + 1.660606461254312?) * (x^2 + 3.854101966249685?*x + 6.527864045000421?) * (x^2 + 13.09016994374948?*x + 93.33939353874569?) 
2588  2603  
2589  2604  TESTS: 
2590   
 2605  
2591  2606  This came up in ticket #7088:: 
2592  2607  
2593  2608  sage: R.<x>=PolynomialRing(ZZ) 
… 
… 

2748  2763  raise ValueError, "factorization of 0 not defined" 
2749  2764  if self.degree() == 0: 
2750  2765  return Factorization([], unit=self[0]) 
 2766  
 2767  R = self.parent().base_ring() 
 2768  if hasattr(R, '_factor_univariate_polynomial'): 
 2769  return R._factor_univariate_polynomial(self) 
 2770  
2751  2771  G = None 
2752   
2753   R = self.parent().base_ring() 
2754  2772  ch = R.characteristic() 
2755  2773  if not (ch == 0 or sage.rings.arith.is_prime(ch)): 
2756  2774  raise NotImplementedError, "factorization of polynomials over rings with composite characteristic is not implemented" 
… 
… 

2763  2781  from sage.rings.rational_field import is_RationalField 
2764  2782  
2765  2783  n = None 
 2784  
2766  2785  if is_IntegerModRing(R) or is_IntegerRing(R) or is_RationalField(R): 
2767  2786  
2768  2787  try: 
… 
… 

4356  4375  sage: g.roots(multiplicities=False) 
4357  4376  [4, 2] 
4358  4377  
 4378  A new ring. In the example below, we add the special method 
 4379  _roots_univariate_polynomial to the base ring, and observe 
 4380  that this method is called instead to find roots of 
 4381  polynomials over this ring. This facility can be used to 
 4382  easily extend root finding to work over new rings you 
 4383  introduce:: 
 4384  
 4385  sage: R.<x> = QQ[] 
 4386  sage: (x^2 + 1).roots() 
 4387  [] 
 4388  sage: g = lambda f, *args, **kwds: f.change_ring(CDF).roots() 
 4389  sage: QQ._roots_univariate_polynomial = g 
 4390  sage: (x^2 + 1).roots() 
 4391  [(...  1.0*I, 1), (1.0*I, 1)] 
 4392  sage: del QQ._roots_univariate_polynomial 
 4393  
4359  4394  An example over RR, which illustrates that only the roots in RR are 
4360  4395  returned:: 
4361  4396  
… 
… 

4747  4782  sage: [abs(p(rt)) < eps for rt in rts] == [True]*50 
4748  4783  True 
4749  4784  """ 
 4785  K = self.parent().base_ring() 
 4786  if hasattr(K, '_roots_univariate_polynomial'): 
 4787  return K._roots_univariate_polynomial(self, ring=ring, multiplicities=multiplicities, algorithm=algorithm) 
 4788  
4750  4789  seq = [] 
4751   
4752   K = self.parent().base_ring() 
4753  4790  L = K if ring is None else ring 
4754   
 4791  
4755  4792  late_import() 
4756  4793  
4757  4794  input_fp = (is_RealField(K) 