Reference docs for the Poly Domains¶
This page lists the reference documentation for the domains in the polys
module. For a general introduction to the polys module it is recommended to
read Basic functionality of the module instead. For an introductory explanation of the
what the domain system is and how it is used it is recommended to read
Introducing the Domains of the poly module. This page lists the reference docs for the
Domain
class and its subclasses (the specific domains such as
ZZ
) as well as the classes that represent the domain elements.
Domains¶
Here we document the various implemented ground domains (see
Introducing the Domains of the poly module for more of an explanation). There are three types
of Domain
subclass: abstract domains, concrete domains, and
“implementation domains”. Abstract domains cannot be (usefully) instantiated
at all, and just collect together functionality shared by many other domains.
Concrete domains are those meant to be instantiated and used in the polynomial
manipulation algorithms. In some cases, there are various possible ways to
implement the data type the domain provides. For example, depending on what
libraries are available on the system, the integers are implemented either
using the python built-in integers, or using gmpy. Note that various aliases
are created automatically depending on the libraries available. As such e.g.
ZZ
always refers to the most efficient implementation of the integer ring
available.
Abstract Domains¶
- class sympy.polys.domains.domain.Domain[source]¶
Superclass for all domains in the polys domains system.
See Introducing the Domains of the poly module for an introductory explanation of the domains system.
The
Domain
class is an abstract base class for all of the concrete domain types. There are many differentDomain
subclasses each of which has an associateddtype
which is a class representing the elements of the domain. The coefficients of aPoly
are elements of a domain which must be a subclass ofDomain
.Examples
The most common example domains are the integers ZZ and the rationals QQ.
>>> from sympy import Poly, symbols, Domain >>> x, y = symbols('x, y') >>> p = Poly(x**2 + y) >>> p Poly(x**2 + y, x, y, domain='ZZ') >>> p.domain ZZ >>> isinstance(p.domain, Domain) True >>> Poly(x**2 + y/2) Poly(x**2 + 1/2*y, x, y, domain='QQ')
The domains can be used directly in which case the domain object e.g. (ZZ or QQ) can be used as a constructor for elements of
dtype
.>>> from sympy import ZZ, QQ >>> ZZ(2) 2 >>> ZZ.dtype <class 'int'> >>> type(ZZ(2)) <class 'int'> >>> QQ(1, 2) 1/2 >>> type(QQ(1, 2)) <class 'sympy.polys.domains.pythonrational.PythonRational'>
The corresponding domain elements can be used with the arithmetic operations
+,-,*,**
and depending on the domain some combination of/,//,%
might be usable. For example in ZZ both//
(floor division) and%
(modulo division) can be used but/
(true division) cannot. Since QQ is aField
its elements can be used with/
but//
and%
should not be used. Some domains have agcd()
method.>>> ZZ(2) + ZZ(3) 5 >>> ZZ(5) // ZZ(2) 2 >>> ZZ(5) % ZZ(2) 1 >>> QQ(1, 2) / QQ(2, 3) 3/4 >>> ZZ.gcd(ZZ(4), ZZ(2)) 2 >>> QQ.gcd(QQ(2,7), QQ(5,3)) 1/21 >>> ZZ.is_Field False >>> QQ.is_Field True
There are also many other domains including:
Each domain is represented by a domain object and also an implementation class (
dtype
) for the elements of the domain. For example the K[x] domains are represented by a domain object which is an instance ofPolynomialRing
and the elements are always instances ofPolyElement
. The implementation class represents particular types of mathematical expressions in a way that is more efficient than a normal SymPy expression which is of typeExpr
. The domain methodsfrom_sympy()
andto_sympy()
are used to convert fromExpr
to a domain element and vice versa.>>> from sympy import Symbol, ZZ, Expr >>> x = Symbol('x') >>> K = ZZ[x] # polynomial ring domain >>> K ZZ[x] >>> type(K) # class of the domain <class 'sympy.polys.domains.polynomialring.PolynomialRing'> >>> K.dtype # class of the elements <class 'sympy.polys.rings.PolyElement'> >>> p_expr = x**2 + 1 # Expr >>> p_expr x**2 + 1 >>> type(p_expr) <class 'sympy.core.add.Add'> >>> isinstance(p_expr, Expr) True >>> p_domain = K.from_sympy(p_expr) >>> p_domain # domain element x**2 + 1 >>> type(p_domain) <class 'sympy.polys.rings.PolyElement'> >>> K.to_sympy(p_domain) == p_expr True
The
convert_from()
method is used to convert domain elements from one domain to another.>>> from sympy import ZZ, QQ >>> ez = ZZ(2) >>> eq = QQ.convert_from(ez, ZZ) >>> type(ez) <class 'int'> >>> type(eq) <class 'sympy.polys.domains.pythonrational.PythonRational'>
Elements from different domains should not be mixed in arithmetic or other operations: they should be converted to a common domain first. The domain method
unify()
is used to find a domain that can represent all the elements of two given domains.>>> from sympy import ZZ, QQ, symbols >>> x, y = symbols('x, y') >>> ZZ.unify(QQ) QQ >>> ZZ[x].unify(QQ) QQ[x] >>> ZZ[x].unify(QQ[y]) QQ[x,y]
If a domain is a
Ring
then is might have an associatedField
and vice versa. Theget_field()
andget_ring()
methods will find or create the associated domain.>>> from sympy import ZZ, QQ, Symbol >>> x = Symbol('x') >>> ZZ.has_assoc_Field True >>> ZZ.get_field() QQ >>> QQ.has_assoc_Ring True >>> QQ.get_ring() ZZ >>> K = QQ[x] >>> K QQ[x] >>> K.get_field() QQ(x)
See also
DomainElement
abstract base class for domain elements
construct_domain
construct a minimal domain for some expressions
- alg_field_from_poly(
- poly,
- alias=None,
- root_index=-1,
Convenience method to construct an algebraic extension on a root of a polynomial, chosen by root index.
- Parameters:
poly :
Poly
The polynomial whose root generates the extension.
alias : str, optional (default=None)
Symbol name for the generator of the extension. E.g. “alpha” or “theta”.
root_index : int, optional (default=-1)
Specifies which root of the polynomial is desired. The ordering is as defined by the
ComplexRootOf
class. The default of-1
selects the most natural choice in the common cases of quadratic and cyclotomic fields (the square root on the positive real or imaginary axis, resp. \(\mathrm{e}^{2\pi i/n}\)).
Examples
>>> from sympy import QQ, Poly >>> from sympy.abc import x >>> f = Poly(x**2 - 2) >>> K = QQ.alg_field_from_poly(f) >>> K.ext.minpoly == f True >>> g = Poly(8*x**3 - 6*x - 1) >>> L = QQ.alg_field_from_poly(g, "alpha") >>> L.ext.minpoly == g True >>> L.to_sympy(L([1, 1, 1])) alpha**2 + alpha + 1
- algebraic_field(*extension, alias=None)[source]¶
Returns an algebraic field, i.e. \(K(\alpha, \ldots)\).
- cyclotomic_field(
- n,
- ss=False,
- alias='zeta',
- gen=None,
- root_index=-1,
Convenience method to construct a cyclotomic field.
- Parameters:
n : int
Construct the nth cyclotomic field.
ss : boolean, optional (default=False)
If True, append n as a subscript on the alias string.
alias : str, optional (default=”zeta”)
Symbol name for the generator.
gen :
Symbol
, optional (default=None)Desired variable for the cyclotomic polynomial that defines the field. If
None
, a dummy variable will be used.root_index : int, optional (default=-1)
Specifies which root of the polynomial is desired. The ordering is as defined by the
ComplexRootOf
class. The default of-1
selects the root \(\mathrm{e}^{2\pi i/n}\).
Examples
>>> from sympy import QQ, latex >>> K = QQ.cyclotomic_field(5) >>> K.to_sympy(K([-1, 1])) 1 - zeta >>> L = QQ.cyclotomic_field(7, True) >>> a = L.to_sympy(L([-1, 1])) >>> print(a) 1 - zeta7 >>> print(latex(a)) 1 - \zeta_{7}
- div(a, b)[source]¶
Quotient and remainder for a and b. Analogue of
divmod(a, b)
- Parameters:
a: domain element
The dividend
b: domain element
The divisor
- Returns:
(q, r): tuple of domain elements
The quotient and remainder
- Raises:
ZeroDivisionError: when the divisor is zero.
Explanation
This is essentially the same as
divmod(a, b)
except that is more consistent when working over someField
domains such as QQ. When working over an arbitraryDomain
thediv()
method should be used instead ofdivmod
.The key invariant is that if
q, r = K.div(a, b)
thena == b*q + r
.The result of
K.div(a, b)
is the same as the tuple(K.quo(a, b), K.rem(a, b))
except that if both quotient and remainder are needed then it is more efficient to usediv()
.Examples
We can use
K.div
instead ofdivmod
for floor division and remainder.>>> from sympy import ZZ, QQ >>> ZZ.div(ZZ(5), ZZ(2)) (2, 1)
If
K
is aField
then the division is always exact with a remainder ofzero
.>>> QQ.div(QQ(5), QQ(2)) (5/2, 0)
Notes
If
gmpy
is installed then thegmpy.mpq
type will be used as thedtype
for QQ. Thegmpy.mpq
type definesdivmod
in a way that is undesirable sodiv()
should be used instead ofdivmod
.>>> a = QQ(1) >>> b = QQ(3, 2) >>> a mpq(1,1) >>> b mpq(3,2) >>> divmod(a, b) (mpz(0), mpq(1,1)) >>> QQ.div(a, b) (mpq(2,3), mpq(0,1))
Using
//
or%
with QQ will lead to incorrect results sodiv()
should be used instead.
- dtype: type | None = None¶
The type (class) of the elements of this
Domain
:>>> from sympy import ZZ, QQ, Symbol >>> ZZ.dtype <class 'int'> >>> z = ZZ(2) >>> z 2 >>> type(z) <class 'int'> >>> type(z) == ZZ.dtype True
Every domain has an associated dtype (“datatype”) which is the class of the associated domain elements.
See also
- exquo(a, b)[source]¶
Exact quotient of a and b. Analogue of
a / b
.- Parameters:
a: domain element
The dividend
b: domain element
The divisor
- Returns:
q: domain element
The exact quotient
- Raises:
ExactQuotientFailed: if exact division is not possible.
ZeroDivisionError: when the divisor is zero.
Explanation
This is essentially the same as
a / b
except that an error will be raised if the division is inexact (if there is any remainder) and the result will always be a domain element. When working in aDomain
that is not aField
(e.g. ZZ or K[x])exquo
should be used instead of/
.The key invariant is that if
q = K.exquo(a, b)
(andexquo
does not raise an exception) thena == b*q
.Examples
We can use
K.exquo
instead of/
for exact division.>>> from sympy import ZZ >>> ZZ.exquo(ZZ(4), ZZ(2)) 2 >>> ZZ.exquo(ZZ(5), ZZ(2)) Traceback (most recent call last): ... ExactQuotientFailed: 2 does not divide 5 in ZZ
Over a
Field
such as QQ, division (with nonzero divisor) is always exact so in that case/
can be used instead ofexquo()
.>>> from sympy import QQ >>> QQ.exquo(QQ(5), QQ(2)) 5/2 >>> QQ(5) / QQ(2) 5/2
Notes
Since the default
dtype
for ZZ isint
(ormpz
) division asa / b
should not be used as it would give afloat
which is not a domain element.>>> ZZ(4) / ZZ(2) 2.0 >>> ZZ(5) / ZZ(2) 2.5
On the other hand with \(SYMPY_GROUND_TYPES=flint\) elements of ZZ are
flint.fmpz
and division would raise an exception:>>> ZZ(4) / ZZ(2) Traceback (most recent call last): ... TypeError: unsupported operand type(s) for /: 'fmpz' and 'fmpz'
Using
/
with ZZ will lead to incorrect results soexquo()
should be used instead.
- exsqrt(a)[source]¶
Principal square root of a within the domain if
a
is square.Explanation
The implementation of this method should return an element
b
in the domain such thatb * b == a
, orNone
if there is no suchb
. For inexact domains like RR and CC, a tiny difference in this equality can be tolerated. The choice of a “principal” square root should follow a consistent rule whenever possible.
- from_sympy(a)[source]¶
Convert a SymPy expression to an element of this domain.
- Parameters:
expr: Expr
A normal SymPy expression of type
Expr
.- Returns:
a: domain element
An element of this
Domain
.
Explanation
See
to_sympy()
for explanation and examples.See also
- has_assoc_Field = False¶
Boolean flag indicating if the domain has an associated
Field
.>>> from sympy import ZZ >>> ZZ.has_assoc_Field True >>> ZZ.get_field() QQ
- has_assoc_Ring = False¶
Boolean flag indicating if the domain has an associated
Ring
.>>> from sympy import QQ >>> QQ.has_assoc_Ring True >>> QQ.get_ring() ZZ
- is_Field = False¶
Boolean flag indicating if the domain is a
Field
.>>> from sympy import ZZ, QQ >>> ZZ.is_Field False >>> QQ.is_Field True
See also
- is_PID = False¶
Boolean flag indicating if the domain is a principal ideal domain.
>>> from sympy import ZZ >>> ZZ.has_assoc_Field True >>> ZZ.get_field() QQ
- is_Ring = False¶
Boolean flag indicating if the domain is a
Ring
.>>> from sympy import ZZ >>> ZZ.is_Ring True
Basically every
Domain
represents a ring so this flag is not that useful.See also
- is_square(a)[source]¶
Returns whether
a
is a square in the domain.Explanation
Returns
True
if there is an elementb
in the domain such thatb * b == a
, otherwise returnsFalse
. For inexact domains like RR and CC, a tiny difference in this equality can be tolerated.See also
- one: Any = None¶
The one element of the
Domain
:>>> from sympy import QQ >>> QQ.one 1 >>> QQ.of_type(QQ.one) True
- quo(a, b)[source]¶
Quotient of a and b. Analogue of
a // b
.K.quo(a, b)
is equivalent toK.div(a, b)[0]
. Seediv()
for more explanation.
- rem(a, b)[source]¶
Modulo division of a and b. Analogue of
a % b
.K.rem(a, b)
is equivalent toK.div(a, b)[1]
. Seediv()
for more explanation.
- sqrt(a)[source]¶
Returns a (possibly inexact) square root of
a
.Explanation
There is no universal definition of “inexact square root” for all domains. It is not recommended to implement this method for domains other then ZZ.
See also
- to_sympy(a)[source]¶
Convert domain element a to a SymPy expression (Expr).
- Parameters:
a: domain element
An element of this
Domain
.- Returns:
expr: Expr
A normal SymPy expression of type
Expr
.
Explanation
Convert a
Domain
element a toExpr
. Most public SymPy functions work with objects of typeExpr
. The elements of aDomain
have a different internal representation. It is not possible to mix domain elements withExpr
so each domain hasto_sympy()
andfrom_sympy()
methods to convert its domain elements to and fromExpr
.Examples
Construct an element of the QQ domain and then convert it to
Expr
.>>> from sympy import QQ, Expr >>> q_domain = QQ(2) >>> q_domain 2 >>> q_expr = QQ.to_sympy(q_domain) >>> q_expr 2
Although the printed forms look similar these objects are not of the same type.
>>> isinstance(q_domain, Expr) False >>> isinstance(q_expr, Expr) True
Construct an element of K[x] and convert to
Expr
.>>> from sympy import Symbol >>> x = Symbol('x') >>> K = QQ[x] >>> x_domain = K.gens[0] # generator x as a domain element >>> p_domain = x_domain**2/3 + 1 >>> p_domain 1/3*x**2 + 1 >>> p_expr = K.to_sympy(p_domain) >>> p_expr x**2/3 + 1
The
from_sympy()
method is used for the opposite conversion from a normal SymPy expression to a domain element.>>> p_domain == p_expr False >>> K.from_sympy(p_expr) == p_domain True >>> K.to_sympy(p_domain) == p_expr True >>> K.from_sympy(K.to_sympy(p_domain)) == p_domain True >>> K.to_sympy(K.from_sympy(p_expr)) == p_expr True
The
from_sympy()
method makes it easier to construct domain elements interactively.>>> from sympy import Symbol >>> x = Symbol('x') >>> K = QQ[x] >>> K.from_sympy(x**2/3 + 1) 1/3*x**2 + 1
See also
- class sympy.polys.domains.domainelement.DomainElement[source]¶
Represents an element of a domain.
Mix in this trait into a class whose instances should be recognized as elements of a domain. Method
parent()
gives that domain.
- class sympy.polys.domains.field.Field[source]¶
Represents a field domain.
- gcd(a, b)[source]¶
Returns GCD of
a
andb
.This definition of GCD over fields allows to clear denominators in \(primitive()\).
Examples
>>> from sympy.polys.domains import QQ >>> from sympy import S, gcd, primitive >>> from sympy.abc import x
>>> QQ.gcd(QQ(2, 3), QQ(4, 9)) 2/9 >>> gcd(S(2)/3, S(4)/9) 2/9 >>> primitive(2*x/3 + S(4)/9) (2/9, 3*x + 2)
- class sympy.polys.domains.ring.Ring[source]¶
Represents a ring domain.
- free_module(rank)[source]¶
Generate a free module of rank
rank
over self.>>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(2) QQ[x]**2
- ideal(*gens)[source]¶
Generate an ideal of
self
.>>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).ideal(x**2) <x**2>
- quotient_ring(e)[source]¶
Form a quotient ring of
self
.Here
e
can be an ideal or an iterable.>>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).quotient_ring(QQ.old_poly_ring(x).ideal(x**2)) QQ[x]/<x**2> >>> QQ.old_poly_ring(x).quotient_ring([x**2]) QQ[x]/<x**2>
The division operator has been overloaded for this:
>>> QQ.old_poly_ring(x)/[x**2] QQ[x]/<x**2>
- class sympy.polys.domains.simpledomain.SimpleDomain[source]¶
Base class for simple domains, e.g. ZZ, QQ.
GF(p)¶
- class sympy.polys.domains.FiniteField(mod, symmetric=True)[source]¶
Finite field of prime order GF(p)
A GF(p) domain represents a finite field \(\mathbb{F}_p\) of prime order as
Domain
in the domain system (see Introducing the Domains of the poly module).A
Poly
created from an expression with integer coefficients will have the domain ZZ. However, if themodulus=p
option is given then the domain will be a finite field instead.>>> from sympy import Poly, Symbol >>> x = Symbol('x') >>> p = Poly(x**2 + 1) >>> p Poly(x**2 + 1, x, domain='ZZ') >>> p.domain ZZ >>> p2 = Poly(x**2 + 1, modulus=2) >>> p2 Poly(x**2 + 1, x, modulus=2) >>> p2.domain GF(2)
It is possible to factorise a polynomial over GF(p) using the modulus argument to
factor()
or by specifying the domain explicitly. The domain can also be given as a string.>>> from sympy import factor, GF >>> factor(x**2 + 1) x**2 + 1 >>> factor(x**2 + 1, modulus=2) (x + 1)**2 >>> factor(x**2 + 1, domain=GF(2)) (x + 1)**2 >>> factor(x**2 + 1, domain='GF(2)') (x + 1)**2
It is also possible to use GF(p) with the
cancel()
andgcd()
functions.>>> from sympy import cancel, gcd >>> cancel((x**2 + 1)/(x + 1)) (x**2 + 1)/(x + 1) >>> cancel((x**2 + 1)/(x + 1), domain=GF(2)) x + 1 >>> gcd(x**2 + 1, x + 1) 1 >>> gcd(x**2 + 1, x + 1, domain=GF(2)) x + 1
When using the domain directly GF(p) can be used as a constructor to create instances which then support the operations
+,-,*,**,/
>>> from sympy import GF >>> K = GF(5) >>> K GF(5) >>> x = K(3) >>> y = K(2) >>> x 3 mod 5 >>> y 2 mod 5 >>> x * y 1 mod 5 >>> x / y 4 mod 5
Notes
It is also possible to create a GF(p) domain of non-prime order but the resulting ring is not a field: it is just the ring of the integers modulo
n
.>>> K = GF(9) >>> z = K(3) >>> z 3 mod 9 >>> z**2 0 mod 9
It would be good to have a proper implementation of prime power fields (
GF(p**n)
) but these are not yet implemented in SymPY.
ZZ¶
The ZZ domain represents the integers \(\mathbb{Z}\) as a
Domain
in the domain system (see Introducing the Domains of the poly module).
By default a Poly
created from an expression with integer
coefficients will have the domain ZZ:
>>> from sympy import Poly, Symbol
>>> x = Symbol('x')
>>> p = Poly(x**2 + 1)
>>> p
Poly(x**2 + 1, x, domain='ZZ')
>>> p.domain
ZZ
The corresponding field of fractions is the domain of the rationals QQ. Conversely ZZ is the ring of integers of QQ:
>>> from sympy import ZZ, QQ
>>> ZZ.get_field()
QQ
>>> QQ.get_ring()
ZZ
When using the domain directly ZZ can be used as a constructor to
create instances which then support the operations +,-,*,**,//,%
(true
division /
should not be used with ZZ - see the
exquo()
domain method):
>>> x = ZZ(5)
>>> y = ZZ(2)
>>> x // y # floor division
2
>>> x % y # modulo division (remainder)
1
The gcd()
method can be used to compute the gcd of any
two elements:
>>> ZZ.gcd(ZZ(10), ZZ(2))
2
There are two implementations of ZZ in SymPy. If gmpy
or gmpy2
is installed then ZZ will be implemented by GMPYIntegerRing
and the elements will be instances of the gmpy.mpz
type. Otherwise if
gmpy
and gmpy2
are not installed then ZZ will be implemented by
PythonIntegerRing
which uses Python’s standard builtin int
type. With larger integers gmpy
can be more efficient so it is preferred
when available.
- class sympy.polys.domains.IntegerRing[source]¶
The domain
ZZ
representing the integers \(\mathbb{Z}\).The
IntegerRing
class represents the ring of integers as aDomain
in the domain system.IntegerRing
is a super class ofPythonIntegerRing
andGMPYIntegerRing
one of which will be the implementation for ZZ depending on whether or notgmpy
orgmpy2
is installed.See also
- algebraic_field(
- *extension,
- alias=None,
Returns an algebraic field, i.e. \(\mathbb{Q}(\alpha, \ldots)\).
- Parameters:
*extension : One or more
Expr
.Generators of the extension. These should be expressions that are algebraic over \(\mathbb{Q}\).
alias : str,
Symbol
, None, optional (default=None)If provided, this will be used as the alias symbol for the primitive element of the returned
AlgebraicField
.- Returns:
-
A
Domain
representing the algebraic field extension.
Examples
>>> from sympy import ZZ, sqrt >>> ZZ.algebraic_field(sqrt(2)) QQ<sqrt(2)>
- get_field()[source]¶
Return the associated field of fractions QQ
- Returns:
QQ:
Examples
>>> from sympy import ZZ >>> ZZ.get_field() QQ
- is_square(a)[source]¶
Return
True
ifa
is a square.Explanation
An integer is a square if and only if there exists an integer
b
such thatb * b == a
.
- log(a, b)[source]¶
Logarithm of a to the base b.
- Parameters:
a: number
b: number
- Returns:
\(\\lfloor\log(a, b)\\rfloor\):
Floor of the logarithm of a to the base b
Examples
>>> from sympy import ZZ >>> ZZ.log(ZZ(8), ZZ(2)) 3 >>> ZZ.log(ZZ(9), ZZ(2)) 3
Notes
This function uses
math.log
which is based onfloat
so it will fail for large integer arguments.
- class sympy.polys.domains.PythonIntegerRing[source]¶
Integer ring based on Python’s
int
type.This will be used as ZZ if
gmpy
andgmpy2
are not installed. Elements are instances of the standard Pythonint
type.
QQ¶
The QQ domain represents the rationals \(\mathbb{Q}\) as a
Domain
in the domain system (see Introducing the Domains of the poly module).
By default a Poly
created from an expression with rational
coefficients will have the domain QQ:
>>> from sympy import Poly, Symbol
>>> x = Symbol('x')
>>> p = Poly(x**2 + x/2)
>>> p
Poly(x**2 + 1/2*x, x, domain='QQ')
>>> p.domain
QQ
The corresponding ring of integers is the Domain
of the
integers ZZ. Conversely QQ is the field of fractions of
ZZ:
>>> from sympy import ZZ, QQ
>>> QQ.get_ring()
ZZ
>>> ZZ.get_field()
QQ
When using the domain directly QQ can be used as a constructor to
create instances which then support the operations +,-,*,**,/
(true
division /
is always possible for nonzero divisors in QQ):
>>> x = QQ(5)
>>> y = QQ(2)
>>> x / y # true division
5/2
There are two implementations of QQ in SymPy. If gmpy
or gmpy2
is installed then QQ will be implemented by
GMPYRationalField
and the elements will be instances of the
gmpy.mpq
type. Otherwise if gmpy
and gmpy2
are not installed then
QQ will be implemented by PythonRationalField
which is a
pure Python class as part of sympy. The gmpy
implementation is
preferred because it is significantly faster.
- class sympy.polys.domains.RationalField[source]¶
Abstract base class for the domain QQ.
The
RationalField
class represents the field of rational numbers \(\mathbb{Q}\) as aDomain
in the domain system.RationalField
is a superclass ofPythonRationalField
andGMPYRationalField
one of which will be the implementation for QQ depending on whether either ofgmpy
orgmpy2
is installed or not.See also
- algebraic_field(
- *extension,
- alias=None,
Returns an algebraic field, i.e. \(\mathbb{Q}(\alpha, \ldots)\).
- Parameters:
*extension : One or more
Expr
Generators of the extension. These should be expressions that are algebraic over \(\mathbb{Q}\).
alias : str,
Symbol
, None, optional (default=None)If provided, this will be used as the alias symbol for the primitive element of the returned
AlgebraicField
.- Returns:
-
A
Domain
representing the algebraic field extension.
Examples
>>> from sympy import QQ, sqrt >>> QQ.algebraic_field(sqrt(2)) QQ<sqrt(2)>
- class sympy.polys.domains.PythonRationalField[source]¶
Rational field based on MPQ.
This will be used as QQ if
gmpy
andgmpy2
are not installed. Elements are instances of MPQ.
- class sympy.polys.domains.GMPYRationalField[source]¶
Rational field based on GMPY’s
mpq
type.This will be the implementation of QQ if
gmpy
orgmpy2
is installed. Elements will be of typegmpy.mpq
.
- class sympy.external.pythonmpq.PythonMPQ(numerator, denominator=None)[source]¶
Rational number implementation that is intended to be compatible with gmpy2’s mpq.
Also slightly faster than fractions.Fraction.
PythonMPQ should be treated as immutable although no effort is made to prevent mutation (since that might slow down calculations).
MPQ¶
The MPQ
type is either PythonMPQ
or otherwise the mpq
type from gmpy2
.
Gaussian domains¶
The Gaussian domains ZZ_I and QQ_I share common superclasses
GaussianElement
for the domain elements and
GaussianDomain
for the domains themselves.
ZZ_I¶
- class sympy.polys.domains.gaussiandomains.GaussianIntegerRing[source]¶
Ring of Gaussian integers
ZZ_I
The ZZ_I domain represents the Gaussian integers \(\mathbb{Z}[i]\) as a
Domain
in the domain system (see Introducing the Domains of the poly module).By default a
Poly
created from an expression with coefficients that are combinations of integers andI
(\(\sqrt{-1}\)) will have the domain ZZ_I.>>> from sympy import Poly, Symbol, I >>> x = Symbol('x') >>> p = Poly(x**2 + I) >>> p Poly(x**2 + I, x, domain='ZZ_I') >>> p.domain ZZ_I
The ZZ_I domain can be used to factorise polynomials that are reducible over the Gaussian integers.
>>> from sympy import factor >>> factor(x**2 + 1) x**2 + 1 >>> factor(x**2 + 1, domain='ZZ_I') (x - I)*(x + I)
The corresponding field of fractions is the domain of the Gaussian rationals QQ_I. Conversely ZZ_I is the ring of integers of QQ_I.
>>> from sympy import ZZ_I, QQ_I >>> ZZ_I.get_field() QQ_I >>> QQ_I.get_ring() ZZ_I
When using the domain directly ZZ_I can be used as a constructor.
>>> ZZ_I(3, 4) (3 + 4*I) >>> ZZ_I(5) (5 + 0*I)
The domain elements of ZZ_I are instances of
GaussianInteger
which support the rings operations+,-,*,**
.>>> z1 = ZZ_I(5, 1) >>> z2 = ZZ_I(2, 3) >>> z1 (5 + 1*I) >>> z2 (2 + 3*I) >>> z1 + z2 (7 + 4*I) >>> z1 * z2 (7 + 17*I) >>> z1 ** 2 (24 + 10*I)
Both floor (
//
) and modulo (%
) division work withGaussianInteger
(see thediv()
method).>>> z3, z4 = ZZ_I(5), ZZ_I(1, 3) >>> z3 // z4 # floor division (1 + -1*I) >>> z3 % z4 # modulo division (remainder) (1 + -2*I) >>> (z3//z4)*z4 + z3%z4 == z3 True
True division (
/
) in ZZ_I gives an element of QQ_I. Theexquo()
method can be used to divide in ZZ_I when exact division is possible.>>> z1 / z2 (1 + -1*I) >>> ZZ_I.exquo(z1, z2) (1 + -1*I) >>> z3 / z4 (1/2 + -3/2*I) >>> ZZ_I.exquo(z3, z4) Traceback (most recent call last): ... ExactQuotientFailed: (1 + 3*I) does not divide (5 + 0*I) in ZZ_I
The
gcd()
method can be used to compute the gcd of any two elements.>>> ZZ_I.gcd(ZZ_I(10), ZZ_I(2)) (2 + 0*I) >>> ZZ_I.gcd(ZZ_I(5), ZZ_I(2, 1)) (2 + 1*I)
- dtype[source]¶
alias of
GaussianInteger
QQ_I¶
- class sympy.polys.domains.gaussiandomains.GaussianRationalField[source]¶
Field of Gaussian rationals
QQ_I
The QQ_I domain represents the Gaussian rationals \(\mathbb{Q}(i)\) as a
Domain
in the domain system (see Introducing the Domains of the poly module).By default a
Poly
created from an expression with coefficients that are combinations of rationals andI
(\(\sqrt{-1}\)) will have the domain QQ_I.>>> from sympy import Poly, Symbol, I >>> x = Symbol('x') >>> p = Poly(x**2 + I/2) >>> p Poly(x**2 + I/2, x, domain='QQ_I') >>> p.domain QQ_I
The polys option
gaussian=True
can be used to specify that the domain should be QQ_I even if the coefficients do not containI
or are all integers.>>> Poly(x**2) Poly(x**2, x, domain='ZZ') >>> Poly(x**2 + I) Poly(x**2 + I, x, domain='ZZ_I') >>> Poly(x**2/2) Poly(1/2*x**2, x, domain='QQ') >>> Poly(x**2, gaussian=True) Poly(x**2, x, domain='QQ_I') >>> Poly(x**2 + I, gaussian=True) Poly(x**2 + I, x, domain='QQ_I') >>> Poly(x**2/2, gaussian=True) Poly(1/2*x**2, x, domain='QQ_I')
The QQ_I domain can be used to factorise polynomials that are reducible over the Gaussian rationals.
>>> from sympy import factor, QQ_I >>> factor(x**2/4 + 1) (x**2 + 4)/4 >>> factor(x**2/4 + 1, domain='QQ_I') (x - 2*I)*(x + 2*I)/4 >>> factor(x**2/4 + 1, domain=QQ_I) (x - 2*I)*(x + 2*I)/4
It is also possible to specify the QQ_I domain explicitly with polys functions like
apart()
.>>> from sympy import apart >>> apart(1/(1 + x**2)) 1/(x**2 + 1) >>> apart(1/(1 + x**2), domain=QQ_I) I/(2*(x + I)) - I/(2*(x - I))
The corresponding ring of integers is the domain of the Gaussian integers ZZ_I. Conversely QQ_I is the field of fractions of ZZ_I.
>>> from sympy import ZZ_I, QQ_I, QQ >>> ZZ_I.get_field() QQ_I >>> QQ_I.get_ring() ZZ_I
When using the domain directly QQ_I can be used as a constructor.
>>> QQ_I(3, 4) (3 + 4*I) >>> QQ_I(5) (5 + 0*I) >>> QQ_I(QQ(2, 3), QQ(4, 5)) (2/3 + 4/5*I)
The domain elements of QQ_I are instances of
GaussianRational
which support the field operations+,-,*,**,/
.>>> z1 = QQ_I(5, 1) >>> z2 = QQ_I(2, QQ(1, 2)) >>> z1 (5 + 1*I) >>> z2 (2 + 1/2*I) >>> z1 + z2 (7 + 3/2*I) >>> z1 * z2 (19/2 + 9/2*I) >>> z2 ** 2 (15/4 + 2*I)
True division (
/
) in QQ_I gives an element of QQ_I and is always exact.>>> z1 / z2 (42/17 + -2/17*I) >>> QQ_I.exquo(z1, z2) (42/17 + -2/17*I) >>> z1 == (z1/z2)*z2 True
Both floor (
//
) and modulo (%
) division can be used withGaussianRational
(seediv()
) but division is always exact so there is no remainder.>>> z1 // z2 (42/17 + -2/17*I) >>> z1 % z2 (0 + 0*I) >>> QQ_I.div(z1, z2) ((42/17 + -2/17*I), (0 + 0*I)) >>> (z1//z2)*z2 + z1%z2 == z1 True
- dtype[source]¶
alias of
GaussianRational
QQ<a>¶
- class sympy.polys.domains.AlgebraicField(dom, *ext, alias=None)[source]¶
Algebraic number field QQ<a>
A QQ<a> domain represents an algebraic number field \(\mathbb{Q}(a)\) as a
Domain
in the domain system (see Introducing the Domains of the poly module).A
Poly
created from an expression involving algebraic numbers will treat the algebraic numbers as generators if the generators argument is not specified.>>> from sympy import Poly, Symbol, sqrt >>> x = Symbol('x') >>> Poly(x**2 + sqrt(2)) Poly(x**2 + (sqrt(2)), x, sqrt(2), domain='ZZ')
That is a multivariate polynomial with
sqrt(2)
treated as one of the generators (variables). If the generators are explicitly specified thensqrt(2)
will be considered to be a coefficient but by default the EX domain is used. To make aPoly
with a QQ<a> domain the argumentextension=True
can be given.>>> Poly(x**2 + sqrt(2), x) Poly(x**2 + sqrt(2), x, domain='EX') >>> Poly(x**2 + sqrt(2), x, extension=True) Poly(x**2 + sqrt(2), x, domain='QQ<sqrt(2)>')
A generator of the algebraic field extension can also be specified explicitly which is particularly useful if the coefficients are all rational but an extension field is needed (e.g. to factor the polynomial).
>>> Poly(x**2 + 1) Poly(x**2 + 1, x, domain='ZZ') >>> Poly(x**2 + 1, extension=sqrt(2)) Poly(x**2 + 1, x, domain='QQ<sqrt(2)>')
It is possible to factorise a polynomial over a QQ<a> domain using the
extension
argument tofactor()
or by specifying the domain explicitly.>>> from sympy import factor, QQ >>> factor(x**2 - 2) x**2 - 2 >>> factor(x**2 - 2, extension=sqrt(2)) (x - sqrt(2))*(x + sqrt(2)) >>> factor(x**2 - 2, domain='QQ<sqrt(2)>') (x - sqrt(2))*(x + sqrt(2)) >>> factor(x**2 - 2, domain=QQ.algebraic_field(sqrt(2))) (x - sqrt(2))*(x + sqrt(2))
The
extension=True
argument can be used but will only create an extension that contains the coefficients which is usually not enough to factorise the polynomial.>>> p = x**3 + sqrt(2)*x**2 - 2*x - 2*sqrt(2) >>> factor(p) # treats sqrt(2) as a symbol (x + sqrt(2))*(x**2 - 2) >>> factor(p, extension=True) (x - sqrt(2))*(x + sqrt(2))**2 >>> factor(x**2 - 2, extension=True) # all rational coefficients x**2 - 2
It is also possible to use QQ<a> with the
cancel()
andgcd()
functions.>>> from sympy import cancel, gcd >>> cancel((x**2 - 2)/(x - sqrt(2))) (x**2 - 2)/(x - sqrt(2)) >>> cancel((x**2 - 2)/(x - sqrt(2)), extension=sqrt(2)) x + sqrt(2) >>> gcd(x**2 - 2, x - sqrt(2)) 1 >>> gcd(x**2 - 2, x - sqrt(2), extension=sqrt(2)) x - sqrt(2)
When using the domain directly QQ<a> can be used as a constructor to create instances which then support the operations
+,-,*,**,/
. Thealgebraic_field()
method is used to construct a particular QQ<a> domain. Thefrom_sympy()
method can be used to create domain elements from normal SymPy expressions.>>> K = QQ.algebraic_field(sqrt(2)) >>> K QQ<sqrt(2)> >>> xk = K.from_sympy(3 + 4*sqrt(2)) >>> xk ANP([4, 3], [1, 0, -2], QQ)
Elements of QQ<a> are instances of
ANP
which have limited printing support. The raw display shows the internal representation of the element as the list[4, 3]
representing the coefficients of1
andsqrt(2)
for this element in the forma * sqrt(2) + b * 1
wherea
andb
are elements of QQ. The minimal polynomial for the generator(x**2 - 2)
is also shown in the DUP representation as the list[1, 0, -2]
. We can useto_sympy()
to get a better printed form for the elements and to see the results of operations.>>> xk = K.from_sympy(3 + 4*sqrt(2)) >>> yk = K.from_sympy(2 + 3*sqrt(2)) >>> xk * yk ANP([17, 30], [1, 0, -2], QQ) >>> K.to_sympy(xk * yk) 17*sqrt(2) + 30 >>> K.to_sympy(xk + yk) 5 + 7*sqrt(2) >>> K.to_sympy(xk ** 2) 24*sqrt(2) + 41 >>> K.to_sympy(xk / yk) sqrt(2)/14 + 9/7
Any expression representing an algebraic number can be used to generate a QQ<a> domain provided its minimal polynomial can be computed. The function
minpoly()
function is used for this.>>> from sympy import exp, I, pi, minpoly >>> g = exp(2*I*pi/3) >>> g exp(2*I*pi/3) >>> g.is_algebraic True >>> minpoly(g, x) x**2 + x + 1 >>> factor(x**3 - 1, extension=g) (x - 1)*(x - exp(2*I*pi/3))*(x + 1 + exp(2*I*pi/3))
It is also possible to make an algebraic field from multiple extension elements.
>>> K = QQ.algebraic_field(sqrt(2), sqrt(3)) >>> K QQ<sqrt(2) + sqrt(3)> >>> p = x**4 - 5*x**2 + 6 >>> factor(p) (x**2 - 3)*(x**2 - 2) >>> factor(p, domain=K) (x - sqrt(2))*(x + sqrt(2))*(x - sqrt(3))*(x + sqrt(3)) >>> factor(p, extension=[sqrt(2), sqrt(3)]) (x - sqrt(2))*(x + sqrt(2))*(x - sqrt(3))*(x + sqrt(3))
Multiple extension elements are always combined together to make a single primitive element. In the case of
[sqrt(2), sqrt(3)]
the primitive element chosen issqrt(2) + sqrt(3)
which is why the domain displays asQQ<sqrt(2) + sqrt(3)>
. The minimal polynomial for the primitive element is computed using theprimitive_element()
function.>>> from sympy import primitive_element >>> primitive_element([sqrt(2), sqrt(3)], x) (x**4 - 10*x**2 + 1, [1, 1]) >>> minpoly(sqrt(2) + sqrt(3), x) x**4 - 10*x**2 + 1
The extension elements that generate the domain can be accessed from the domain using the
ext
andorig_ext
attributes as instances ofAlgebraicNumber
. The minimal polynomial for the primitive element as aDMP
instance is available asmod
.>>> K = QQ.algebraic_field(sqrt(2), sqrt(3)) >>> K QQ<sqrt(2) + sqrt(3)> >>> K.ext sqrt(2) + sqrt(3) >>> K.orig_ext (sqrt(2), sqrt(3)) >>> K.mod DMP_Python([1, 0, -10, 0, 1], QQ)
The discriminant of the field can be obtained from the
discriminant()
method, and an integral basis from theintegral_basis()
method. The latter returns a list ofANP
instances by default, but can be made to return instances ofExpr
orAlgebraicNumber
by passing afmt
argument. The maximal order, or ring of integers, of the field can also be obtained from themaximal_order()
method, as aSubmodule
.>>> zeta5 = exp(2*I*pi/5) >>> K = QQ.algebraic_field(zeta5) >>> K QQ<exp(2*I*pi/5)> >>> K.discriminant() 125 >>> K = QQ.algebraic_field(sqrt(5)) >>> K QQ<sqrt(5)> >>> K.integral_basis(fmt='sympy') [1, 1/2 + sqrt(5)/2] >>> K.maximal_order() Submodule[[2, 0], [1, 1]]/2
The factorization of a rational prime into prime ideals of the field is computed by the
primes_above()
method, which returns a list ofPrimeIdeal
instances.>>> zeta7 = exp(2*I*pi/7) >>> K = QQ.algebraic_field(zeta7) >>> K QQ<exp(2*I*pi/7)> >>> K.primes_above(11) [(11, _x**3 + 5*_x**2 + 4*_x - 1), (11, _x**3 - 4*_x**2 - 5*_x - 1)]
The Galois group of the Galois closure of the field can be computed (when the minimal polynomial of the field is of sufficiently small degree).
>>> K.galois_group(by_name=True)[0] S6TransitiveSubgroups.C6
Notes
It is not currently possible to generate an algebraic extension over any domain other than QQ. Ideally it would be possible to generate extensions like
QQ(x)(sqrt(x**2 - 2))
. This is equivalent to the quotient ringQQ(x)[y]/(y**2 - x**2 + 2)
and there are two implementations of this kind of quotient ring/extension in theQuotientRing
andMonogenicFiniteExtension
classes. Each of those implementations needs some work to make them fully usable though.- algebraic_field(
- *extension,
- alias=None,
Returns an algebraic field, i.e. \(\mathbb{Q}(\alpha, \ldots)\).
- ext¶
Primitive element used for the extension.
>>> from sympy import QQ, sqrt >>> K = QQ.algebraic_field(sqrt(2), sqrt(3)) >>> K.ext sqrt(2) + sqrt(3)
- galois_group(
- by_name=False,
- max_tries=30,
- randomize=False,
Compute the Galois group of the Galois closure of this field.
Examples
If the field is Galois, the order of the group will equal the degree of the field:
>>> from sympy import QQ >>> from sympy.abc import x >>> k = QQ.alg_field_from_poly(x**4 + 1) >>> G, _ = k.galois_group() >>> G.order() 4
If the field is not Galois, then its Galois closure is a proper extension, and the order of the Galois group will be greater than the degree of the field:
>>> k = QQ.alg_field_from_poly(x**4 - 2) >>> G, _ = k.galois_group() >>> G.order() 8
- integral_basis(fmt=None)[source]¶
Get an integral basis for the field.
- Parameters:
fmt : str, None, optional (default=None)
If
None
, return a list ofANP
instances. If"sympy"
, convert each element of the list to anExpr
, usingself.to_sympy()
. If"alg"
, convert each element of the list to anAlgebraicNumber
, usingself.to_alg_num()
.
Examples
>>> from sympy import QQ, AlgebraicNumber, sqrt >>> alpha = AlgebraicNumber(sqrt(5), alias='alpha') >>> k = QQ.algebraic_field(alpha) >>> B0 = k.integral_basis() >>> B1 = k.integral_basis(fmt='sympy') >>> B2 = k.integral_basis(fmt='alg') >>> print(B0[1]) ANP([mpq(1,2), mpq(1,2)], [mpq(1,1), mpq(0,1), mpq(-5,1)], QQ) >>> print(B1[1]) 1/2 + alpha/2 >>> print(B2[1]) alpha/2 + 1/2
In the last two cases we get legible expressions, which print somewhat differently because of the different types involved:
>>> print(type(B1[1])) <class 'sympy.core.add.Add'> >>> print(type(B2[1])) <class 'sympy.core.numbers.AlgebraicNumber'>
See also
- maximal_order()[source]¶
Compute the maximal order, or ring of integers, of the field.
- Returns:
See also
- mod¶
Minimal polynomial for the primitive element of the extension.
>>> from sympy import QQ, sqrt >>> K = QQ.algebraic_field(sqrt(2)) >>> K.mod DMP([1, 0, -2], QQ)
- orig_ext¶
Original elements given to generate the extension.
>>> from sympy import QQ, sqrt >>> K = QQ.algebraic_field(sqrt(2), sqrt(3)) >>> K.orig_ext (sqrt(2), sqrt(3))
- to_alg_num(a)[source]¶
Convert
a
ofdtype
to anAlgebraicNumber
.
RR¶
CC¶
- class sympy.polys.domains.ComplexField(prec=None, dps=None, tol=None)[source]¶
Complex numbers up to the given precision.
K[x]¶
K(x)¶
EX¶
- class sympy.polys.domains.ExpressionDomain[source]¶
A class for arbitrary expressions.
- dtype[source]¶
alias of
Expression
Quotient ring¶
- class sympy.polys.domains.quotientring.QuotientRing(ring, ideal)[source]¶
Class representing (commutative) quotient rings.
You should not usually instantiate this by hand, instead use the constructor from the base ring in the construction.
>>> from sympy.abc import x >>> from sympy import QQ >>> I = QQ.old_poly_ring(x).ideal(x**3 + 1) >>> QQ.old_poly_ring(x).quotient_ring(I) QQ[x]/<x**3 + 1>
Shorter versions are possible:
>>> QQ.old_poly_ring(x)/I QQ[x]/<x**3 + 1>
>>> QQ.old_poly_ring(x)/[x**3 + 1] QQ[x]/<x**3 + 1>
Attributes:
ring - the base ring
base_ideal - the ideal used to form the quotient
Sparse polynomials¶
Sparse polynomials are represented as dictionaries.
- sympy.polys.rings.ring(
- symbols,
- domain,
- order: MonomialOrder | str = LexOrder(),
Construct a polynomial ring returning
(ring, x_1, ..., x_n)
.- Parameters:
symbols : str
Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
domain :
Domain
or coercibleorder :
MonomialOrder
or coercible, optional, defaults tolex
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex
>>> R, x, y, z = ring("x,y,z", ZZ, lex) >>> R Polynomial ring in x, y, z over ZZ with lex order >>> x + y + z x + y + z >>> type(_) <class 'sympy.polys.rings.PolyElement'>
- sympy.polys.rings.xring(symbols, domain, order=LexOrder())[source]¶
Construct a polynomial ring returning
(ring, (x_1, ..., x_n))
.- Parameters:
symbols : str
Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
domain :
Domain
or coercibleorder :
MonomialOrder
or coercible, optional, defaults tolex
Examples
>>> from sympy.polys.rings import xring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex
>>> R, (x, y, z) = xring("x,y,z", ZZ, lex) >>> R Polynomial ring in x, y, z over ZZ with lex order >>> x + y + z x + y + z >>> type(_) <class 'sympy.polys.rings.PolyElement'>
- sympy.polys.rings.vring(symbols, domain, order=LexOrder())[source]¶
Construct a polynomial ring and inject
x_1, ..., x_n
into the global namespace.- Parameters:
symbols : str
Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
domain :
Domain
or coercibleorder :
MonomialOrder
or coercible, optional, defaults tolex
Examples
>>> from sympy.polys.rings import vring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex
>>> vring("x,y,z", ZZ, lex) Polynomial ring in x, y, z over ZZ with lex order >>> x + y + z # noqa: x + y + z >>> type(_) <class 'sympy.polys.rings.PolyElement'>
- sympy.polys.rings.sring(exprs, *symbols, **options)[source]¶
Construct a ring deriving generators and domain from options and input expressions.
- Parameters:
exprs :
Expr
or sequence ofExpr
(sympifiable)symbols : sequence of
Symbol
/Expr
options : keyword arguments understood by
Options
Examples
>>> from sympy import sring, symbols
>>> x, y, z = symbols("x,y,z") >>> R, f = sring(x + 2*y + 3*z) >>> R Polynomial ring in x, y, z over ZZ with lex order >>> f x + 2*y + 3*z >>> type(_) <class 'sympy.polys.rings.PolyElement'>
- class sympy.polys.rings.PolyRing(symbols, domain, order=LexOrder())[source]¶
Multivariate distributed polynomial ring.
- add(*objs)[source]¶
Add a sequence of polynomials or containers of polynomials.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> R, x = ring("x", ZZ) >>> R.add([ x**2 + 2*i + 3 for i in range(4) ]) 4*x**2 + 24 >>> _.factor_list() (4, [(x**2 + 6, 1)])
- drop_to_ground(*gens)[source]¶
Remove specified generators from the ring and inject them into its domain.
- mul(*objs)[source]¶
Multiply a sequence of polynomials or containers of polynomials.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> R, x = ring("x", ZZ) >>> R.mul([ x**2 + 2*i + 3 for i in range(4) ]) x**8 + 24*x**6 + 206*x**4 + 744*x**2 + 945 >>> _.factor_list() (1, [(x**2 + 3, 1), (x**2 + 5, 1), (x**2 + 7, 1), (x**2 + 9, 1)])
- class sympy.polys.rings.PolyElement[source]¶
Element of multivariate distributed polynomial ring.
- cancel(g)[source]¶
Cancel common factors in a rational function
f/g
.Examples
>>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ)
>>> (2*x**2 - 2).cancel(x**2 - 2*x + 1) (2*x + 2, x - 1)
- coeff(element)[source]¶
Returns the coefficient that stands next to the given monomial.
- Parameters:
element : PolyElement (with
is_monomial = True
) or 1
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y, z = ring("x,y,z", ZZ) >>> f = 3*x**2*y - x*y*z + 7*z**3 + 23
>>> f.coeff(x**2*y) 3 >>> f.coeff(x*y) 0 >>> f.coeff(1) 23
- coeff_wrt(x, deg)[source]¶
Coefficient of
self
with respect tox**deg
.Treating
self
as a univariate polynomial inx
this finds the coefficient ofx**deg
as a polynomial in the other generators.- Parameters:
x : generator or generator index
The generator or generator index to compute the expression for.
deg : int
The degree of the monomial to compute the expression for.
- Returns:
-
The coefficient of
x**deg
as a polynomial in the same ring.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x, y, z = ring("x, y, z", ZZ)
>>> p = 2*x**4 + 3*y**4 + 10*z**2 + 10*x*z**2 >>> deg = 2 >>> p.coeff_wrt(2, deg) # Using the generator index 10*x + 10 >>> p.coeff_wrt(z, deg) # Using the generator 10*x + 10 >>> p.coeff(z**2) # shows the difference between coeff and coeff_wrt 10
- coeffs(order=None)[source]¶
Ordered list of polynomial coefficients.
- Parameters:
order :
MonomialOrder
or coercible, optional
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex, grlex
>>> _, x, y = ring("x, y", ZZ, lex) >>> f = x*y**7 + 2*x**2*y**3
>>> f.coeffs() [2, 1] >>> f.coeffs(grlex) [1, 2]
- copy()[source]¶
Return a copy of polynomial self.
Polynomials are mutable; if one is interested in preserving a polynomial, and one plans to use inplace operations, one can copy the polynomial. This method makes a shallow copy.
Examples
>>> from sympy.polys.domains import ZZ >>> from sympy.polys.rings import ring
>>> R, x, y = ring('x, y', ZZ) >>> p = (x + y)**2 >>> p1 = p.copy() >>> p2 = p >>> p[R.zero_monom] = 3 >>> p x**2 + 2*x*y + y**2 + 3 >>> p1 x**2 + 2*x*y + y**2 >>> p2 x**2 + 2*x*y + y**2 + 3
- degree(x=None)[source]¶
The leading degree in
x
or the main variable.Note that the degree of 0 is negative infinity (
float('-inf')
)
- degrees()[source]¶
A tuple containing leading degrees in all variables.
Note that the degree of 0 is negative infinity (
float('-inf')
)
- diff(x)[source]¶
Computes partial derivative in
x
.Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring("x,y", ZZ) >>> p = x + x**2*y**3 >>> p.diff(x) 2*x*y**3 + 1
- div(fv)[source]¶
Division algorithm, see [CLO] p64.
- fv array of polynomials
return qv, r such that self = sum(fv[i]*qv[i]) + r
All polynomials are required not to be Laurent polynomials.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring('x, y', ZZ) >>> f = x**3 >>> f0 = x - y**2 >>> f1 = x - y >>> qv, r = f.div((f0, f1)) >>> qv[0] x**2 + x*y**2 + y**4 >>> qv[1] 0 >>> r y**6
- imul_num(c)[source]¶
multiply inplace the polynomial p by an element in the coefficient ring, provided p is not one of the generators; else multiply not inplace
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring('x, y', ZZ) >>> p = x + y**2 >>> p1 = p.imul_num(3) >>> p1 3*x + 3*y**2 >>> p1 is p True >>> p = x >>> p1 = p.imul_num(3) >>> p1 3*x >>> p1 is p False
- leading_expv()[source]¶
Leading monomial tuple according to the monomial ordering.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y, z = ring('x, y, z', ZZ) >>> p = x**4 + x**3*y + x**2*z**2 + z**7 >>> p.leading_expv() (4, 0, 0)
- leading_monom()[source]¶
Leading monomial as a polynomial element.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring('x, y', ZZ) >>> (3*x*y + y**2).leading_monom() x*y
- leading_term()[source]¶
Leading term as a polynomial element.
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring('x, y', ZZ) >>> (3*x*y + y**2).leading_term() 3*x*y
- monoms(order=None)[source]¶
Ordered list of polynomial monomials.
- Parameters:
order :
MonomialOrder
or coercible, optional
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex, grlex
>>> _, x, y = ring("x, y", ZZ, lex) >>> f = x*y**7 + 2*x**2*y**3
>>> f.monoms() [(2, 3), (1, 7)] >>> f.monoms(grlex) [(1, 7), (2, 3)]
- pdiv(g, x=None)[source]¶
Computes the pseudo-division of the polynomial
self
with respect tog
.The pseudo-division algorithm is used to find the pseudo-quotient
q
and pseudo-remainderr
such thatm*f = g*q + r
, wherem
represents the multiplier andf
is the dividend polynomial.The pseudo-quotient
q
and pseudo-remainderr
are polynomials in the variablex
, with the degree ofr
with respect tox
being strictly less than the degree ofg
with respect tox
.The multiplier
m
is defined asLC(g, x) ^ (deg(f, x) - deg(g, x) + 1)
, whereLC(g, x)
represents the leading coefficient ofg
.It is important to note that in the context of the
prem
method, multivariate polynomials in a ring, such asR[x,y,z]
, are treated as univariate polynomials with coefficients that are polynomials, such asR[x,y][z]
. When dividingf
byg
with respect to the variablez
, the pseudo-quotientq
and pseudo-remainderr
satisfym*f = g*q + r
, wheredeg(r, z) < deg(g, z)
andm = LC(g, z)^(deg(f, z) - deg(g, z) + 1)
.In this function, the pseudo-remainder
r
can be obtained using theprem
method, the pseudo-quotientq
can be obtained using thepquo
method, and the functionpdiv
itself returns a tuple(q, r)
.- Parameters:
g :
PolyElement
The polynomial to divide
self
by.x : generator or generator index, optional
The main variable of the polynomials and default is first generator.
- Returns:
-
The pseudo-division polynomial (tuple of
q
andr
). - Raises:
ZeroDivisionError : If
g
is the zero polynomial.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x, y = ring("x, y", ZZ)
>>> f = x**2 + x*y >>> g = 2*x + 2 >>> f.pdiv(g) # first generator is chosen by default if it is not given (2*x + 2*y - 2, -4*y + 4) >>> f.div(g) # shows the difference between pdiv and div (0, x**2 + x*y) >>> f.pdiv(g, y) # generator is given (2*x**3 + 2*x**2*y + 6*x**2 + 2*x*y + 8*x + 4, 0) >>> f.pdiv(g, 1) # generator index is given (2*x**3 + 2*x**2*y + 6*x**2 + 2*x*y + 8*x + 4, 0)
- pexquo(g, x=None)[source]¶
Polynomial exact pseudo-quotient in multivariate polynomial ring.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ)
>>> f = x**2 + x*y >>> g = 2*x + 2*y >>> h = 2*x + 2 >>> f.pexquo(g) 2*x >>> f.exquo(g) # shows the differnce between pexquo and exquo Traceback (most recent call last): ... ExactQuotientFailed: 2*x + 2*y does not divide x**2 + x*y >>> f.pexquo(h) Traceback (most recent call last): ... ExactQuotientFailed: 2*x + 2 does not divide x**2 + x*y
See also
- pquo(g, x=None)[source]¶
Polynomial pseudo-quotient in multivariate polynomial ring.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ)
>>> f = x**2 + x*y >>> g = 2*x + 2*y >>> h = 2*x + 2 >>> f.pquo(g) 2*x >>> f.quo(g) # shows the difference between pquo and quo 0 >>> f.pquo(h) 2*x + 2*y - 2 >>> f.quo(h) # shows the difference between pquo and quo 0
See also
- prem(g, x=None)[source]¶
Pseudo-remainder of the polynomial
self
with respect tog
.The pseudo-quotient
q
and pseudo-remainderr
with respect toz
when dividingf
byg
satisfym*f = g*q + r
, wheredeg(r,z) < deg(g,z)
andm = LC(g,z)**(deg(f,z) - deg(g,z)+1)
.See
pdiv()
for explanation of pseudo-division.- Parameters:
g :
PolyElement
The polynomial to divide
self
by.x : generator or generator index, optional
The main variable of the polynomials and default is first generator.
- Returns:
-
The pseudo-remainder polynomial.
- Raises:
ZeroDivisionError : If
g
is the zero polynomial.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x, y = ring("x, y", ZZ)
>>> f = x**2 + x*y >>> g = 2*x + 2 >>> f.prem(g) # first generator is chosen by default if it is not given -4*y + 4 >>> f.rem(g) # shows the differnce between prem and rem x**2 + x*y >>> f.prem(g, y) # generator is given 0 >>> f.prem(g, 1) # generator index is given 0
See also
- square()[source]¶
square of a polynomial
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ
>>> _, x, y = ring('x, y', ZZ) >>> p = x + y**2 >>> p.square() x**2 + 2*x*y**2 + y**4
- subresultants(g, x=None)[source]¶
Computes the subresultant PRS of two polynomials
self
andg
.- Parameters:
g :
PolyElement
The second polynomial.
x : generator or generator index
The variable with respect to which the subresultant sequence is computed.
- Returns:
R : list
Returns a list polynomials representing the subresultant PRS.
Examples
>>> from sympy.polys import ring, ZZ >>> R, x, y = ring("x, y", ZZ)
>>> f = x**2*y + x*y >>> g = x + y >>> f.subresultants(g) # first generator is chosen by default if not given [x**2*y + x*y, x + y, y**3 - y**2] >>> f.subresultants(g, 0) # generator index is given [x**2*y + x*y, x + y, y**3 - y**2] >>> f.subresultants(g, y) # generator is given [x**2*y + x*y, x + y, x**3 + x**2]
- symmetrize()[source]¶
Rewrite self in terms of elementary symmetric polynomials.
- Returns:
Triple
(p, r, m)
p
is aPolyElement
that represents our attempt to express self as a function of elementary symmetric polynomials. Each variable inp
stands for one of the elementary symmetric polynomials. The correspondence is given bym
.r
is the remainder.m
is a list of pairs, giving the mapping from variables inp
to elementary symmetric polynomials.The triple satisfies the equation
p.compose(m) + r == self
. If the remainderr
is zero, self is symmetric. If it is nonzero, we were not able to represent self as symmetric.
Explanation
If this
PolyElement
belongs to a ring of \(n\) variables, we can try to write it as a function of the elementary symmetric polynomials on \(n\) variables. We compute a symmetric part, and a remainder for any part we were not able to symmetrize.Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ >>> R, x, y = ring("x,y", ZZ)
>>> f = x**2 + y**2 >>> f.symmetrize() (x**2 - 2*y, 0, [(x, x + y), (y, x*y)])
>>> f = x**2 - y**2 >>> f.symmetrize() (x**2 - 2*y, -2*y**2, [(x, x + y), (y, x*y)])
See also
References
[R791]Lauer, E. Algorithms for symmetrical polynomials, Proc. 1976 ACM Symp. on Symbolic and Algebraic Computing, NY 242-247. https://dl.acm.org/doi/pdf/10.1145/800205.806342
- tail_degree(x=None)[source]¶
The tail degree in
x
or the main variable.Note that the degree of 0 is negative infinity (
float('-inf')
)
- tail_degrees()[source]¶
A tuple containing tail degrees in all variables.
Note that the degree of 0 is negative infinity (
float('-inf')
)
- terms(order=None)[source]¶
Ordered list of polynomial terms.
- Parameters:
order :
MonomialOrder
or coercible, optional
Examples
>>> from sympy.polys.rings import ring >>> from sympy.polys.domains import ZZ >>> from sympy.polys.orderings import lex, grlex
>>> _, x, y = ring("x, y", ZZ, lex) >>> f = x*y**7 + 2*x**2*y**3
>>> f.terms() [((2, 3), 2), ((1, 7), 1)] >>> f.terms(grlex) [((1, 7), 1), ((2, 3), 2)]
Sparse rational functions¶
Sparse polynomials are represented as dictionaries.
- sympy.polys.fields.field(symbols, domain, order=LexOrder())[source]¶
Construct new rational function field returning (field, x1, …, xn).
- sympy.polys.fields.xfield(symbols, domain, order=LexOrder())[source]¶
Construct new rational function field returning (field, (x1, …, xn)).
- sympy.polys.fields.vfield(symbols, domain, order=LexOrder())[source]¶
Construct new rational function field and inject generators into global namespace.
- sympy.polys.fields.sfield(exprs, *symbols, **options)[source]¶
Construct a field deriving generators and domain from options and input expressions.
- Parameters:
exprs : py:class:\(~.Expr\) or sequence of
Expr
(sympifiable)symbols : sequence of
Symbol
/Expr
options : keyword arguments understood by
Options
Examples
>>> from sympy import exp, log, symbols, sfield
>>> x = symbols("x") >>> K, f = sfield((x*log(x) + 4*x**2)*exp(1/x + log(x)/3)/x**2) >>> K Rational function field in x, exp(1/x), log(x), x**(1/3) over ZZ with lex order >>> f (4*x**2*(exp(1/x)) + x*(exp(1/x))*(log(x)))/((x**(1/3))**5)
- class sympy.polys.fields.FracField(symbols, domain, order=LexOrder())[source]¶
Multivariate distributed rational function field.
Dense polynomials¶
- class sympy.polys.polyclasses.DMP(rep, dom, lev=None)[source]¶
Dense Multivariate Polynomials over \(K\).
- count_complex_roots(inf=None, sup=None)[source]¶
Return the number of complex roots of
f
in[inf, sup]
.
- exclude()[source]¶
Remove useless generators from
f
.Returns the removed generators and the new excluded
f
.Examples
>>> from sympy.polys.polyclasses import DMP >>> from sympy.polys.domains import ZZ
>>> DMP([[[ZZ(1)]], [[ZZ(1)], [ZZ(2)]]], ZZ).exclude() ([2], DMP_Python([[1], [1, 2]], ZZ))
- classmethod from_list(rep, lev, dom)[source]¶
Create an instance of
cls
given a list of native coefficients.
- classmethod from_sympy_list(rep, lev, dom)[source]¶
Create an instance of
cls
given a list of SymPy coefficients.
- intervals(
- all=False,
- eps=None,
- inf=None,
- sup=None,
- fast=False,
- sqf=False,
Compute isolating intervals for roots of
f
.
- property is_cyclotomic¶
Returns
True
iff
is a cyclotomic polynomial.
- property is_ground¶
Returns
True
iff
is an element of the ground domain.
- property is_homogeneous¶
Returns
True
iff
is a homogeneous polynomial.
- property is_irreducible¶
Returns
True
iff
has no factors over its domain.
- property is_linear¶
Returns
True
iff
is linear in all its variables.
- property is_monic¶
Returns
True
if the leading coefficient off
is one.
- property is_monomial¶
Returns
True
iff
is zero or has only one term.
- property is_one¶
Returns
True
iff
is a unit polynomial.
- property is_primitive¶
Returns
True
if the GCD of the coefficients off
is one.
- property is_quadratic¶
Returns
True
iff
is quadratic in all its variables.
- property is_sqf¶
Returns
True
iff
is a square-free polynomial.
- property is_zero¶
Returns
True
iff
is a zero polynomial.
- permute(P)[source]¶
Returns a polynomial in \(K[x_{P(1)}, ..., x_{P(n)}]\).
Examples
>>> from sympy.polys.polyclasses import DMP >>> from sympy.polys.domains import ZZ
>>> DMP([[[ZZ(2)], [ZZ(1), ZZ(0)]], [[]]], ZZ).permute([1, 0, 2]) DMP_Python([[[2], []], [[1, 0], []]], ZZ)
>>> DMP([[[ZZ(2)], [ZZ(1), ZZ(0)]], [[]]], ZZ).permute([1, 2, 0]) DMP_Python([[[1], []], [[2, 0], []]], ZZ)
- refine_root(
- s,
- t,
- eps=None,
- steps=None,
- fast=False,
Refine an isolating interval to the given precision.
eps
should be a rational number.
- property rep¶
Get the representation of
f
.
- to_best()[source]¶
Convert to DUP_Flint if possible.
This method should be used when the domain or level is changed and it potentially becomes possible to convert from DMP_Python to DUP_Flint.
- class sympy.polys.polyclasses.DMF(rep, dom, lev=None)[source]¶
Dense Multivariate Fractions over \(K\).
- property is_one¶
Returns
True
iff
is a unit fraction.
- property is_zero¶
Returns
True
iff
is a zero fraction.
- class sympy.polys.polyclasses.ANP(rep, mod, dom)[source]¶
Dense Algebraic Number Polynomials over a field.
- property is_ground¶
Returns
True
iff
is an element of the ground domain.
- property is_one¶
Returns
True
iff
is a unit algebraic number.
- property is_zero¶
Returns
True
iff
is a zero algebraic number.