Polynomials
Polynomial manipulation algorithms and algebraic objects.
Computations with polynomials are at the core of computer algebra and having a fast and robust polynomials manipulation module is a key for building a powerful symbolic manipulation system. Here we document a dedicated module for computing in polynomial algebras over various coefficient domains.
There is a vast number of methods implemented, ranging from simple tools like polynomial division, to advanced concepts including Gröbner bases and multivariate factorization over algebraic number domains.
Basic polynomial manipulation functions
User-friendly public interface to polynomial functions.
- class diofant.polys.polytools.GroebnerBasis(F, *gens, **args)[source]
Represents a reduced Gröbner basis.
- contains(poly)[source]
Check if
poly
belongs the ideal generated byself
.Examples
>>> f = 2*x**3 + y**3 + 3*y >>> G = groebner([x**2 + y**2 - 1, x*y - 2])
>>> G.contains(f) True >>> G.contains(f + 1) False
- property dimension
Dimension of the ideal, generated by a Gröbner basis.
- property independent_sets
Compute independent sets for ideal, generated by a Gröbner basis.
References
[KW88]
- reduce(expr, auto=True)[source]
Reduces a polynomial modulo a Gröbner basis.
Given a polynomial
f
and a set of polynomialsG = (g_1, ..., g_n)
, computes a set of quotientsq = (q_1, ..., q_n)
and the remainderr
such thatf = q_1*f_1 + ... + q_n*f_n + r
, wherer
vanishes orr
is a completely reduced polynomial with respect toG
.Examples
>>> f = 2*x**4 - x**2 + y**3 + y**2 >>> G = groebner([x**3 - x, y**3 - y])
>>> G.reduce(f) ([2*x, 1], x**2 + y**2 + y) >>> Q, r = _
>>> expand(sum(q*g for q, g in zip(Q, G)) + r) 2*x**4 - x**2 + y**3 + y**2 >>> _ == f True
- set_order(order)[source]
Convert a Gröbner basis from one ordering to another.
Notes
The FGLM algorithm [FaugereGLM93] used to convert reduced Gröbner bases of zero-dimensional ideals from one ordering to another. Sometimes it is infeasible to compute a Gröbner basis with respect to a particular ordering directly.
Examples
>>> F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1] >>> G = groebner(F, order='grlex')
>>> G.set_order('lex') == groebner(F, order='lex') True
- diofant.polys.polytools.LC(f, *gens, **args)[source]
Return the leading coefficient of
f
.Examples
>>> LC(4*x**2 + 2*x*y**2 + x*y + 3*y) 4
- diofant.polys.polytools.LM(f, *gens, **args)[source]
Return the leading monomial of
f
.Examples
>>> LM(4*x**2 + 2*x*y**2 + x*y + 3*y) x**2
- diofant.polys.polytools.LT(f, *gens, **args)[source]
Return the leading term of
f
.Examples
>>> LT(4*x**2 + 2*x*y**2 + x*y + 3*y) 4*x**2
- class diofant.polys.polytools.Poly(rep, *gens, **args)[source]
Generic class for representing polynomial expressions.
- EC(order=None)[source]
Returns the last non-zero coefficient of
self
.Examples
>>> (x**3 + 2*x**2 + 3*x).as_poly().EC() 3
- EM(order=None)[source]
Returns the last non-zero monomial of
self
.Examples
>>> (4*x**2 + 2*x*y**2 + x*y + 3*y).as_poly().EM() x**0*y**1
- ET(order=None)[source]
Returns the last non-zero term of
self
.Examples
>>> (4*x**2 + 2*x*y**2 + x*y + 3*y).as_poly().ET() (x**0*y**1, 3)
- LC(order=None)[source]
Returns the leading coefficient of
self
.Examples
>>> (4*x**3 + 2*x**2 + 3*x).as_poly().LC() 4
- LM(order=None)[source]
Returns the leading monomial of
self
.The leading monomial signifies the the monomial having the highest power of the principal generator in the polynomial expression.
Examples
>>> (4*x**2 + 2*x*y**2 + x*y + 3*y).as_poly().LM() x**2*y**0
- LT(order=None)[source]
Returns the leading term of
self
.The leading term signifies the term having the highest power of the principal generator in the polynomial expression.
Examples
>>> (4*x**2 + 2*x*y**2 + x*y + 3*y).as_poly().LT() (x**2*y**0, 4)
- TC()[source]
Returns the trailing coefficient of
self
.Examples
>>> (x**3 + 2*x**2 + 3*x).as_poly().TC() 0
- all_coeffs()[source]
Returns all coefficients from a univariate polynomial
self
.Examples
>>> (x**3 + 2*x - 1).as_poly().all_coeffs() [-1, 2, 0, 1]
- all_roots(multiple=True, radicals=True)[source]
Return a list of real and complex roots with multiplicities.
Examples
>>> (2*x**3 - 7*x**2 + 4*x + 4).as_poly().all_roots() [-1/2, 2, 2] >>> (x**3 + x + 1).as_poly().all_roots() [RootOf(x**3 + x + 1, 0), RootOf(x**3 + x + 1, 1), RootOf(x**3 + x + 1, 2)]
- property args
Don’t mess up with the core.
Examples
>>> (x**2 + 1).as_poly().args (x**2 + 1, x)
- as_dict(native=False)[source]
Switch to a
dict
representation.Examples
>>> (x**2 + 2*x*y**2 - y).as_poly().as_dict() {(0, 1): -1, (1, 2): 2, (2, 0): 1}
- as_expr(*gens)[source]
Convert a Poly instance to an Expr instance.
Examples
>>> f = (x**2 + 2*x*y**2 - y).as_poly()
>>> f.as_expr() x**2 + 2*x*y**2 - y >>> f.as_expr({x: 5}) 10*y**2 - y + 25 >>> f.as_expr(5, 6) 379
- cancel(other, include=False)[source]
Cancel common factors in a rational function
self/other
.Examples
>>> (2*x**2 - 2).as_poly().cancel((x**2 - 2*x + 1).as_poly()) (1, Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))
>>> (2*x**2 - 2).as_poly().cancel((x**2 - 2*x + 1).as_poly(), include=True) (Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))
- clear_denoms(convert=False)[source]
Clear denominators, but keep the ground domain.
Examples
>>> f = (x/2 + Rational(1, 3)).as_poly()
>>> f.clear_denoms() (6, Poly(3*x + 2, x, domain='QQ')) >>> f.clear_denoms(convert=True) (6, Poly(3*x + 2, x, domain='ZZ'))
- coeff_monomial(monom)[source]
Returns the coefficient of
monom
inself
if there, else None.Examples
>>> p = (24*x*y*exp(8) + 23*x).as_poly(greedy=False)
>>> p.coeff_monomial(x) 23 >>> p.coeff_monomial(y) 0 >>> p.coeff_monomial(x*y) 24*E**8 >>> p.coeff_monomial((1, 1)) 24*E**8
Note that
Expr.coeff()
behaves differently, collecting terms if possible; the Poly must be converted to an Expr to use that method, however:>>> p.as_expr().coeff(x) 24*E**8*y + 23 >>> p.as_expr().coeff(y) 24*E**8*x >>> p.as_expr().coeff(x*y) 24*E**8
- coeffs(order=None)[source]
Returns all non-zero coefficients from
self
in lex order.Examples
>>> (x**3 + 2*x + 3).as_poly().coeffs() [1, 2, 3]
See also
- cofactors(other)[source]
Returns the GCD of
self
andother
and their cofactors.For two polynomials
f
andg
it returns polynomials(h, cff, cfg)
such thath = gcd(f, g)
, andcff = quo(f, h)
andcfg = quo(g, h)
are, so called, cofactors off
andg
.Examples
>>> (x**2 - 1).as_poly().cofactors((x**2 - 3*x + 2).as_poly()) (Poly(x - 1, x, domain='ZZ'), Poly(x + 1, x, domain='ZZ'), Poly(x - 2, x, domain='ZZ'))
- compose(other)[source]
Computes the functional composition of
self
andother
.Examples
>>> (x**2 + x).as_poly().compose((x - 1).as_poly()) Poly(x**2 - x, x, domain='ZZ')
- content()[source]
Returns the GCD of polynomial coefficients.
Examples
>>> (6*x**2 + 8*x + 12).as_poly().content() 2
- count_roots(inf=None, sup=None)[source]
Return the number of roots of
self
in[inf, sup]
interval.Examples
>>> (x**4 - 4).as_poly().count_roots(-3, 3) 2 >>> (x**4 - 4).as_poly().count_roots(0, 1 + 3*I) 1
- decompose()[source]
Computes a functional decomposition of
self
.Examples
>>> (x**4 + 2*x**3 - x - 1).as_poly().decompose() [Poly(x**2 - x - 1, x, domain='ZZ'), Poly(x**2 + x, x, domain='ZZ')]
- degree(gen=0)[source]
Returns degree of
self
inx_j
.The degree of 0 is negative floating-point infinity.
Examples
>>> (x**2 + y*x + 1).as_poly().degree() 2 >>> (x**2 + y*x + y).as_poly().degree(y) 1 >>> Integer(0).as_poly(x).degree() -inf
- discriminant()[source]
Computes the discriminant of
self
.Examples
>>> (x**2 + 2*x + 3).as_poly().discriminant() -8
- dispersionset(other=None)[source]
Compute the dispersion set of two polynomials.
Examples
>>> ((x - 3)*(x + 3)).as_poly().dispersionset() {0, 6}
- div(other, auto=True)[source]
Polynomial division with remainder of
self
byother
.Examples
>>> (x**2 + 1).as_poly().div((2*x - 4).as_poly()) (Poly(1/2*x + 1, x, domain='QQ'), Poly(5, x, domain='QQ'))
>>> (x**2 + 1).as_poly().div((2*x - 4).as_poly(), auto=False) (Poly(0, x, domain='ZZ'), Poly(x**2 + 1, x, domain='ZZ'))
- property domain
Get the ground domain of
self
.
- drop(*gens)[source]
Drop selected generators, if possible.
Examples
>>> f = (x + 1).as_poly(x, y)
>>> f.drop(y) Poly(x + 1, x, domain='ZZ') >>> f.drop(x) Traceback (most recent call last): ... ValueError: can't drop (Symbol('x'),)
- eject(*gens)[source]
Eject selected generators into the ground domain.
Examples
>>> f = (x**2*y + x*y**3 + x*y + 1).as_poly()
>>> f.eject(x) Poly(x*y**3 + (x**2 + x)*y + 1, y, domain='ZZ[x]') >>> f.eject(y) Poly(y*x**2 + (y**3 + y)*x + 1, x, domain='ZZ[y]')
- eval(x, a=None, auto=True)[source]
Evaluate
self
ata
in the given variable.Examples
>>> (x**2 + 2*x + 3).as_poly().eval(2) 11
>>> (2*x*y + 3*x + y + 2).as_poly().eval(x, 2) Poly(5*y + 8, y, domain='ZZ')
>>> f = (2*x*y + 3*x + y + 2*z).as_poly()
>>> f.eval({x: 2}) Poly(5*y + 2*z + 6, y, z, domain='ZZ') >>> f.eval({x: 2, y: 5}) Poly(2*z + 31, z, domain='ZZ') >>> f.eval({x: 2, y: 5, z: 7}) 45
>>> f.eval((2, 5)) Poly(2*z + 31, z, domain='ZZ') >>> f(2, 5) Poly(2*z + 31, z, domain='ZZ')
- exclude()[source]
Remove unnecessary generators from
self
.Examples
>>> (a + x).as_poly(a, b, c, d, x).exclude() Poly(a + x, a, x, domain='ZZ')
- exquo(other, auto=True)[source]
Computes polynomial exact quotient of
self
byother
.Examples
>>> (x**2 - 1).as_poly().exquo((x - 1).as_poly()) Poly(x + 1, x, domain='ZZ')
>>> (x**2 + 1).as_poly().exquo((2*x - 4).as_poly()) Traceback (most recent call last): ... ExactQuotientFailedError: 2*x - 4 does not divide x**2 + 1
- exquo_ground(coeff)[source]
Exact quotient of
self
by a an element of the ground domain.Examples
>>> (2*x + 4).as_poly().exquo_ground(2) Poly(x + 2, x, domain='ZZ')
>>> (2*x + 3).as_poly().exquo_ground(2) Traceback (most recent call last): ... ExactQuotientFailedError: 2 does not divide 3 in ZZ
- factor_list()[source]
Returns a list of irreducible factors of
self
.Examples
>>> f = (2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y).as_poly()
>>> f.factor_list() (2, [(Poly(x + y, x, y, domain='ZZ'), 1), (Poly(x**2 + 1, x, y, domain='ZZ'), 2)])
- property free_symbols
Free symbols of a polynomial expression.
Examples
>>> (x**2 + 1).as_poly().free_symbols {x} >>> (x**2 + y).as_poly().free_symbols {x, y} >>> (x**2 + y).as_poly(x).free_symbols {x, y}
- property free_symbols_in_domain
Free symbols of the domain of
self
.Examples
>>> (x**2 + 1).as_poly().free_symbols_in_domain set() >>> (x**2 + y).as_poly().free_symbols_in_domain set() >>> (x**2 + y).as_poly(x).free_symbols_in_domain {y}
- gcd(other)[source]
Returns the polynomial GCD of
self
andother
.Examples
>>> (x**2 - 1).as_poly().gcd((x**2 - 3*x + 2).as_poly()) Poly(x - 1, x, domain='ZZ')
- gcdex(other, auto=True)[source]
Extended Euclidean algorithm of
self
andother
.Returns
(h, s, t)
such thath = gcd(f, g)
ands*f + t*g = h
.Examples
>>> f = (x**4 - 2*x**3 - 6*x**2 + 12*x + 15).as_poly() >>> g = (x**3 + x**2 - 4*x - 4).as_poly()
>>> f.gcdex(g) (Poly(x + 1, x, domain='QQ'), Poly(-1/5*x + 3/5, x, domain='QQ'), Poly(1/5*x**2 - 6/5*x + 2, x, domain='QQ'))
- property gen
Return the principal generator.
Examples
>>> (x**2 + 1).as_poly().gen x
- get_modulus()[source]
Get the modulus of
self
.Examples
>>> (x**2 + 1).as_poly(modulus=2).get_modulus() 2
- half_gcdex(other, auto=True)[source]
Half extended Euclidean algorithm of
self
andother
.Returns
(h, s)
such thath = gcd(f, g)
ands*f = h (mod g)
.Examples
>>> f = (x**4 - 2*x**3 - 6*x**2 + 12*x + 15).as_poly() >>> g = (x**3 + x**2 - 4*x - 4).as_poly()
>>> f.half_gcdex(g) (Poly(x + 1, x, domain='QQ'), Poly(-1/5*x + 3/5, x, domain='QQ'))
- has_only_gens(*gens)[source]
Return
True
ifPoly(f, *gens)
retains ground domain.Examples
>>> (x*y + 1).as_poly(x, y, z).has_only_gens(x, y) True >>> (x*y + z).as_poly(x, y, z).has_only_gens(x, y) False
- inject(front=False)[source]
Inject ground domain generators into
self
.Examples
>>> f = (x**2*y + x*y**3 + x*y + 1).as_poly(x)
>>> f.inject() Poly(x**2*y + x*y**3 + x*y + 1, x, y, domain='ZZ') >>> f.inject(front=True) Poly(y**3*x + y*x**2 + y*x + 1, y, x, domain='ZZ')
- integrate(*specs, **args)[source]
Computes indefinite integral of
self
.Examples
>>> (x**2 + 2*x + 1).as_poly().integrate() Poly(1/3*x**3 + x**2 + x, x, domain='QQ')
>>> (x*y**2 + x).as_poly().integrate((0, 1), (1, 0)) Poly(1/2*x**2*y**2 + 1/2*x**2, x, y, domain='QQ')
- invert(other, auto=True)[source]
Invert
self
moduloother
when possible.Examples
>>> (x**2 - 1).as_poly().invert((2*x - 1).as_poly()) Poly(-4/3, x, domain='QQ')
>>> (x**2 - 1).as_poly().invert((x - 1).as_poly()) Traceback (most recent call last): ... NotInvertibleError: zero divisor
- property is_cyclotomic
Returns
True
ifself
is a cyclotomic polynomial.Examples
>>> f = (x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1).as_poly() >>> f.is_cyclotomic False
>>> g = (x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1).as_poly() >>> g.is_cyclotomic True
- property is_ground
Returns
True
ifself
is an element of the ground domain.Examples
>>> x.as_poly().is_ground False >>> Integer(2).as_poly(x).is_ground True >>> y.as_poly(x).is_ground True
- property is_homogeneous
Returns
True
ifself
is a homogeneous polynomial.A homogeneous polynomial is a polynomial whose all monomials with non-zero coefficients have the same total degree.
Examples
>>> (x**2 + x*y).as_poly().is_homogeneous True >>> (x**3 + x*y).as_poly().is_homogeneous False
- property is_irreducible
Returns
True
ifself
has no factors over its domain.Examples
>>> (x**2 + x + 1).as_poly(modulus=2).is_irreducible True >>> (x**2 + 1).as_poly(modulus=2).is_irreducible False
- property is_linear
Returns
True
ifself
is linear in all its variables.Examples
>>> (x + y + 2).as_poly().is_linear True >>> (x*y + 2).as_poly().is_linear False
- property is_multivariate
Returns
True
ifself
is a multivariate polynomial.Examples
>>> (x**2 + x + 1).as_poly().is_multivariate False >>> (x*y**2 + x*y + 1).as_poly().is_multivariate True >>> (x*y**2 + x*y + 1).as_poly(x).is_multivariate False >>> (x**2 + x + 1).as_poly(x, y).is_multivariate True
- property is_one
Returns
True
ifself
is a unit polynomial.Examples
>>> Integer(0).as_poly(x).is_one False >>> Integer(1).as_poly(x).is_one True
- property is_quadratic
Returns
True
ifself
is quadratic in all its variables.Examples
>>> (x*y + 2).as_poly().is_quadratic True >>> (x*y**2 + 2).as_poly().is_quadratic False
- property is_squarefree
Returns
True
ifself
is a square-free polynomial.Examples
>>> (x**2 - 2*x + 1).as_poly().is_squarefree False >>> (x**2 - 1).as_poly().is_squarefree True
- property is_term
Returns
True
ifself
is zero or has only one term.Examples
>>> (3*x**2).as_poly().is_term True >>> (3*x**2 + 1).as_poly().is_term False
- property is_univariate
Returns
True
ifself
is a univariate polynomial.Examples
>>> (x**2 + x + 1).as_poly().is_univariate True >>> (x*y**2 + x*y + 1).as_poly().is_univariate False >>> (x*y**2 + x*y + 1).as_poly(x).is_univariate True >>> (x**2 + x + 1).as_poly(x, y).is_univariate False
- property is_zero
Returns
True
ifself
is a zero polynomial.Examples
>>> Integer(0).as_poly(x).is_zero True >>> Integer(1).as_poly(x).is_zero False
- lcm(other)[source]
Returns polynomial LCM of
self
andother
.Examples
>>> (x**2 - 1).as_poly().lcm((x**2 - 3*x + 2).as_poly()) Poly(x**3 - 2*x**2 - x + 2, x, domain='ZZ')
- length()[source]
Returns the number of non-zero terms in
self
.Examples
>>> (x**2 + 2*x - 1).as_poly().length() 3
- monic(auto=True)[source]
Divides all coefficients by
LC(f)
.Examples
>>> (3*x**2 + 6*x + 9).as_poly().monic() Poly(x**2 + 2*x + 3, x, domain='QQ')
>>> (3*x**2 + 4*x + 2).as_poly().monic() Poly(x**2 + 4/3*x + 2/3, x, domain='QQ')
- monoms(order=None)[source]
Returns all non-zero monomials from
self
in lex order.Examples
>>> (x**2 + 2*x*y**2 + x*y + 3*y).as_poly().monoms() [(2, 0), (1, 2), (1, 1), (0, 1)]
- nroots(n=15, maxsteps=50, cleanup=True)[source]
Compute numerical approximations of roots of
self
.- Parameters:
n … the number of digits to calculate
maxsteps … the maximum number of iterations to do
If the accuracy `n` cannot be reached in `maxsteps`, it will raise an
exception. You need to rerun with higher maxsteps.
Examples
>>> (x**2 - 3).as_poly().nroots(n=15) [-1.73205080756888, 1.73205080756888] >>> (x**2 - 3).as_poly().nroots(n=30) [-1.73205080756887729352744634151, 1.73205080756887729352744634151]
- per(rep, *gens, remove=None)[source]
Create a Poly out of the given representation.
Examples
>>> a = (x**2 + 1).as_poly() >>> R = ZZ.inject(x)
>>> a.per(R.from_list([ZZ(1), ZZ(1)]), y) Poly(y + 1, y, domain='ZZ')
- primitive()[source]
Returns the content and a primitive form of
self
.Examples
>>> (2*x**2 + 8*x + 12).as_poly().primitive() (2, Poly(x**2 + 4*x + 6, x, domain='ZZ'))
- quo(other, auto=True)[source]
Computes polynomial quotient of
self
byother
.Examples
>>> (x**2 + 1).as_poly().quo((2*x - 4).as_poly()) Poly(1/2*x + 1, x, domain='QQ')
>>> (x**2 - 1).as_poly().quo((x - 1).as_poly()) Poly(x + 1, x, domain='ZZ')
- quo_ground(coeff)[source]
Quotient of
self
by a an element of the ground domain.Examples
>>> (2*x + 4).as_poly().quo_ground(2) Poly(x + 2, x, domain='ZZ')
>>> (2*x + 3).as_poly().quo_ground(2) Poly(x + 1, x, domain='ZZ')
- rat_clear_denoms(other)[source]
Clear denominators in a rational function
self/other
.Examples
>>> f = (x**2/y + 1).as_poly(x) >>> g = (x**3 + y).as_poly(x)
>>> p, q = f.rat_clear_denoms(g)
>>> p Poly(x**2 + y, x, domain='ZZ[y]') >>> q Poly(y*x**3 + y**2, x, domain='ZZ[y]')
- real_roots(multiple=True, radicals=True)[source]
Return a list of real roots with multiplicities.
Examples
>>> (2*x**3 - 7*x**2 + 4*x + 4).as_poly().real_roots() [-1/2, 2, 2] >>> (x**3 + x + 1).as_poly().real_roots() [RootOf(x**3 + x + 1, 0)]
- rem(other, auto=True)[source]
Computes the polynomial remainder of
self
byother
.Examples
>>> (x**2 + 1).as_poly().rem((2*x - 4).as_poly()) Poly(5, x, domain='ZZ')
>>> (x**2 + 1).as_poly().rem((2*x - 4).as_poly(), auto=False) Poly(x**2 + 1, x, domain='ZZ')
- reorder(*gens, **args)[source]
Efficiently apply new order of generators.
Examples
>>> (x**2 + x*y**2).as_poly().reorder(y, x) Poly(y**2*x + x**2, y, x, domain='ZZ')
- replace(x, y=None)[source]
Replace
x
withy
in generators list.Examples
>>> (x**2 + 1).as_poly().replace(x, y) Poly(y**2 + 1, y, domain='ZZ')
- resultant(other, includePRS=False)[source]
Computes the resultant of
self
andother
via PRS.If includePRS=True, it includes the subresultant PRS in the result. Because the PRS is used to calculate the resultant, this is more efficient than calling
subresultants()
separately.Examples
>>> f = (x**2 + 1).as_poly()
>>> f.resultant((x**2 - 1).as_poly()) 4 >>> f.resultant((x**2 - 1).as_poly(), includePRS=True) (4, [Poly(x**2 + 1, x, domain='ZZ'), Poly(x**2 - 1, x, domain='ZZ'), Poly(-2, x, domain='ZZ')])
- retract(field=None)[source]
Recalculate the ground domain of a polynomial.
Examples
>>> f = (x**2 + 1).as_poly(domain=QQ.inject(y)) >>> f Poly(x**2 + 1, x, domain='QQ[y]')
>>> f.retract() Poly(x**2 + 1, x, domain='ZZ') >>> f.retract(field=True) Poly(x**2 + 1, x, domain='QQ')
- root(index, radicals=True)[source]
Get an indexed root of a polynomial.
Examples
>>> f = (2*x**3 - 7*x**2 + 4*x + 4).as_poly()
>>> f.root(0) -1/2 >>> f.root(1) 2 >>> f.root(2) 2 >>> f.root(3) Traceback (most recent call last): ... IndexError: root index out of [-3, 2] range, got 3
>>> (x**5 + x + 1).as_poly().root(0) RootOf(x**3 - x**2 + 1, 0)
- set_modulus(modulus)[source]
Set the modulus of
self
.Examples
>>> (5*x**2 + 2*x - 1).as_poly().set_modulus(2) Poly(x**2 + 1, x, modulus=2)
- shift(a)[source]
Efficiently compute Taylor shift
f(x + a)
.Examples
>>> (x**2 - 2*x + 1).as_poly().shift(2) Poly(x**2 + 2*x + 1, x, domain='ZZ')
- sqf_list()[source]
Returns a list of square-free factors of
self
.Examples
>>> f = (2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16).as_poly()
>>> f.sqf_list() (2, [(Poly(x + 1, x, domain='ZZ'), 2), (Poly(x + 2, x, domain='ZZ'), 3)])
- sqf_norm()[source]
Computes square-free norm of
self
.Returns
s
,f
,r
, such thatg(x) = f(x-sa)
andr(x) = Norm(g(x))
is a square-free polynomial overK
, wherea
is the algebraic extension of the ground domain.Examples
>>> s, f, r = (x**2 + 1).as_poly(extension=[sqrt(3)]).sqf_norm()
>>> s 1 >>> f Poly(x**2 - 2*sqrt(3)*x + 4, x, domain='QQ<sqrt(3)>') >>> r Poly(x**4 - 4*x**2 + 16, x, domain='QQ')
- sqf_part()[source]
Computes square-free part of
self
.Examples
>>> (x**3 - 3*x - 2).as_poly().sqf_part() Poly(x**2 - x - 2, x, domain='ZZ')
- subresultants(other)[source]
Computes the subresultant PRS of
self
andother
.Examples
>>> (x**2 + 1).as_poly().subresultants((x**2 - 1).as_poly()) [Poly(x**2 + 1, x, domain='ZZ'), Poly(x**2 - 1, x, domain='ZZ'), Poly(-2, x, domain='ZZ')]
- terms(order=None)[source]
Returns all non-zero terms from
self
in lex order.Examples
>>> (x**2 + 2*x*y**2 + x*y + 3*y).as_poly().terms() [((2, 0), 1), ((1, 2), 2), ((1, 1), 1), ((0, 1), 3)]
- terms_gcd()[source]
Remove GCD of terms from the polynomial
self
.Examples
>>> (x**6*y**2 + x**3*y).as_poly().terms_gcd() ((3, 1), Poly(x**3*y + 1, x, y, domain='ZZ'))
- termwise(func, *gens, **args)[source]
Apply a function to all terms of
self
.Examples
>>> def func(k, coeff): ... k = k[0] ... return coeff//10**(2-k)
>>> (x**2 + 20*x + 400).as_poly().termwise(func) Poly(x**2 + 2*x + 4, x, domain='ZZ')
- to_exact()[source]
Make the ground domain exact.
Examples
>>> (x**2 + 1.0).as_poly().to_exact() Poly(x**2 + 1, x, domain='QQ')
- to_field()[source]
Make the ground domain a field.
Examples
>>> (x**2 + 1).as_poly().to_field() Poly(x**2 + 1, x, domain='QQ')
- to_ring()[source]
Make the ground domain a ring.
Examples
>>> (x**2 + 1).as_poly(field=True).to_ring() Poly(x**2 + 1, x, domain='ZZ')
- total_degree()[source]
Returns the total degree of
self
.Examples
>>> (x**2 + y*x + 1).as_poly().total_degree() 2 >>> (x + y**5).as_poly().total_degree() 5
- class diofant.polys.polytools.PurePoly(rep, *gens, **args)[source]
Class for representing pure polynomials.
- property free_symbols
Free symbols of a polynomial.
Examples
>>> PurePoly(x**2 + 1).free_symbols set() >>> PurePoly(x**2 + y).free_symbols set() >>> PurePoly(x**2 + y, x).free_symbols {y}
- diofant.polys.polytools.cancel(f, *gens, **args)[source]
Cancel common factors in a rational function
f
.Examples
>>> A = Symbol('A', commutative=False)
>>> cancel((2*x**2 - 2)/(x**2 - 2*x + 1)) (2*x + 2)/(x - 1) >>> cancel((sqrt(3) + sqrt(15)*A)/(sqrt(2) + sqrt(10)*A)) sqrt(6)/2
- diofant.polys.polytools.cofactors(f, g, *gens, **args)[source]
Compute GCD and cofactors of
f
andg
.Returns polynomials
(h, cff, cfg)
such thath = gcd(f, g)
, andcff = quo(f, h)
andcfg = quo(g, h)
are, so called, cofactors off
andg
.Examples
>>> cofactors(x**2 - 1, x**2 - 3*x + 2) (x - 1, x + 1, x - 2)
- diofant.polys.polytools.compose(f, g, *gens, **args)[source]
Compute functional composition
f(g)
.Examples
>>> compose(x**2 + x, x - 1) x**2 - x
- diofant.polys.polytools.content(f, *gens, **args)[source]
Compute GCD of coefficients of
f
.Examples
>>> content(6*x**2 + 8*x + 12) 2
- diofant.polys.polytools.count_roots(f, inf=None, sup=None)[source]
Return the number of roots of
f
in[inf, sup]
interval.If one of
inf
orsup
is complex, it will return the number of roots in the complex rectangle with corners atinf
andsup
.Examples
>>> count_roots(x**4 - 4, -3, 3) 2 >>> count_roots(x**4 - 4, 0, 1 + 3*I) 1
- diofant.polys.polytools.decompose(f, *gens, **args)[source]
Compute functional decomposition of
f
.Examples
>>> decompose(x**4 + 2*x**3 - x - 1) [x**2 - x - 1, x**2 + x]
- diofant.polys.polytools.degree(f, *gens, **args)[source]
Return the degree of
f
in the given variable.The degree of 0 is negative infinity.
Examples
>>> degree(x**2 + y*x + 1, gen=x) 2 >>> degree(x**2 + y*x + 1, gen=y) 1 >>> degree(0, x) -inf
- diofant.polys.polytools.discriminant(f, *gens, **args)[source]
Compute discriminant of
f
.Examples
>>> discriminant(x**2 + 2*x + 3) -8
- diofant.polys.polytools.div(f, g, *gens, **args)[source]
Compute polynomial division of
f
andg
.Examples
>>> div(x**2 + 1, 2*x - 4, field=False) (0, x**2 + 1) >>> div(x**2 + 1, 2*x - 4) (x/2 + 1, 5)
- diofant.polys.polytools.eliminate(F, G, *gens, **args)[source]
Eliminate the symbols
G
from the polynomialsF
.- Parameters:
F (iterable of Expr’s) – The system of polynomials to eliminate variables from.
G (iterable of Symbol’s) – Symbols to be eliminated.
- Returns:
list – Equations, which are equivalent to the
F
, but do not contain symbolsG
.
Examples
>>> eliminate([x + y + z, y - z], [y]) [x + 2*z] >>> eliminate([x + y + z, y - z, x - y], [y, z]) [x] >>> eliminate([x**2 + y + z - 1, x + y**2 + z - 1, x + y + z**2 - 1], [z]) [x**2 - x - y**2 + y, 2*x*y**2 + y**4 - y**2, y**6 - 4*y**4 + 4*y**3 - y**2]
- diofant.polys.polytools.exquo(f, g, *gens, **args)[source]
Compute polynomial exact quotient of
f
andg
.Examples
>>> exquo(x**2 - 1, x - 1) x + 1
>>> exquo(x**2 + 1, 2*x - 4) Traceback (most recent call last): ... ExactQuotientFailedError: 2*x - 4 does not divide x**2 + 1
- diofant.polys.polytools.factor(f, *gens, **args)[source]
Compute the factorization of expression,
f
, into irreducibles. (To factor an integer into primes, usefactorint
.)There two modes implemented: symbolic and formal. If
f
is not an instance ofPoly
and generators are not specified, then the former mode is used. Otherwise, the formal mode is used.In symbolic mode,
factor()
will traverse the expression tree and factor its components without any prior expansion, unless an instance ofAdd
is encountered (in this case formal factorization is used). This wayfactor()
can handle large or symbolic exponents.By default, the factorization is computed over the rationals. To factor over other domain, e.g. an algebraic or finite field, use appropriate options:
extension
,modulus
ordomain
.Examples
>>> factor(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y) 2*(x + y)*(x**2 + 1)**2
>>> factor(x**2 + 1) x**2 + 1 >>> factor(x**2 + 1, modulus=2) (x + 1)**2 >>> factor(x**2 + 1, gaussian=True) (x - I)*(x + I)
>>> factor(x**2 - 2, extension=sqrt(2)) (x - sqrt(2))*(x + sqrt(2))
>>> factor((x**2 - 1)/(x**2 + 4*x + 4)) (x - 1)*(x + 1)/(x + 2)**2 >>> factor((x**2 + 4*x + 4)**10000000*(x**2 + 1)) (x + 2)**20000000*(x**2 + 1)
By default, factor deals with an expression as a whole:
>>> eq = 2**(x**2 + 2*x + 1) >>> factor(eq) 2**(x**2 + 2*x + 1)
If the
deep
flag is True then subexpressions will be factored:>>> factor(eq, deep=True) 2**((x + 1)**2)
See also
- diofant.polys.polytools.factor_list(f, *gens, **args)[source]
Compute a list of irreducible factors of
f
.Examples
>>> factor_list(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y) (2, [(x + y, 1), (x**2 + 1, 2)])
- diofant.polys.polytools.gcd(f, g, *gens, **args)[source]
Compute GCD of
f
andg
.Examples
>>> gcd(x**2 - 1, x**2 - 3*x + 2) x - 1
- diofant.polys.polytools.gcdex(f, g, *gens, **args)[source]
Extended Euclidean algorithm of
f
andg
.Returns
(h, s, t)
such thath = gcd(f, g)
ands*f + t*g = h
.Examples
>>> gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4) (x + 1, -x/5 + 3/5, x**2/5 - 6*x/5 + 2)
- diofant.polys.polytools.groebner(F, *gens, **args)[source]
Computes the reduced Gröbner basis for a set of polynomials.
- Parameters:
F (list) – a set of polynomials
*gens (tuple) – polynomial generators
**args (dict) – a dictionary of parameters, namely
- orderstr, optional
Monomial order, defaults to
lex
.- method{‘buchberger’, ‘f5b’}, optional
Set algorithm to compute Gröbner basis. By default, an improved implementation of the Buchberger algorithm is used.
- fieldbool, optional
Force coefficients domain to be a field. Defaults to False.
Examples
>>> F = [x*y - 2*x, 2*x**2 - y**2]
>>> groebner(F) GroebnerBasis([2*x**2 - y**2, x*y - 2*x, y**3 - 2*y**2], x, y, domain='ZZ', order='lex')
>>> groebner(F, order=grevlex) GroebnerBasis([y**3 - 2*y**2, 2*x**2 - y**2, x*y - 2*x], x, y, domain='ZZ', order='grevlex')
>>> groebner(F, field=True) GroebnerBasis([x**2 - y**2/2, x*y - 2*x, y**3 - 2*y**2], x, y, domain='QQ', order='lex')
References
- diofant.polys.polytools.half_gcdex(f, g, *gens, **args)[source]
Half extended Euclidean algorithm of
f
andg
.Returns
(h, s)
such thath = gcd(f, g)
ands*f = h (mod g)
.Examples
>>> half_gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4) (x + 1, -x/5 + 3/5)
- diofant.polys.polytools.invert(f, g, *gens, **args)[source]
Invert
f
modulog
when possible.Examples
>>> invert(x**2 - 1, 2*x - 1) -4/3
>>> invert(x**2 - 1, x - 1) Traceback (most recent call last): ... NotInvertibleError: zero divisor
For more efficient inversion of Rationals, use the
mod_inverse
function:>>> mod_inverse(3, 5) 2 >>> (Integer(2)/5).invert(Integer(7)/3) 5/2
See also
- diofant.polys.polytools.lcm(f, g, *gens, **args)[source]
Compute LCM of
f
andg
.Examples
>>> lcm(x**2 - 1, x**2 - 3*x + 2) x**3 - 2*x**2 - x + 2
- diofant.polys.polytools.monic(f, *gens, **args)[source]
Divide all coefficients of
f
byLC(f)
.Examples
>>> monic(3*x**2 + 4*x + 2) x**2 + 4*x/3 + 2/3
- diofant.polys.polytools.nroots(f, n=15, maxsteps=50, cleanup=True)[source]
Compute numerical approximations of roots of
f
.Examples
>>> nroots(x**2 - 3, n=15) [-1.73205080756888, 1.73205080756888] >>> nroots(x**2 - 3, n=30) [-1.73205080756887729352744634151, 1.73205080756887729352744634151]
- diofant.polys.polytools.parallel_poly_from_expr(exprs, *gens, **args)[source]
Construct polynomials from expressions.
- diofant.polys.polytools.primitive(f, *gens, **args)[source]
Compute content and the primitive form of
f
.Examples
>>> primitive(6*x**2 + 8*x + 12) (2, 3*x**2 + 4*x + 6)
>>> eq = (2 + 2*x)*x + 2
Expansion is performed by default:
>>> primitive(eq) (2, x**2 + x + 1)
Set
expand
to False to shut this off. Note that the extraction will not be recursive; use the as_content_primitive method for recursive, non-destructive Rational extraction.>>> primitive(eq, expand=False) (1, x*(2*x + 2) + 2)
>>> eq.as_content_primitive() (2, x*(x + 1) + 1)
- diofant.polys.polytools.quo(f, g, *gens, **args)[source]
Compute polynomial quotient of
f
andg
.Examples
>>> quo(x**2 + 1, 2*x - 4) x/2 + 1 >>> quo(x**2 - 1, x - 1) x + 1
- diofant.polys.polytools.real_roots(f, multiple=True)[source]
Return a list of real roots with multiplicities of
f
.Examples
>>> real_roots(2*x**3 - 7*x**2 + 4*x + 4) [-1/2, 2, 2]
- diofant.polys.polytools.reduced(f, G, *gens, **args)[source]
Reduces a polynomial
f
modulo a set of polynomialsG
.Given a polynomial
f
and a set of polynomialsG = (g_1, ..., g_n)
, computes a set of quotientsq = (q_1, ..., q_n)
and the remainderr
such thatf = q_1*g_1 + ... + q_n*g_n + r
, wherer
vanishes orr
is a completely reduced polynomial with respect toG
.Examples
>>> reduced(2*x**4 + y**2 - x**2 + y**3, [x**3 - x, y**3 - y]) ([2*x, 1], x**2 + y**2 + y)
- diofant.polys.polytools.rem(f, g, *gens, **args)[source]
Compute polynomial remainder of
f
andg
.Examples
>>> rem(x**2 + 1, 2*x - 4, field=False) x**2 + 1 >>> rem(x**2 + 1, 2*x - 4) 5
- diofant.polys.polytools.resultant(f, g, *gens, **args)[source]
Compute resultant of
f
andg
.Examples
>>> resultant(x**2 + 1, x**2 - 1) 4
- diofant.polys.polytools.sqf(f, *gens, **args)[source]
Compute square-free factorization of
f
.Examples
>>> sqf(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16) 2*(x + 1)**2*(x + 2)**3
- diofant.polys.polytools.sqf_list(f, *gens, **args)[source]
Compute a list of square-free factors of
f
.Examples
>>> sqf_list(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16) (2, [(x + 1, 2), (x + 2, 3)])
- diofant.polys.polytools.sqf_norm(f, *gens, **args)[source]
Compute square-free norm of
f
.Returns
s
,f
,r
, such thatg(x) = f(x-sa)
andr(x) = Norm(g(x))
is a square-free polynomial overK
, wherea
is the algebraic extension of the ground domain.Examples
>>> sqf_norm(x**2 + 1, extension=[sqrt(3)]) (1, x**2 - 2*sqrt(3)*x + 4, x**4 - 4*x**2 + 16)
- diofant.polys.polytools.sqf_part(f, *gens, **args)[source]
Compute square-free part of
f
.Examples
>>> sqf_part(x**3 - 3*x - 2) x**2 - x - 2
- diofant.polys.polytools.subresultants(f, g, *gens, **args)[source]
Compute subresultant PRS of
f
andg
.Examples
>>> subresultants(x**2 + 1, x**2 - 1) [x**2 + 1, x**2 - 1, -2]
- diofant.polys.polytools.terms_gcd(f, *gens, **args)[source]
Remove GCD of terms from
f
.If the
deep
flag is True, then the arguments off
will have terms_gcd applied to them.If a fraction is factored out of
f
andf
is an Add, then an unevaluated Mul will be returned so that automatic simplification does not redistribute it. The hintclear
, when set to False, can be used to prevent such factoring when all coefficients are not fractions.Examples
>>> terms_gcd(x**6*y**2 + x**3*y) x**3*y*(x**3*y + 1)
The default action of polys routines is to expand the expression given to them. terms_gcd follows this behavior:
>>> terms_gcd((3+3*x)*(x+x*y)) 3*x*(x*y + x + y + 1)
If this is not desired then the hint
expand
can be set to False. In this case the expression will be treated as though it were comprised of one or more terms:>>> terms_gcd((3+3*x)*(x+x*y), expand=False) (3*x + 3)*(x*y + x)
In order to traverse factors of a Mul or the arguments of other functions, the
deep
hint can be used:>>> terms_gcd((3 + 3*x)*(x + x*y), expand=False, deep=True) 3*x*(x + 1)*(y + 1) >>> terms_gcd(cos(x + x*y), deep=True) cos(x*(y + 1))
Rationals are factored out by default:
>>> terms_gcd(x + y/2) (2*x + y)/2
Only the y-term had a coefficient that was a fraction; if one does not want to factor out the 1/2 in cases like this, the flag
clear
can be set to False:>>> terms_gcd(x + y/2, clear=False) x + y/2 >>> terms_gcd(x*y/2 + y**2, clear=False) y*(x/2 + y)
The
clear
flag is ignored if all coefficients are fractions:>>> terms_gcd(x/3 + y/2, clear=False) (2*x + 3*y)/6
Extra polynomial manipulation functions
High-level polynomials manipulation functions.
- diofant.polys.polyfuncs.horner(f, *gens, **args)[source]
Rewrite a polynomial in Horner form.
Among other applications, evaluation of a polynomial at a point is optimal when it is applied using the Horner scheme.
Examples
>>> from diofant.abc import e
>>> horner(9*x**4 + 8*x**3 + 7*x**2 + 6*x + 5) x*(x*(x*(9*x + 8) + 7) + 6) + 5
>>> horner(a*x**4 + b*x**3 + c*x**2 + d*x + e) e + x*(d + x*(c + x*(a*x + b)))
>>> f = 4*x**2*y**2 + 2*x**2*y + 2*x*y**2 + x*y
>>> horner(f, wrt=x) x*(x*y*(4*y + 2) + y*(2*y + 1))
>>> horner(f, wrt=y) y*(x*y*(4*x + 2) + x*(2*x + 1))
References
- diofant.polys.polyfuncs.interpolate(data, x)[source]
Construct an interpolating polynomial for the data points.
Examples
A list is interpreted as though it were paired with a range starting from 1:
>>> interpolate([1, 4, 9, 16], x) x**2
This can be made explicit by giving a list of coordinates:
>>> interpolate([(1, 1), (2, 4), (3, 9)], x) x**2
The (x, y) coordinates can also be given as keys and values of a dictionary (and the points need not be equispaced):
>>> interpolate([(-1, 2), (1, 2), (2, 5)], x) x**2 + 1 >>> interpolate({-1: 2, 1: 2, 2: 5}, x) x**2 + 1
- diofant.polys.polyfuncs.symmetrize(F, *gens, **args)[source]
Rewrite a polynomial in terms of elementary symmetric polynomials.
A symmetric polynomial is a multivariate polynomial that remains invariant under any variable permutation, i.e., if
f = f(x_1, x_2, ..., x_n)
, thenf = f(x_{i_1}, x_{i_2}, ..., x_{i_n})
, where(i_1, i_2, ..., i_n)
is a permutation of(1, 2, ..., n)
(an element of the groupS_n
).Returns a tuple of symmetric polynomials
(f1, f2, ..., fn)
such thatf = f1 + f2 + ... + fn
.Examples
>>> symmetrize(x**2 + y**2) (-2*x*y + (x + y)**2, 0)
>>> symmetrize(x**2 + y**2, formal=True) (s1**2 - 2*s2, 0, [(s1, x + y), (s2, x*y)])
>>> symmetrize(x**2 - y**2) (-2*x*y + (x + y)**2, -2*y**2)
>>> symmetrize(x**2 - y**2, formal=True) (s1**2 - 2*s2, -2*y**2, [(s1, x + y), (s2, x*y)])
Domain constructors
Tools for constructing domains for expressions.
Algebraic number fields
Computational algebraic field theory.
- diofant.polys.numberfields.field_isomorphism(a, b, **args)[source]
Construct an isomorphism between two number fields.
- diofant.polys.numberfields.minimal_polynomial(ex, method=None, **args)[source]
Computes the minimal polynomial of an algebraic element.
- Parameters:
ex (algebraic element expression)
method (str, optional) – If
compose
, the minimal polynomial of the subexpressions ofex
are computed, then the arithmetic operations on them are performed using the resultant and factorization. Ifgroebner
, a bottom-up algorithm, using Gröbner bases is used. Default value is determined bysetup()
.domain (Domain, optional) – If no ground domain is given, it will be generated automatically from the expression.
Examples
>>> minimal_polynomial(sqrt(2))(x) x**2 - 2 >>> minimal_polynomial(sqrt(2), domain=QQ.algebraic_field(sqrt(2)))(x) x - sqrt(2) >>> minimal_polynomial(sqrt(2) + sqrt(3))(x) x**4 - 10*x**2 + 1 >>> minimal_polynomial(solve(x**3 + x + 3)[0][x])(x) x**3 + x + 3 >>> minimal_polynomial(sqrt(y))(x) x**2 - y
Monomials encoded as tuples
Tools and arithmetics for monomials of distributed polynomials.
Orderings of monomials
Definitions of monomial orderings.
Formal manipulation of roots of polynomials
Implementation of RootOf class and related tools.
- class diofant.polys.rootoftools.RootOf(f, x, index=None, radicals=True, evaluate=None, domain=None, modulus=None)[source]
Represents
k
-th root of a univariate polynomial.The ordering used for indexing takes real roots to come before complex ones, sort complex roots by real part, then by imaginary part and finally takes complex conjugate pairs of roots to be adjacent.
- Parameters:
f (Expr) – Univariate polynomial expression.
x (Symbol or Integer) – Polynomial variable or the index of the root.
index (Integer or None, optional) – Index of the root. If None (default), parameter
x
is used instead as index.radicals (bool, optional) – Explicitly solve linear or quadratic polynomial equation (enabled by default).
evaluate (bool or None, optional) – Control automatic evaluation.
Examples
>>> expand_func(RootOf(x**3 + I*x + 2, 0)) RootOf(x**6 + 4*x**3 + x**2 + 4, 1)
- eval_rational(tol)[source]
Returns a Rational approximation to
self
with the tolerancetol
.The returned instance will be at most ‘tol’ from the exact root.
The following example first obtains Rational approximation to 1e-7 accuracy for all roots of the 4-th order Legendre polynomial, and then evaluates it to 5 decimal digits (so all digits will be correct including rounding):
>>> p = legendre_poly(4, x, polys=True) >>> roots = [r.eval_rational(Rational(1, 10)**7) for r in p.real_roots()] >>> roots = [str(r.evalf(5)) for r in roots] >>> roots ['-0.86114', '-0.33998', '0.33998', '0.86114']
- property interval
Return isolation interval for the root.
Symbolic root-finding algorithms
Algorithms for computing symbolic roots of polynomials.
- diofant.polys.polyroots.roots(f, *gens, **flags)[source]
Computes symbolic roots of a univariate polynomial.
Given a univariate polynomial f with symbolic coefficients (or a list of the polynomial’s coefficients), returns a dictionary with its roots and their multiplicities.
Only roots expressible via radicals will be returned. To get a complete set of roots use RootOf class or numerical methods instead. By default cubic and quartic formulas are used in the algorithm. To disable them because of unreadable output set
cubics=False
orquartics=False
respectively. If cubic roots are real but are expressed in terms of complex numbers (casus irreducibilis) thetrig
flag can be set to True to have the solutions returned in terms of cosine and inverse cosine functions.To get roots from a specific domain set the
filter
flag with one of the following specifiers: Z, Q, R, I, C. By default all roots are returned (this is equivalent to settingfilter='C'
).By default a dictionary is returned giving a compact result in case of multiple roots. However to get a list containing all those roots set the
multiple
flag to True; the list will have identical roots appearing next to each other in the result. (For a given Poly, the all_roots method will give the roots in sorted numerical order.)Examples
>>> roots(x**2 - 1, x) {-1: 1, 1: 1}
>>> p = (x**2 - 1).as_poly() >>> roots(p) {-1: 1, 1: 1}
>>> p = (x**2 - y).as_poly()
>>> roots(p.as_poly(x)) {-sqrt(y): 1, sqrt(y): 1}
>>> roots(x**2 - y, x) {-sqrt(y): 1, sqrt(y): 1}
>>> roots([1, 0, -1]) {-1: 1, 1: 1}
References
Special polynomials
Functions for generating interesting polynomials, e.g. for benchmarking.
- diofant.polys.specialpolys.cyclotomic_poly(n, x=None, **args)[source]
Generates cyclotomic polynomial of order \(n\) in \(x\).
- diofant.polys.specialpolys.interpolating_poly(n, x, X='x', Y='y')[source]
Construct Lagrange interpolating polynomial for
n
data points.
- diofant.polys.specialpolys.random_poly(x, n, inf, sup, domain=GMPYIntegerRing(), polys=False, percent=None)[source]
Return a polynomial of degree
n
with coefficients in[inf, sup]
.
Orthogonal polynomials
Efficient functions for generating orthogonal polynomials.
- diofant.polys.orthopolys.chebyshevt_poly(n, x=None, **args)[source]
Generates Chebyshev polynomial of the first kind of degree \(n\) in \(x\).
- diofant.polys.orthopolys.chebyshevu_poly(n, x=None, **args)[source]
Generates Chebyshev polynomial of the second kind of degree \(n\) in \(x\).
- diofant.polys.orthopolys.gegenbauer_poly(n, a, x=None, **args)[source]
Generates Gegenbauer polynomial of degree \(n\) in \(x\).
- diofant.polys.orthopolys.hermite_poly(n, x=None, **args)[source]
Generates Hermite polynomial of degree \(n\) in \(x\).
- diofant.polys.orthopolys.jacobi_poly(n, a, b, x=None, **args)[source]
Generates Jacobi polynomial of degree \(n\) in \(x\).
- diofant.polys.orthopolys.laguerre_poly(n, x=None, alpha=None, **args)[source]
Generates Laguerre polynomial of degree \(n\) in \(x\).
- diofant.polys.orthopolys.legendre_poly(n, x=None, **args)[source]
Generates Legendre polynomial of degree \(n\) in \(x\).
- diofant.polys.orthopolys.spherical_bessel_fn(n, x=None, **args)[source]
Coefficients for the spherical Bessel functions.
Those are only needed in the jn() function.
The coefficients are calculated from:
fn(0, z) = 1/z fn(1, z) = 1/z**2 fn(n-1, z) + fn(n+1, z) == (2*n+1)/z * fn(n, z)
Examples
>>> spherical_bessel_fn(1, z) z**(-2) >>> spherical_bessel_fn(2, z) -1/z + 3/z**3 >>> spherical_bessel_fn(3, z) -6/z**2 + 15/z**4 >>> spherical_bessel_fn(4, z) 1/z - 45/z**3 + 105/z**5
Manipulation of rational functions
Tools for manipulation of rational expressions.
- diofant.polys.rationaltools.together(expr, deep=False)[source]
Denest and combine rational expressions using symbolic methods.
This function takes an expression or a container of expressions and puts it (them) together by denesting and combining rational subexpressions. No heroic measures are taken to minimize degree of the resulting numerator and denominator. To obtain completely reduced expression use
cancel()
. However,together()
can preserve as much as possible of the structure of the input expression in the output (no expansion is performed).A wide variety of objects can be put together including lists, tuples, sets, relational objects, integrals and others. It is also possible to transform interior of function applications, by setting
deep
flag toTrue
.By definition,
together()
is a complement toapart()
, soapart(together(expr))
should return expr unchanged. Note however, thattogether()
uses only symbolic methods, so it might be necessary to usecancel()
to perform algebraic simplification and minimise degree of the numerator and denominator.Examples
>>> together(1/x + 1/y) (x + y)/(x*y) >>> together(1/x + 1/y + 1/z) (x*y + x*z + y*z)/(x*y*z)
>>> together(1/(x*y) + 1/y**2) (x + y)/(x*y**2)
>>> together(1/(1 + 1/x) + 1/(1 + 1/y)) (x*(y + 1) + y*(x + 1))/((x + 1)*(y + 1))
>>> together(exp(1/x + 1/y)) E**(1/y + 1/x) >>> together(exp(1/x + 1/y), deep=True) E**((x + y)/(x*y))
>>> together(1/exp(x) + 1/(x*exp(x))) E**(-x)*(x + 1)/x
>>> together(1/exp(2*x) + 1/(x*exp(3*x))) E**(-3*x)*(E**x*x + 1)/x
Partial fraction decomposition
Algorithms for partial fraction decomposition of rational functions.
- diofant.polys.partfrac.apart(f, x=None, full=False, **options)[source]
Compute partial fraction decomposition of a rational function.
Given a rational function
f
, computes the partial fraction decomposition off
. Two algorithms are available: One is based on the undertermined coefficients method, the other is Bronstein’s full partial fraction decomposition algorithm.The undetermined coefficients method (selected by
full=False
) uses polynomial factorization (and therefore accepts the same options as factor) for the denominator. Per default it works over the rational numbers, therefore decomposition of denominators with non-rational roots (e.g. irrational, complex roots) is not supported by default (see options of factor).Bronstein’s algorithm can be selected by using
full=True
and allows a decomposition of denominators with non-rational roots. A human-readable result can be obtained viadoit()
(see examples below).Examples
By default, using the undetermined coefficients method:
>>> apart(y/(x + 2)/(x + 1), x) -y/(x + 2) + y/(x + 1)
The undetermined coefficients method does not provide a result when the denominators roots are not rational:
>>> apart(y/(x**2 + x + 1), x) y/(x**2 + x + 1)
You can choose Bronstein’s algorithm by setting
full=True
:>>> apart(y/(x**2 + x + 1), x, full=True) RootSum(_w**2 + _w + 1, Lambda(_a, (-2*y*_a/3 - y/3)/(x - _a)))
Calling
doit()
yields a human-readable result:>>> apart(y/(x**2 + x + 1), x, full=True).doit() (-y/3 - 2*y*(-1/2 - sqrt(3)*I/2)/3)/(x + 1/2 + sqrt(3)*I/2) + (-y/3 - 2*y*(-1/2 + sqrt(3)*I/2)/3)/(x + 1/2 - sqrt(3)*I/2)
See also
- diofant.polys.partfrac.apart_list(f, x=None, dummies=None, **options)[source]
Compute partial fraction decomposition of a rational function and return the result in structured form.
Given a rational function
f
compute the partial fraction decomposition off
. Only Bronstein’s full partial fraction decomposition algorithm is supported by this method. The return value is highly structured and perfectly suited for further algorithmic treatment rather than being human-readable. The function returns a tuple holding three elements:The first item is the common coefficient, free of the variable \(x\) used for decomposition. (It is an element of the base field \(K\).)
The second item is the polynomial part of the decomposition. This can be the zero polynomial. (It is an element of \(K[x]\).)
The third part itself is a list of quadruples. Each quadruple has the following elements in this order:
The (not necessarily irreducible) polynomial \(D\) whose roots \(w_i\) appear in the linear denominator of a bunch of related fraction terms. (This item can also be a list of explicit roots. However, at the moment
apart_list
never returns a result this way, but the relatedassemble_partfrac_list
function accepts this format as input.)The numerator of the fraction, written as a function of the root \(w\)
The linear denominator of the fraction excluding its power exponent, written as a function of the root \(w\).
The power to which the denominator has to be raised.
On can always rebuild a plain expression by using the function
assemble_partfrac_list
.Examples
A first example:
>>> f = (2*x**3 - 2*x) / (x**2 - 2*x + 1) >>> pfd = apart_list(f) >>> pfd (1, Poly(2*x + 4, x, domain='ZZ'), [(Poly(_w - 1, _w, domain='ZZ'), Lambda(_a, 4), Lambda(_a, x - _a), 1)])
>>> assemble_partfrac_list(pfd) 2*x + 4 + 4/(x - 1)
Second example:
>>> f = (-2*x - 2*x**2) / (3*x**2 - 6*x) >>> pfd = apart_list(f) >>> pfd (-1, Poly(2/3, x, domain='QQ'), [(Poly(_w - 2, _w, domain='ZZ'), Lambda(_a, 2), Lambda(_a, x - _a), 1)])
>>> assemble_partfrac_list(pfd) -2/3 - 2/(x - 2)
Another example, showing symbolic parameters:
>>> pfd = apart_list(t/(x**2 + x + t), x) >>> pfd (1, Poly(0, x, domain='ZZ[t]'), [(Poly(_w**2 + _w + t, _w, domain='ZZ[t]'), Lambda(_a, -2*t*_a/(4*t - 1) - t/(4*t - 1)), Lambda(_a, x - _a), 1)])
>>> assemble_partfrac_list(pfd) RootSum(t + _w**2 + _w, Lambda(_a, (-2*t*_a/(4*t - 1) - t/(4*t - 1))/(x - _a)))
This example is taken from Bronstein’s original paper:
>>> f = 36 / (x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2) >>> pfd = apart_list(f) >>> pfd (1, Poly(0, x, domain='ZZ'), [(Poly(_w - 2, _w, domain='ZZ'), Lambda(_a, 4), Lambda(_a, x - _a), 1), (Poly(_w**2 - 1, _w, domain='ZZ'), Lambda(_a, -3*_a - 6), Lambda(_a, x - _a), 2), (Poly(_w + 1, _w, domain='ZZ'), Lambda(_a, -4), Lambda(_a, x - _a), 1)])
>>> assemble_partfrac_list(pfd) -4/(x + 1) - 3/(x + 1)**2 - 9/(x - 1)**2 + 4/(x - 2)
See also
References
[BS93]
- diofant.polys.partfrac.assemble_partfrac_list(partial_list)[source]
Reassemble a full partial fraction decomposition from a structured result obtained by the function
apart_list
.Examples
This example is taken from Bronstein’s original paper:
>>> f = 36 / (x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2) >>> pfd = apart_list(f) >>> pfd (1, Poly(0, x, domain='ZZ'), [(Poly(_w - 2, _w, domain='ZZ'), Lambda(_a, 4), Lambda(_a, x - _a), 1), (Poly(_w**2 - 1, _w, domain='ZZ'), Lambda(_a, -3*_a - 6), Lambda(_a, x - _a), 2), (Poly(_w + 1, _w, domain='ZZ'), Lambda(_a, -4), Lambda(_a, x - _a), 1)])
>>> assemble_partfrac_list(pfd) -4/(x + 1) - 3/(x + 1)**2 - 9/(x - 1)**2 + 4/(x - 2)
If we happen to know some roots we can provide them easily inside the structure:
>>> pfd = apart_list(2/(x**2-2)) >>> pfd (1, Poly(0, x, domain='ZZ'), [(Poly(_w**2 - 2, _w, domain='ZZ'), Lambda(_a, _a/2), Lambda(_a, x - _a), 1)])
>>> pfda = assemble_partfrac_list(pfd) >>> pfda RootSum(_w**2 - 2, Lambda(_a, _a/(x - _a)))/2
>>> pfda.doit() -sqrt(2)/(2*(x + sqrt(2))) + sqrt(2)/(2*(x - sqrt(2)))
>>> a = Dummy('a') >>> pfd = (1, Integer(0).as_poly(x), ... [([sqrt(2), -sqrt(2)], ... Lambda(a, a/2), Lambda(a, -a + x), 1)])
>>> assemble_partfrac_list(pfd) -sqrt(2)/(2*(x + sqrt(2))) + sqrt(2)/(2*(x - sqrt(2)))
See also