@@ -176,6 +176,24 @@ cdef class fmpq_poly(flint_poly):
176
176
def is_one (self ):
177
177
return < bint> fmpq_poly_is_one(self .val)
178
178
179
+ def leading_coefficient (self ):
180
+ """
181
+ Returns the leading coefficient of the polynomial.
182
+
183
+ >>> f = fmpq_poly([1, 2, 3])
184
+ >>> f
185
+ 3*x^2 + 2*x + 1
186
+ >>> f.leading_coefficient()
187
+ 3
188
+ """
189
+ cdef fmpq x
190
+ cdef slong d
191
+ d = fmpq_poly_degree(self .val)
192
+ x = fmpq.__new__ (fmpq)
193
+ if d >= 0 :
194
+ fmpq_poly_get_coeff_fmpq(x.val, self .val, d)
195
+ return x
196
+
179
197
def __call__ (self , other ):
180
198
t = any_as_fmpz(other)
181
199
if t is not NotImplemented :
@@ -393,28 +411,64 @@ cdef class fmpq_poly(flint_poly):
393
411
fmpq_poly_xgcd(res1.val, res2.val, res3.val, self .val, (< fmpq_poly> other).val)
394
412
return (res1, res2, res3)
395
413
396
- def factor (self ):
414
+ def factor (self , *, monic = False ):
397
415
"""
398
416
Factors *self* into irreducible polynomials. Returns (*c*, *factors*)
399
417
where *c* is the leading coefficient and *factors* is a list of
400
- (*poly*, *exp*) pairs with all *poly* monic .
418
+ (*poly*, *exp*).
401
419
402
420
>>> fmpq_poly.legendre_p(5).factor()
403
- (63 /8, [(x, 1), (x^4 + (-10/9 )*x^2 + 5/21 , 1)])
421
+ (1 /8, [(x, 1), (63* x^4 + (-70 )*x^2 + 15 , 1)])
404
422
>>> (fmpq_poly([1,-1],10) ** 5 * fmpq_poly([1,2,3],7)).factor()
423
+ (-1/700000, [(3*x^2 + 2*x + 1, 1), (x + (-1), 5)])
424
+
425
+ Since python-flint 0.7.0 this returns primitive denominator-free
426
+ factors consistent with ``fmpq_mpoly.factor()``. In previous versions
427
+ of python-flint all factors were made monic. Pass ``monic=True`` to get
428
+ monic factors instead.
429
+
430
+ >>> fmpq_poly.legendre_p(5).factor(monic=True)
431
+ (63/8, [(x, 1), (x^4 + (-10/9)*x^2 + 5/21, 1)])
432
+ >>> (fmpq_poly([1,-1],10) ** 5 * fmpq_poly([1,2,3],7)).factor(monic=True)
405
433
(-3/700000, [(x^2 + 2/3*x + 1/3, 1), (x + (-1), 5)])
406
434
407
435
"""
408
436
c, fac = self .numer().factor()
409
437
c = fmpq(c)
410
- for i in range (len (fac)):
411
- base, exp = fac[i]
412
- lead = base[base.degree()]
413
- base = fmpq_poly(base, lead)
414
- c *= lead ** exp
415
- fac[i] = (base, exp)
438
+
439
+ if monic:
440
+ for i in range (len (fac)):
441
+ base, exp = fac[i]
442
+ lead = base[base.degree()]
443
+ base = fmpq_poly(base, lead)
444
+ c *= lead ** exp
445
+ fac[i] = (base, exp)
446
+ else :
447
+ fac = [(fmpq_poly(f), m) for f, m in fac]
448
+
416
449
return c / self .denom(), fac
417
450
451
+ def factor_squarefree (self ):
452
+ """
453
+ Factors *self* into square-free polynomials. Returns (*c*, *factors*)
454
+ where *c* is the leading coefficient and *factors* is a list of
455
+ (*poly*, *exp*).
456
+
457
+ >>> x = fmpq_poly([0, 1])
458
+ >>> p = x**2 * (x/2 - 1)**2 * (x + 1)**3
459
+ >>> p
460
+ 1/4*x^7 + (-1/4)*x^6 + (-5/4)*x^5 + 1/4*x^4 + 2*x^3 + x^2
461
+ >>> p.factor_squarefree()
462
+ (1/4, [(x^2 + (-2)*x, 2), (x + 1, 3)])
463
+ >>> p.factor()
464
+ (1/4, [(x, 2), (x + (-2), 2), (x + 1, 3)])
465
+
466
+ """
467
+ c, fac = self .numer().factor_squarefree()
468
+ c = fmpq(c) / self .denom()
469
+ fac = [(fmpq_poly(f), m) for f, m in fac]
470
+ return c, fac
471
+
418
472
def sqrt (self ):
419
473
"""
420
474
Return the exact square root of this polynomial or ``None``.
0 commit comments