SymPy-1-13-中文文档-二十四-

SymPy 1.13 中文文档(二十四)

原文:docs.sympy.org/latest/index.html

多项式操作

原始文档:docs.sympy.org/latest/modules/polys/index.html

多项式计算是计算机代数的核心,拥有快速且健壮的多项式操作模块是构建强大的符号操作系统的关键。SymPy 有一个专门的模块 sympy.polys 用于在各种系数域上进行多项式代数的计算。

实现了大量方法,从像多项式除法这样的简单工具,到包括 Gröbner 基和代数数域中的多变量因式分解等高级概念。

内容

  • 模块的基本功能

  • Wester 文章中的例子

  • 多项式操作模块的参考文档

  • AGCA - 代数几何与交换代数模块

  • 介绍 poly 模块的领域

  • Poly Domains 的参考文档

  • 多项式操作模块的内部

  • 使用多项式进行系列操作

  • 文献资料

  • 多项式求解器

  • 介绍 poly 模块的 domainmatrix

  • 数域

模块的基本功能

原文链接:docs.sympy.org/latest/modules/polys/basics.html

介绍

本教程试图概述 SymPy 中关于多项式的功能。所有代码示例假设:

>>> from sympy import *
>>> x, y, z = symbols('x,y,z')
>>> init_printing(use_unicode=False) 

基本概念

多项式

给定一个符号族((x_i)),或其他适当的对象,包括数字,由它们通过重复加法、减法和乘法导出的表达式称为生成器中的多项式表达式(x_i)。

根据分配律,在加法和减法之前进行乘法是可能的。因此获得的生成器的乘积称为单项式。它们通常以形式(x_1{\nu_1}x_2\cdots x_n{\nu_n})书写,其中指数(\nu_i)为非负整数。通常便于简写为(x\nu),其中(x = (x_1, x_2, \ldots, x_n))表示生成器的族,(\nu = (\nu_1, \nu_2, \ldots, \nu_n))表示指数的族。

当合并所有具有相同指数的单项式时,多项式表达式变为乘积的和(c_\nu x^\nu),称为多项式的,其中系数(c_\nu)为整数。如果某些(x_i)是明确的数字,则它们被合并到系数中,而不视为生成器。这些系数通常是有理数、实数或复数。一些符号数,例如pi,可以是系数或生成器。

由不同单项式之和构成的多项式表达式可以唯一由其系数族((c_\nu))确定。这样的表达式通常被称为多项式,尽管更准确地说,该名称是指一旦生成器给定后的系数族。SymPy 默认将多项式实现为以单项式为键、系数为值的字典。另一种实现方式是系数的嵌套列表。

在生成器(x_i)中所有整数系数的多项式集合是一个,即其元素的和、差和积再次是相同生成器的多项式。这个环记作(\mathbb{Z}[x_1, x_2, \ldots, x_n]),或(\mathbb{Z}[(x_i)]),并称为具有整数系数的生成器(x_i)的多项式环。

更一般地,多项式的系数可以是任何可交换环(A)的元素,相应的多项式环通常记作(A[x_1, x_2, \dots, x_n])。环(A)也可以是一个多项式环。在 SymPy 中,系数环称为多项式环的domain,可以作为关键字参数给出。默认情况下,它由多项式参数的系数确定。

多项式表达式可以通过方法sympy.core.expr.Expr.as_poly转换为多项式:

>>> e = (x + y)*(y - 2*z)
>>> e.as_poly()
Poly(x*y - 2*x*z + y**2 - 2*y*z, x, y, z, domain='ZZ') 

如果多项式表达式包含非整数的数,则它们被视为系数,并相应地扩展系数环。特别是,除以整数导致有理系数:

>>> e = (3*x/2 + y)*(z - 1)
>>> e.as_poly()
Poly(3/2*x*z - 3/2*x + y*z - y, x, y, z, domain='QQ') 

符号数被认为是生成器,除非明确排除,否则它们被附加到系数环中:

>>> e = (x + 2*pi)*y
>>> e.as_poly()
Poly(x*y + 2*y*pi, x, y, pi, domain='ZZ')
>>> e.as_poly(x, y)
Poly(x*y + 2*pi*y, x, y, domain='ZZ[pi]') 

或者,可以通过关键字参数指定系数域:

>>> e = (x + 2*pi)*y
>>> e.as_poly(domain=ZZ[pi])
Poly(x*y + 2*pi*y, x, y, domain='ZZ[pi]') 

注意,环 (\mathbb{Z}[\pi][x, y]),即以 (\mathbb{Z}[\pi]) 为系数的 (x) 和 (y) 的多项式环,在数学上等同于 (\mathbb{Z}[\pi, x, y]),只是它们的实现有所不同。

如果表达式中包含生成器的函数,除了它们的正整数幂之外,这些函数被解释为新的生成器:

>>> e = x*sin(y) - y
>>> e.as_poly()
Poly(x*(sin(y)) - y, x, y, sin(y), domain='ZZ') 

由于 (y) 和 (\sin(y)) 在代数上是独立的,它们可以作为多项式中的生成器出现。然而,多项式表达式不得包含生成器的负幂

>>> e = x - 1/x
>>> e.as_poly()
Poly(x - (1/x), x, 1/x, domain='ZZ') 

重要的是要意识到生成器 (x) 和 (1/x = x^{-1}) 被视为代数独立的变量。特别地,它们的乘积不等于 1。因此应避免分母中的生成器,即使它们在当前实现中没有错误。这种行为是不希望的,可能在将来会改变。类似的问题也会出现在生成器的有理幂中。例如,(x) 和 (\sqrt x = x^{1/2}) 并不被识别为代数相关。

如果表达式中含有代数数,则可以通过设置关键字extension将它们附加到系数环中:

>>> e = x + sqrt(2)
>>> e.as_poly()
Poly(x + (sqrt(2)), x, sqrt(2), domain='ZZ')
>>> e.as_poly(extension=True)
Poly(x + sqrt(2), x, domain='QQ<sqrt(2)>') 

使用默认设置extension=False,(x) 和 (\sqrt 2) 都被错误地视为代数独立的变量。在扩展域 (\mathbb{Q}(\sqrt 2)) 中,平方根正确地被视为代数数。尽管当前的实现没有强制要求,但涉及代数数时建议设置extension=True

可除性

第四个有理运算,即除法或倒数乘法,通常在环中不可能。如果 (a) 和 (b) 是环 (A) 的两个元素,则可能存在第三个元素 (q) 使得 (a = bq)。事实上,可能存在几个这样的元素。

如果还有 (a = bq'),其中 (q') 在 (A) 中,则 (b(q - q') = 0)。因此要么 (b) 要么 (q - q') 是零,或者它们都是零因子,乘积为零的非零元素。

整环

没有零因子的交换环称为整环。大多数常见的环,如整数环、域以及整环上的多项式环,都是整环。

现在假设(A)是一个整环,并考虑其非零元素构成的集合(P),它在乘法下封闭。如果(a)和(b)属于(P),并且存在(P)中的元素(q)使得(a = bq),那么(q)是唯一的,并称为(a)除以(b)的,记为(a/b)。此外,有如下关系:

  • (a)是(b)的倍数

  • (b)是(a)的除数

  • (a)是(b)的倍数

  • (b)是(a)的因子

元素(a)属于(P),如果且仅如果它在(A)中是可逆的,即存在逆元(a^{-1} = 1/a)。这样的元素称为单位。整数环的单位包括(1)和(-1)。在域上的多项式环中,可逆元素为非零常数多项式。

如果(P)中的两个元素(a)和(b)相互整除,则商(a/b)可逆,其逆元为(b/a),或等价地,(b = ua),其中(u)是单位。这样的元素称为关联同伴。整数(n)的同伴是(n)和(-n)。在域上的多项式环中,多项式的同伴是它的常数倍数。

每个(P)中的元素都可被它的关联元素和单位整除。如果一个元素是不可约的,那么它没有其他除数且不是单位。整数环中的不可约元素包括素数(p)及其负数(-p)。在域中,每个非零元素都是可逆的,因此没有不可约元素。

阶乘整环

在整数环中,每个非零元素都可以表示为不可约元素的乘积,可选地加上单位(\pm 1)。此外,任意两个这样的乘积具有相同数量的不可约因子,它们在适当顺序下相互关联。具有此特性的整环称为阶乘唯一分解整环。除整数环外,所有域上的多项式环都是阶乘整环,更一般地说,所有阶乘整环上的多项式环也是阶乘整环。域因其只有单位而显然是阶乘的。阶乘整环中的不可约元素通常称为素数

整数族仅有有限个公共因数,并且其中最大的因数可整除它们中的所有元素。更一般地,给定整环中的非零元素族((a_i)),元素(d)称为该族的最大公因数(简称gcd),如果它是所有公因数的倍数。最大公因数一般并非唯一;所有它的同伴都具有相同的性质。如果没有歧义,用(d = \gcd(a_1,\ldots,a_n))表示。一个族的最小公倍数(简称lcm)(m)定义为所有公倍数中的最小数,记为(m = \operatorname{lcm}(a_1,\dots,a_n))。

在因子环中,最大公约数总是存在的。至少在原理上,可以通过将每个成员因式分解为素数幂的乘积和可选单位,并对每个素数取出现在因式分解中的最小幂来找到它们。这些素数幂的乘积就是最大公约数。最小公倍数可以从相同的因式分解中获得,即为每个素数取最大幂的乘积。

欧几里德整环

一个实用的计算最大公约数的算法可以在欧几里德整环中实现。它们是可以赋予域内每个非零元素一个非负整数的整环,并具有以下属性:

如果 (a) 和 (b) 非零,则存在 (q) 和 (r) 满足除法标识

(a = qb + r)

这样要么 (r = 0) 要么 (w(r) < w(b))。

整数环和所有域上的一元多项式环是具有 (w(a) = |a|) 或 (w(a) = \deg(a)) 的欧几里德整环。

整数的除法标识在 Python 中作为内置函数divmod实现,也可以应用于 SymPy 整数:

>>> divmod(Integer(53), Integer(7))
(7, 4) 

对于多项式,SymPy 中的除法标识由函数div()给出:

>>> f = 5*x**2 + 10*x + 3
>>> g = 2*x + 2

>>> q, r = div(f, g, domain='QQ')
>>> q
5*x   5
--- + -
 2    2
>>> r
-2
>>> (q*g + r).expand()
 2
5*x  + 10*x + 3 

可以使用除法标识来确定欧几里德整环中元素的可除性。如果在除法标识中 (r = 0),则 (a) 可以被 (b) 整除。反之,如果 (a = cb) 对于某些元素 (c),则 ((c - q)b = r)。由此可知,如果 (w) 具有附加属性,则 (c = q) 并且 (r = 0)。

如果 (a) 和 (b) 非零,则 (w(ab) \ge w(b))。

这些给定的函数满足这一点。(并且总是可以通过重新定义 (w(a)) 为 (w(xa)) 的值中的最小值来满足。)

除法标识的主要应用是通过欧几里德算法高效地计算欧几里德整环中两个元素的最大公约数。它适用于多个元素的最大公约数可以通过迭代获得。

计算 SymPy 整数最大公约数的函数目前是igcd()

>>> igcd(2, 4)
2
>>> igcd(5, 10, 15)
5 

对于域上的一元多项式,该函数通常被称为gcd(),并且返回的多项式是首一的:

>>> f = 4*x**2 - 1
>>> g = 8*x**3 + 1
>>> gcd(f, g, domain=QQ)
x + 1/2 

多项式的可除性

一元多项式环 (A = \mathbb{Z}[x]) 不是欧几里德但仍然是因子的。要看到这一点,请考虑(A)中的可整除性。

设(f)和(g)是(A)中的两个非零多项式。如果(f)在(A)中被(g)整除,则在有理系数多项式环(B = \mathbb{Q}[x])中也是如此。由于(B)是欧几里得环,这可以通过除法恒等式确定。

假设反过来,对于某些多项式(h)在(B)中,(f = gh)。那么(f)在(A)中被(g)整除当且仅当(h)的系数是整数。要确定这是否成立,需要考虑系数的可整除性。

对于(A)中的多项式(f),设(c)是其系数的最大公因子。那么(f)在(A)中被常数多项式(c)整除,且商(f/c = p)是其系数是没有单位以外的整数的多项式。这样的多项式称为原始。有理系数的多项式也可以写为(f = cp),其中(c)是有理数,(p)是原始多项式。常数(c)称为(f)的内容,(p)是其原始部分。这些组成部分可以通过方法sympy.core.expr.Expr.as_content_primitive找到:

>>> f = 6*x**2 - 3*x + 9
>>> c, p = f.as_content_primitive()
>>> c, p
 2
(3, 2*x  - x + 3)
>>> f = x**2/3 - x/2 + 1
>>> c, p = f.as_content_primitive()
>>> c, p
 2
(1/6, 2*x  - 3*x + 6) 

设(f)和(f')是具有内容(c)和(c')以及原始部分(p)和(p')的多项式。那么(ff' = (cc')(pp')),其中乘积(pp')由Gauss 引理是原始的。由此得出

多项式乘积的内容是它们内容的乘积,而乘积的原始部分是原始部分的乘积。

回到环(\mathbb{Z}[x])中的整除性,假设(f)和(g)是具有整数系数的两个多项式,使得在(\mathbb{Q}[x])中的除法恒等式产生多项式(h)的等式(f = gh)。则(f)的内容等于(g)的内容乘以(h)的内容。由于(h)具有整数系数当且仅当其内容是整数,我们得到以下判据:

(f)在环(\mathbb{Z}[x])中被(g)整除当且仅当

  1. (f)在(\mathbb{Q}[x])中被(g)整除,并且
  2. (f)的内容在(\mathbb{Z})中能被(g)的内容整除。

如果(f = cp)在(\mathbb{Z}[x])中是不可约的,则(c)或(p)必须是单位。如果(p)不是单位,则它在(\mathbb{Q}[x])中也必须是不可约的。因为如果它是两个多项式的乘积,它也是它们的原始部分的乘积,其中一个必须是单位。因此在(\mathbb{Z}[x])中有两种不可约元素:

  1. (\mathbb{Z})的素数,以及

  2. 在(\mathbb{Q}[x])中是不可约的原始多项式。

由此可知,(\mathbb{Z}[x]) 中的每个多项式都是不可约元素的乘积。只需分别对其内容和原始部分进行因式分解即可。这些乘积基本上是唯一的;因此 (\mathbb{Z}[x]) 也是因子的。

另一个重要的结论是,在 (\mathbb{Z}[x]) 中两个多项式的最大公约数可以通过将它们的内容和原始部分分别应用于欧几里得域 (\mathbb{Z}) 和 (\mathbb{Q}[x]) 中的欧几里得算法来有效地找到。这也在 SymPy 中实现了:

>>> f = 4*x**2 - 1
>>> g = 8*x**3 + 1
>>> gcd(f, g)
2*x + 1
>>> gcd(6*f, 3*g)
6*x + 3 

基本功能

这些函数提供了处理 SymPy 表达式形式的多项式的不同算法,如符号、求和等。

除法

函数 div() 提供了带余除法。也就是说,对于多项式 fg,它计算出 qr,使得 (f = g \cdot q + r) 且 (\deg(r) < \deg(q))。对于系数在一个域中(例如有理数)的一元多项式,这种方式唯一地定义了 qr

>>> f = 5*x**2 + 10*x + 3
>>> g = 2*x + 2

>>> q, r = div(f, g, domain='QQ')
>>> q
5*x   5
--- + -
 2    2
>>> r
-2
>>> (q*g + r).expand()
 2
5*x  + 10*x + 3 

正如你所见,q 有一个非整数系数。如果你只想在整数系数的多项式环中进行除法,你可以指定一个额外的参数:

>>> q, r = div(f, g, domain='ZZ')
>>> q
0
>>> r
 2
5*x  + 10*x + 3 

但要注意,这个环不再是欧几里得环,余数的次数不一定比 f 的次数小。因为 2 不能整除 5,所以 (2 x) 不能整除 (5 x²),即使次数较小。但:

>>> g = 5*x + 1

>>> q, r = div(f, g, domain='ZZ')
>>> q
x
>>> r
9*x + 3
>>> (q*g + r).expand()
 2
5*x  + 10*x + 3 

这也适用于多变量多项式:

>>> f = x*y + y*z
>>> g = 3*x + 3*z

>>> q, r = div(f, g, domain='QQ')
>>> q
y
-
3
>>> r
0 

在最后的示例中,所有三个变量 xyz 都被假定为多项式的变量。但如果你有一些无关的常数作为系数,你可以显式地指定这些变量:

>>> a, b, c = symbols('a,b,c')
>>> f = a*x**2 + b*x + c
>>> g = 3*x + 2
>>> q, r = div(f, g, domain='QQ')
>>> q
a*x   2*a   b
--- - --- + -
 3     9    3

>>> r
4*a   2*b
--- - --- + c
 9     3 

最大公约数和最小公倍数

除法时,还涉及最大公约数和最小公倍数的计算。

当多项式具有整数系数时,考虑到内容的最大公约数:

>>> f = (12*x + 12)*x
>>> g = 16*x**2
>>> gcd(f, g)
4*x 

但是如果多项式具有有理系数,则返回的多项式是首一的:

>>> f = 3*x**2/2
>>> g = 9*x/4
>>> gcd(f, g)
x 

它也适用于多变量。在这种情况下,默认情况下,变量按字母顺序排序,这会影响到主导系数:

>>> f = x*y/2 + y**2
>>> g = 3*x + 6*y

>>> gcd(f, g)
x + 2*y 

最小公倍数与最大公约数相关联,可以用其中一个来计算另一个:

>>> f = x*y**2 + x**2*y
>>> g = x**2*y**2
>>> gcd(f, g)
x*y
>>> lcm(f, g)
 3  2    2  3
x *y  + x *y
>>> (f*g).expand()
 4  3    3  4
x *y  + x *y
>>> (gcd(f, g, x, y)*lcm(f, g, x, y)).expand()
 4  3    3  4
x *y  + x *y 

无平方因式分解

单变量多项式的无平方因式分解是所有一次、二次等因子的乘积(不一定是不可约的):

>>> f = 2*x**2 + 5*x**3 + 4*x**4 + x**5

>>> sqf_list(f)
 2
(1, [(x + 2, 1), (x  + x, 2)])

>>> sqf(f)
 2
 / 2    \
(x + 2)*\x  + x/ 

因式分解

这个函数提供了有理系数的一元和多元多项式的因式分解:

>>> factor(x**4/2 + 5*x**3/12 - x**2/3)
 2
x *(2*x - 1)*(3*x + 4)
----------------------
 12

>>> factor(x**2 + 4*x*y + 4*y**2)
 2
(x + 2*y) 

Groebner 基

Buchberger 算法已经实现,支持各种单项式排序:

>>> groebner([x**2 + 1, y**4*x + x**3], x, y, order='lex')
 /[ 2       4    ]                            \
GroebnerBasis\[x  + 1, y  - 1], x, y, domain=ZZ, order=lex/

>>> groebner([x**2 + 1, y**4*x + x**3, x*y*z**3], x, y, z, order='grevlex')
 /[ 4       3   2    ]                                   \
GroebnerBasis\[y  - 1, z , x  + 1], x, y, z, domain=ZZ, order=grevlex/ 

解方程

我们有(不完整的)方法来找到多项式的复数甚至符号根,并解一些多项式方程组:

>>> from sympy import roots, solve_poly_system

>>> solve(x**3 + 2*x + 3, x)
 ____          ____
 1   \/ 11 *I  1   \/ 11 *I
[-1, - - --------, - + --------]
 2      2      2      2

>>> p = Symbol('p')
>>> q = Symbol('q')

>>> solve(x**2 + p*x + q, x)
 __________           __________
 /  2                 /  2
 p   \/  p  - 4*q     p   \/  p  - 4*q
[- - - -------------, - - + -------------]
 2         2          2         2

>>> solve_poly_system([y - x, x - 5], x, y)
[(5, 5)]

>>> solve_poly_system([y**2 - x**3 + 1, y*x], x, y)
 ___                 ___
 1   \/ 3 *I         1   \/ 3 *I
[(0, -I), (0, I), (1, 0), (- - - -------, 0), (- - + -------, 0)]
 2      2            2      2 

来自 Wester 文章的示例

原文:docs.sympy.org/latest/modules/polys/wester.html

引言

在本教程中,我们提供了来自 Wester 文章的示例,涉及比较和批评多个计算机代数系统的数学能力(参见 [Wester1999])。所有示例与多项式和代数计算相关,并且针对所有示例都添加了 SymPy 特定的注释。

示例

本教程中的所有示例都是可计算的,因此可以直接复制粘贴到 Python shell 中,并做一些有用的事情。所有计算都是在以下设置下完成的:

>>> from sympy import *

>>> init_printing(use_unicode=True)

>>> var('x,y,z,s,c')
(x, y, z, s, c) 

简单的单变量多项式因式分解

要获得多项式的因式分解,请使用 factor() 函数。默认情况下,factor() 返回未评估的形式的结果,因此输入多项式的内容保持未展开,如以下示例所示:

>>> factor(6*x - 10)
2⋅(3⋅x - 5) 

要以更系统的方式实现相同的效果,请使用 primitive() 函数,该函数返回输入多项式的内容和原始部分:

>>> primitive(6*x - 10)
(2, 3⋅x - 5) 

注意

只能在环上计算多项式的内容和原始部分。要在域上简化多项式的系数,请使用 monic()

单变量 GCD、结果和因式分解

考虑整数环上的单变量多项式 f, gh

>>> f = 64*x**34 - 21*x**47 - 126*x**8 - 46*x**5 - 16*x**60 - 81
>>> g = 72*x**60 - 25*x**25 - 19*x**23 - 22*x**39 - 83*x**52 + 54*x**10 + 81
>>> h = 34*x**19 - 25*x**16 + 70*x**7 + 20*x**3 - 91*x - 86 

我们可以使用 gcd() 函数计算两个多项式的最大公约数(GCD):

>>> gcd(f, g)
1 

我们看到 fg 没有共同的因子。然而,f*hg*h 显然有一个因子 h

>>> gcd(expand(f*h), expand(g*h)) - h
0 

可以使用单变量多项式的结果来验证相同的内容:

>>> resultant(expand(f*h), expand(g*h))
0 

例如,在此情况下,可以对整数上的度数为 120 的大型单变量多项式进行因式分解:

>>> factor(expand(f*g))
 ⎛    60       47       34        8       5     ⎞ ⎛    60       52     39       25       23       10     ⎞
-⎝16⋅x   + 21⋅x   - 64⋅x   + 126⋅x  + 46⋅x  + 81⎠⋅⎝72⋅x   - 83⋅x - 22⋅x   - 25⋅x   - 19⋅x   + 54⋅x   + 81⎠ 

多变量 GCD 和因式分解

在单变量情况下可以做的事情,也可以用于多变量多项式。考虑以下在 (\mathbb{Z}[x,y,z]) 上的多项式 f, gh

>>> f = 24*x*y**19*z**8 - 47*x**17*y**5*z**8 + 6*x**15*y**9*z**2 - 3*x**22 + 5
>>> g = 34*x**5*y**8*z**13 + 20*x**7*y**7*z**7 + 12*x**9*y**16*z**4 + 80*y**14*z
>>> h = 11*x**12*y**7*z**13 - 23*x**2*y**8*z**10 + 47*x**17*y**5*z**8 

与之前一样,我们可以验证 fg 没有共同的因子:

>>> gcd(f, g)
1 

然而,f*hg*h 显然有一个因子 h

>>> gcd(expand(f*h), expand(g*h)) - h
0 

也可以对大型多项式进行多变量因式分解:

>>> factor(expand(f*g))
 7   ⎛   9  9  3       7  6       5    12       7⎞ ⎛   22       17  5  8      15  9  2         19  8    ⎞
-2⋅y ⋅z⋅⎝6⋅x ⋅y ⋅z  + 10⋅x ⋅z  + 17⋅x ⋅y⋅z   + 40⋅y ⎠⋅⎝3⋅x   + 47⋅x  ⋅y ⋅z  - 6⋅x  ⋅y ⋅z  - 24⋅x⋅y  ⋅z  - 5⎠ 

支持指数中的符号

sympy.polys 提供的多项式操作函数大多数用于整数指数。然而,使用符号指数进行计算也是完全有效的,例如:

>>> n = var('n')
>>> gcd(x**n - x**(2*n), x**n)
 n
x

Results may depend on powers being expanded (which will depend on
assumptions of the base):

>>> gcd(x**(n + 4), x**(n + 1) + 3*x**n)
1
>>> x = var('x', positive=True)
>>> gcd(x**(n + 4), x**(n + 1) + 3*x**n)
 n
x 

测试多项式是否有共同的零点

要测试两个多项式是否有共同的根,可以使用resultant()函数。理论表明,如果两个多项式有共同的零点,则它们的 resultant 为零。例如:

>>> x = var('x')
>>> resultant(3*x**4 + 3*x**3 + x**2 - x - 2, x**3 - 3*x**2 + x + 5)
0 

我们可以通过将多项式因式分解来可视化这个事实:

>>> factor(3*x**4 + 3*x**3 + x**2 - x - 2)
 ⎛   3        ⎞
(x + 1)⋅⎝3⋅x  + x - 2⎠

>>> factor(x**3 - 3*x**2 + x + 5)
 ⎛ 2          ⎞
(x + 1)⋅⎝x  - 4⋅x + 5⎠ 

在这两种情况下,我们得到的因子是 (x + 1),这告诉我们共同的根是 (x = -1)。

规范化简单的有理函数

要从有理函数的分子和分母中优雅地去除公因子,可以使用cancel()函数。例如:

>>> cancel((x**2 - 4)/(x**2 + 4*x + 4))
x - 2
─────
x + 2 

展开表达式然后因式分解

人们可以轻松地处理展开和因式分解形式的表达式。考虑一个展开形式的多项式 f。我们对它进行微分,然后将结果因式分解回来:

>>> f = expand((x + 1)**20)

>>> g = diff(f, x)

>>> factor(g)
 19
20⋅(x + 1) 

同样可以以因式分解的形式实现:

>>> diff((x + 1)**20, x)
 19
20⋅(x + 1) 

以旋轮多项式的形式进行因式分解

SymPy 可以非常高效地将形如 (x^n \pm 1) 的多项式分解为旋轮多项式的形式:

>>> factor(x**15 - 1)
 ⎛ 2        ⎞ ⎛ 4    3    2        ⎞ ⎛ 8    7    5    4    3       ⎞
(x - 1)⋅⎝x  + x + 1⎠⋅⎝x  + x  + x  + x + 1⎠⋅⎝x  - x  + x  - x  + x - x + 1⎠ 

最初的 Wester 的例子是 (x^{100} - 1),但为了便于阅读而被截断了。请注意,这对于 factor() 来说,并不是解分解 1000 次或更高次多项式的难题。

在高斯数上一元因式分解

考虑一个具有整数系数的一元多项式 f

>>> f = 4*x**4 + 8*x**3 + 77*x**2 + 18*x + 153 

我们想要在高斯数上对 f 进行因式分解。为此,我们使用 factor(),并将 gaussian 关键字设置为 True

>>> factor(f, gaussian=True)
 ⎛    3⋅ⅈ⎞ ⎛    3⋅ⅈ⎞
4⋅⎜x - ───⎟⋅⎜x + ───⎟⋅(x + 1 - 4⋅ⅈ)⋅(x + 1 + 4⋅ⅈ)
 ⎝     2 ⎠ ⎝     2 ⎠ 

结果是我们得到了 f 的分裂因式分解,其中每个因子都是首一的(在 SymPy 中计算域中的一般规则)。gaussian 关键字有助于提高代码可读性,不过也可以使用更通用的语法得到相同的结果:

>>> factor(f, extension=I)
 ⎛    3⋅ⅈ⎞ ⎛    3⋅ⅈ⎞
4⋅⎜x - ───⎟⋅⎜x + ───⎟⋅(x + 1 - 4⋅ⅈ)⋅(x + 1 + 4⋅ⅈ)
 ⎝     2 ⎠ ⎝     2 ⎠ 

使用自动域扩展进行计算

考虑两个一元多项式 fg

>>> f = x**3 + (sqrt(2) - 2)*x**2 - (2*sqrt(2) + 3)*x - 3*sqrt(2)
>>> g = x**2 - 2 

我们希望简化有理函数 f/g 的分子和分母的次数。为此,我们使用 cancel() 函数:

>>> cancel(f/g)
 3      2       2
x  - 2⋅x  + √2⋅x  - 3⋅x - 2⋅√2⋅x - 3⋅√2
───────────────────────────────────────
 2
 x  - 2 

不幸的是,没有发生什么有趣的事情。这是因为默认情况下,SymPy 将 (\sqrt{2}) 视为生成器,从而获得了分子的双变量多项式。要使 cancel() 认识到 (\sqrt{2}) 的代数性质,需要使用 extension 关键字:

>>> cancel(f/g, extension=True)
 2
x  - 2⋅x - 3
────────────
 x - √2 

设置extension=True告诉cancel(),以找到f/g系数的最小代数数域。自动推断的域是(\mathbb{Q}(\sqrt{2}))。如果不想依赖自动推断,可以通过设置extension关键字与显式的代数数来获得相同的结果:

>>> cancel(f/g, extension=sqrt(2))
 2
x  - 2⋅x - 3
────────────
 x - √2 

在各种域上的单变量因式分解

考虑一个整系数的单变量多项式f

>>> f = x**4 - 3*x**2 + 1 

使用sympy.polys,我们可以在不同的域上获得f的因式分解,包括:

  • 有理数:

    >>> factor(f)
    ⎛ 2        ⎞ ⎛ 2        ⎞
    ⎝x  - x - 1⎠⋅⎝x  + x - 1⎠ 
    
  • 有限域:

    >>> factor(f, modulus=5)
     2        2
    (x - 2) ⋅(x + 2) 
    
  • 代数数:

    >>> alg = AlgebraicNumber((sqrt(5) - 1)/2, alias='alpha')
    
    >>> factor(f, extension=alg)
    (x - α)⋅(x + α)⋅(x - 1 - α)⋅(x + α + 1) 
    

将多项式分解为线性因子

当前 SymPy 可以将多项式因式分解为各种域上的不可约因子,这可能导致分裂因式分解(成线性因子)。然而,目前还没有系统的方法自动推断分裂域(代数数域)。在未来,将实现以下语法:

>>> factor(x**3 + x**2 - 7, split=True)
Traceback (most recent call last):
...
NotImplementedError: 'split' option is not implemented yet 

注意这与extension=True不同,因为后者仅告诉表达式解析应该如何进行,而不指定计算域。可以使用solve()函数模拟多个多项式类的split关键字。

在大有限域上的高级因式分解

考虑一个整系数的单变量多项式f

>>> f = x**11 + x + 1 

我们可以在大有限域(F_{65537})上对f进行因式分解:

>>> factor(f, modulus=65537)
⎛ 2        ⎞ ⎛ 9    8    6    5    3    2    ⎞
⎝x  + x + 1⎠⋅⎝x  - x  + x  - x  + x  - x  + 1⎠ 

然后将结果的因式分解展开回来:

>>> expand(_)
 11
x   + x + 1 

获得多项式f。这是通过对有限域上的对称多项式表示来完成的。使用非对称表示也可以做同样的事情:

>>> factor(f, modulus=65537, symmetric=False)
⎛ 2        ⎞ ⎛ 9          8    6          5    3          2    ⎞
⎝x  + x + 1⎠⋅⎝x  + 65536⋅x  + x  + 65536⋅x  + x  + 65536⋅x  + 1⎠ 

与对称表示一样,我们可以展开因式分解以获得输入多项式。然而,这次我们需要对展开多项式的系数模 65537 进行截断:

>>> trunc(expand(_), 65537)
 11
x   + x + 1 

作为多项式处理表达式

考虑一个多变量多项式f在(\mathbb{Z}[x,y,z])中:

>>> f = expand((x - 2*y**2 + 3*z**3)**20) 

我们希望计算f的因式分解。为此,我们通常使用factor,但需要注意的是,考虑的多项式已经处于展开形式,因此可以告诉因式分解例程跳过展开f

>>> factor(f, expand=False)
 20
⎛       2      3⎞
⎝x - 2⋅y  + 3⋅z ⎠ 

sympy.polys中,默认情况是展开所有作为多项式操作函数和Poly类参数给出的表达式。如果我们知道展开是不必要的,可以通过设置expand=False节省处理复杂输入的大量时间。当处理像以下表达式时,这可能非常重要:

>>> g = expand((sin(x) - 2*cos(y)**2 + 3*tan(z)**3)**20)

>>> factor(g, expand=False)
 20
⎛               2           3   ⎞
⎝-sin(x) + 2⋅cos (y) - 3⋅tan (z)⎠ 

计算减少的 Gröbner 基础

要为一组多项式计算简化的 Gröbner 基础,请使用 groebner() 函数。该函数接受各种单项式排序方式,例如:lexgrlexgrevlex,或者通过 order 关键字定义用户自定义排序。lex 排序是最有趣的,因为它具有消除属性,这意味着如果多项式方程系统向 groebner() 零维(有有限个解)时,基础的最后一个元素是一个一元多项式。考虑以下示例:

>>> f = expand((1 - c**2)**5 * (1 - s**2)**5 * (c**2 + s**2)**10)

>>> groebner([f, c**2 + s**2 - 1])
 ⎛⎡ 2    2       20      18       16       14      12    10⎤                           ⎞
GroebnerBasis⎝⎣c  + s  - 1, c   - 5⋅c   + 10⋅c   - 10⋅c   + 5⋅c   - c  ⎦, s, c, domain=ℤ, order=lex⎠ 

结果是一个普通的 Python 列表,因此我们可以轻松地将一个函数应用到它的所有元素上,例如我们可以因式分解这些元素:

>>> list(map(factor, _))
⎡ 2    2       10        5        5⎤
⎣c  + s  - 1, c  ⋅(c - 1) ⋅(c + 1) ⎦ 

从上面的内容中,我们可以轻松地找到多项式方程组的所有解。或者我们可以使用 solve() 以更系统的方式实现:

>>> solve([f, s**2 + c**2 - 1], c, s)
[(-1, 0), (0, -1), (0, 1), (1, 0)] 

多元素数上的因式分解

在各种域上使用多元多项式进行计算与一元情况一样简单。例如,考虑以下在 (\mathbb{Q}(\sqrt{-3})) 上的因式分解:

>>> factor(x**3 + y**3, extension=sqrt(-3))
 ⎛      ⎛  1   √3⋅ⅈ⎞⎞ ⎛      ⎛  1   √3⋅ⅈ⎞⎞
(x + y)⋅⎜x + y⋅⎜- ─ - ────⎟⎟⋅⎜x + y⋅⎜- ─ + ────⎟⎟
 ⎝      ⎝  2    2  ⎠⎠ ⎝      ⎝  2    2  ⎠⎠ 

注意

目前不支持有限域上的多元多项式。

部分分式分解

考虑一个具有整数系数的一元有理函数 f

>>> f = (x**2 + 2*x + 3)/(x**3 + 4*x**2 + 5*x + 2) 

要将 f 分解成部分分式,请使用 apart() 函数:

>>> apart(f)
 3       2        2
───── - ───── + ────────
x + 2   x + 1          2
 (x + 1) 

要从部分分式返回有理函数,请使用 together()cancel() 的组合:

>>> cancel(together(_))
 2
 x  + 2⋅x + 3
───────────────────
 3      2
x  + 4⋅x  + 5⋅x + 2 

文献

[Wester1999]

Michael J. Wester, 《CA 系统的数学能力批评》, 1999, www.math.unm.edu/~wester/cas/book/Wester.pdf

多项式操作模块参考

原文:docs.sympy.org/latest/modules/polys/reference.html

多项式操作算法和代数对象。

请查看多项式操作以获取 polys 模块文档的索引和模块的基本功能以获取简介性说明。

基本多项式操作函数

sympy.polys.polytools.poly(expr, *gens, **args)

将表达式有效地转换为多项式。

示例

>>> from sympy import poly
>>> from sympy.abc import x 
>>> poly(x*(x**2 + x - 1)**2)
Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ') 
sympy.polys.polytools.poly_from_expr(expr, *gens, **args)

从表达式构造一个多项式。

sympy.polys.polytools.parallel_poly_from_expr(exprs, *gens, **args)

从表达式构造多项式。

sympy.polys.polytools.degree(f, gen=0)

返回 f 在给定变量中的次数。

0 的次数为负无穷大。

示例

>>> from sympy import degree
>>> from sympy.abc import x, y 
>>> degree(x**2 + y*x + 1, gen=x)
2
>>> degree(x**2 + y*x + 1, gen=y)
1
>>> degree(0, x)
-oo 

另请参阅

sympy.polys.polytools.Poly.total_degreedegree_list

sympy.polys.polytools.degree_list(f, *gens, **args)

返回 f 在所有变量中的次数列表。

示例

>>> from sympy import degree_list
>>> from sympy.abc import x, y 
>>> degree_list(x**2 + y*x + 1)
(2, 1) 
sympy.polys.polytools.LC(f, *gens, **args)

返回多项式 f 的首项系数。

示例

>>> from sympy import LC
>>> from sympy.abc import x, y 
>>> LC(4*x**2 + 2*x*y**2 + x*y + 3*y)
4 
sympy.polys.polytools.LM(f, *gens, **args)

返回 f 的首项单项式。

示例

>>> from sympy import LM
>>> from sympy.abc import x, y 
>>> LM(4*x**2 + 2*x*y**2 + x*y + 3*y)
x**2 
sympy.polys.polytools.LT(f, *gens, **args)

返回 f 的首项。

示例

>>> from sympy import LT
>>> from sympy.abc import x, y 
>>> LT(4*x**2 + 2*x*y**2 + x*y + 3*y)
4*x**2 
sympy.polys.polytools.pdiv(f, g, *gens, **args)

计算多项式 fg 的伪除法。

示例

>>> from sympy import pdiv
>>> from sympy.abc import x 
>>> pdiv(x**2 + 1, 2*x - 4)
(2*x + 4, 20) 
sympy.polys.polytools.prem(f, g, *gens, **args)

计算多项式 fg 的伪余数。

示例

>>> from sympy import prem
>>> from sympy.abc import x 
>>> prem(x**2 + 1, 2*x - 4)
20 
sympy.polys.polytools.pquo(f, g, *gens, **args)

计算多项式 fg 的精确伪商。

示例

>>> from sympy import pquo
>>> from sympy.abc import x 
>>> pquo(x**2 + 1, 2*x - 4)
2*x + 4
>>> pquo(x**2 - 1, 2*x - 1)
2*x + 1 
sympy.polys.polytools.pexquo(f, g, *gens, **args)

计算多项式 fg 的精确伪商。

示例

>>> from sympy import pexquo
>>> from sympy.abc import x 
>>> pexquo(x**2 - 1, 2*x - 2)
2*x + 2 
>>> pexquo(x**2 + 1, 2*x - 4)
Traceback (most recent call last):
...
ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1 
sympy.polys.polytools.div(f, g, *gens, **args)

计算多项式 fg 的除法。

示例

>>> from sympy import div, ZZ, QQ
>>> from sympy.abc import x 
>>> div(x**2 + 1, 2*x - 4, domain=ZZ)
(0, x**2 + 1)
>>> div(x**2 + 1, 2*x - 4, domain=QQ)
(x/2 + 1, 5) 
sympy.polys.polytools.rem(f, g, *gens, **args)

计算多项式 fg 的余数。

示例

>>> from sympy import rem, ZZ, QQ
>>> from sympy.abc import x 
>>> rem(x**2 + 1, 2*x - 4, domain=ZZ)
x**2 + 1
>>> rem(x**2 + 1, 2*x - 4, domain=QQ)
5 
sympy.polys.polytools.quo(f, g, *gens, **args)

计算多项式 fg 的商。

示例

>>> from sympy import quo
>>> from sympy.abc import x 
>>> quo(x**2 + 1, 2*x - 4)
x/2 + 1
>>> quo(x**2 - 1, x - 1)
x + 1 
sympy.polys.polytools.exquo(f, g, *gens, **args)

计算多项式 fg 的精确商。

示例

>>> from sympy import exquo
>>> from sympy.abc import x 
>>> exquo(x**2 - 1, x - 1)
x + 1 
>>> exquo(x**2 + 1, 2*x - 4)
Traceback (most recent call last):
...
ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1 
sympy.polys.polytools.half_gcdex(f, g, *gens, **args)

fg 的半扩展欧几里德算法。

返回 (s, h),使得 h = gcd(f, g)s*f = h (mod g)

示例

>>> from sympy import half_gcdex
>>> from sympy.abc import x 
>>> half_gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
(3/5 - x/5, x + 1) 
sympy.polys.polytools.gcdex(f, g, *gens, **args)

fg 的扩展欧几里德算法。

返回 (s, t, h),使得 h = gcd(f, g)s*f + t*g = h

示例

>>> from sympy import gcdex
>>> from sympy.abc import x 
>>> gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
(3/5 - x/5, x**2/5 - 6*x/5 + 2, x + 1) 
sympy.polys.polytools.invert(f, g, *gens, **args)

在可能时对 fg 取倒数。

示例

>>> from sympy import invert, S, mod_inverse
>>> from sympy.abc import x 
>>> invert(x**2 - 1, 2*x - 1)
-4/3 
>>> invert(x**2 - 1, x - 1)
Traceback (most recent call last):
...
NotInvertible: zero divisor 

要更高效地求有理数的倒数,请使用sympy.core.intfunc.mod_inverse函数:

>>> mod_inverse(3, 5)
2
>>> (S(2)/5).invert(S(7)/3)
5/2 

另请参阅

sympy.core.intfunc.mod_inverse

sympy.polys.polytools.subresultants(f, g, *gens, **args)

计算 fg 的子结果 PRS。

示例

>>> from sympy import subresultants
>>> from sympy.abc import x 
>>> subresultants(x**2 + 1, x**2 - 1)
[x**2 + 1, x**2 - 1, -2] 
sympy.polys.polytools.resultant(f, g, *gens, includePRS=False, **args)

计算 fg 的结果多项式。

示例

>>> from sympy import resultant
>>> from sympy.abc import x 
>>> resultant(x**2 + 1, x**2 - 1)
4 
sympy.polys.polytools.discriminant(f, *gens, **args)

计算 f 的判别式。

示例

>>> from sympy import discriminant
>>> from sympy.abc import x 
>>> discriminant(x**2 + 2*x + 3)
-8 
sympy.polys.polytools.terms_gcd(f, *gens, **args)

移除 f 中项的最大公因式。

如果 deep 标志为 True,则 f 的参数将应用 terms_gcd 到它们。

如果从 f 中分离出一个分数,并且 f 是一个加法表达式,则会返回一个未求值的乘法表达式,以避免自动化简时重新分配它。当 clear 标志设置为 False 时,可以防止这种分离,前提是所有系数都不是分数。

示例

>>> from sympy import terms_gcd, cos
>>> from sympy.abc import x, y
>>> terms_gcd(x**6*y**2 + x**3*y, x, y)
x**3*y*(x**3*y + 1) 

polys 程序的默认操作是展开给定的表达式。terms_gcd 遵循此行为:

>>> terms_gcd((3+3*x)*(x+x*y))
3*x*(x*y + x + y + 1) 

如果不需要这样做,则可以将提示 expand 设置为 False。在这种情况下,该表达式将被视为由一个或多个项组成:

>>> terms_gcd((3+3*x)*(x+x*y), expand=False)
(3*x + 3)*(x*y + x) 

为了遍历 Mul 的因子或其他函数的参数,可以使用 deep 提示:

>>> 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)) 

有理数默认被分解出来:

>>> terms_gcd(x + y/2)
(2*x + y)/2 

只有 y 项的系数是分数;如果不想在这种情况下因式分解 1/2,可以将标志 clear 设为 False

>>> terms_gcd(x + y/2, clear=False)
x + y/2
>>> terms_gcd(x*y/2 + y**2, clear=False)
y*(x/2 + y) 

如果所有系数都是分数,则忽略 clear 标志:

>>> terms_gcd(x/3 + y/2, clear=False)
(2*x + 3*y)/6 

另请参阅

sympy.core.exprtools.gcd_terms, sympy.core.exprtools.factor_terms

sympy.polys.polytools.cofactors(f, g, *gens, **args)

计算 fg 的最大公约数及其余因子。

返回多项式 (h, cff, cfg),使得 h = gcd(f, g)cff = quo(f, h)cfg = quo(g, h) 是所谓的 fg 的余因子。

示例

>>> from sympy import cofactors
>>> from sympy.abc import x 
>>> cofactors(x**2 - 1, x**2 - 3*x + 2)
(x - 1, x + 1, x - 2) 
sympy.polys.polytools.gcd(f, g=None, *gens, **args)

计算 fg 的最大公约数。

示例

>>> from sympy import gcd
>>> from sympy.abc import x 
>>> gcd(x**2 - 1, x**2 - 3*x + 2)
x - 1 
sympy.polys.polytools.gcd_list(seq, *gens, **args)

计算多项式列表的最大公约数。

示例

>>> from sympy import gcd_list
>>> from sympy.abc import x 
>>> gcd_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
x - 1 
sympy.polys.polytools.lcm(f, g=None, *gens, **args)

计算 fg 的最小公倍数。

示例

>>> from sympy import lcm
>>> from sympy.abc import x 
>>> lcm(x**2 - 1, x**2 - 3*x + 2)
x**3 - 2*x**2 - x + 2 
sympy.polys.polytools.lcm_list(seq, *gens, **args)

计算多项式列表的最小公倍数。

示例

>>> from sympy import lcm_list
>>> from sympy.abc import x 
>>> lcm_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
x**5 - x**4 - 2*x**3 - x**2 + x + 2 
sympy.polys.polytools.trunc(f, p, *gens, **args)

f 对常数 p 取模。

示例

>>> from sympy import trunc
>>> from sympy.abc import x 
>>> trunc(2*x**3 + 3*x**2 + 5*x + 7, 3)
-x**3 - x + 1 
sympy.polys.polytools.monic(f, *gens, **args)

f 的所有系数除以 LC(f)

示例

>>> from sympy import monic
>>> from sympy.abc import x 
>>> monic(3*x**2 + 4*x + 2)
x**2 + 4*x/3 + 2/3 
sympy.polys.polytools.content(f, *gens, **args)

计算 f 的系数的最大公约数。

示例

>>> from sympy import content
>>> from sympy.abc import x 
>>> content(6*x**2 + 8*x + 12)
2 
sympy.polys.polytools.primitive(f, *gens, **args)

计算 f 的内容和原始形式。

示例

>>> from sympy.polys.polytools import primitive
>>> from sympy.abc import x 
>>> primitive(6*x**2 + 8*x + 12)
(2, 3*x**2 + 4*x + 6) 
>>> eq = (2 + 2*x)*x + 2 

默认执行展开:

>>> primitive(eq)
(2, x**2 + x + 1) 

expand 设置为 False 可关闭此功能。请注意,提取将不会递归进行;使用 as_content_primitive 方法进行递归、非破坏性有理数提取。

>>> primitive(eq, expand=False)
(1, x*(2*x + 2) + 2) 
>>> eq.as_content_primitive()
(2, x*(x + 1) + 1) 
sympy.polys.polytools.compose(f, g, *gens, **args)

计算函数组合 f(g)

示例

>>> from sympy import compose
>>> from sympy.abc import x 
>>> compose(x**2 + x, x - 1)
x**2 - x 
sympy.polys.polytools.decompose(f, *gens, **args)

计算 f 的函数分解。

示例

>>> from sympy import decompose
>>> from sympy.abc import x 
>>> decompose(x**4 + 2*x**3 - x - 1)
[x**2 - x - 1, x**2 + x] 
sympy.polys.polytools.sturm(f, *gens, **args)

计算 f 的斯图姆序列。

示例

>>> from sympy import sturm
>>> from sympy.abc import x 
>>> sturm(x**3 - 2*x**2 + x - 3)
[x**3 - 2*x**2 + x - 3, 3*x**2 - 4*x + 1, 2*x/9 + 25/9, -2079/4] 
sympy.polys.polytools.gff_list(f, *gens, **args)

计算 f 的最大阶乘因式列表。

注意,ff()rf() 的输入应为 Poly 实例,以使用这里的定义。

示例

>>> from sympy import gff_list, ff, Poly
>>> from sympy.abc import x 
>>> f = Poly(x**5 + 2*x**4 - x**3 - 2*x**2, x) 
>>> gff_list(f)
[(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)] 
>>> (ff(Poly(x), 1)*ff(Poly(x + 2), 4)) == f
True 
>>> f = Poly(x**12 + 6*x**11 - 11*x**10 - 56*x**9 + 220*x**8 + 208*x**7 -         1401*x**6 + 1090*x**5 + 2715*x**4 - 6720*x**3 - 1092*x**2 + 5040*x, x) 
>>> gff_list(f)
[(Poly(x**3 + 7, x, domain='ZZ'), 2), (Poly(x**2 + 5*x, x, domain='ZZ'), 3)] 
>>> ff(Poly(x**3 + 7, x), 2)*ff(Poly(x**2 + 5*x, x), 3) == f
True 
sympy.polys.polytools.gff(f, *gens, **args)

计算 f 的最大阶乘因式分解。

sympy.polys.polytools.sqf_norm(f, *gens, **args)

计算 f 的平方自由规范。

返回 sfr,使得 g(x) = f(x-sa)r(x) = Norm(g(x))K 上的平方自由多项式,其中 a 是基域的代数扩展。

示例

>>> from sympy import sqf_norm, sqrt
>>> from sympy.abc import x 
>>> sqf_norm(x**2 + 1, extension=[sqrt(3)])
([1], x**2 - 2*sqrt(3)*x + 4, x**4 - 4*x**2 + 16) 
sympy.polys.polytools.sqf_part(f, *gens, **args)

计算 f 的平方自由部分。

示例

>>> from sympy import sqf_part
>>> from sympy.abc import x 
>>> sqf_part(x**3 - 3*x - 2)
x**2 - x - 2 
sympy.polys.polytools.sqf_list(f, *gens, **args)

计算 f 的平方自由因式列表。

示例

>>> from sympy import sqf_list
>>> from sympy.abc import x 
>>> sqf_list(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
(2, [(x + 1, 2), (x + 2, 3)]) 
sympy.polys.polytools.sqf(f, *gens, **args)

计算 f 的平方自由因式分解。

示例

>>> from sympy import sqf
>>> from sympy.abc import x 
>>> sqf(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
2*(x + 1)**2*(x + 2)**3 
sympy.polys.polytools.factor_list(f, *gens, **args)

计算 f 的不可约因式列表。

示例

>>> from sympy import factor_list
>>> from sympy.abc import x, y 
>>> 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)]) 
sympy.polys.polytools.factor(f, *gens, deep=False, **args)

计算表达式 f 的因式分解为不可约因式。(要将整数因式分解为质数,请使用 factorint。)

有两种实现模式:符号模式和形式模式。如果 f 不是 Poly 的实例,并且未指定生成器,则使用前者模式。否则,使用形式模式。

在符号模式下,factor() 将遍历表达式树并分解其组件,不进行先前的展开,除非遇到 Add 的实例(在这种情况下使用形式分解)。这样 factor() 可以处理大或符号指数。

默认情况下,因子分解是在有理数上计算的。要在其他域上进行因子分解,例如代数或有限域,请使用适当的选项:extensionmodulusdomain

示例

>>> from sympy import factor, sqrt, exp
>>> from sympy.abc import x, y 
>>> 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) 

默认情况下,因子处理整个表达式:

>>> eq = 2**(x**2 + 2*x + 1)
>>> factor(eq)
2**(x**2 + 2*x + 1) 

如果 deep 标志为 True 则将分解子表达式:

>>> factor(eq, deep=True)
2**((x + 1)**2) 

如果 fraction 标志为 False,则不会合并有理表达式。默认为 True。

>>> factor(5*x + 3*exp(2 - 7*x), deep=True)
(5*x*exp(7*x) + 3*exp(2))*exp(-7*x)
>>> factor(5*x + 3*exp(2 - 7*x), deep=True, fraction=False)
5*x + 3*exp(2)*exp(-7*x) 

另请参阅

sympy.ntheory.factor_.factorint

sympy.polys.polytools.intervals(F, all=False, eps=None, inf=None, sup=None, strict=False, fast=False, sqf=False)

计算 f 的根的隔离区间。

示例

>>> from sympy import intervals
>>> from sympy.abc import x 
>>> intervals(x**2 - 3)
[((-2, -1), 1), ((1, 2), 1)]
>>> intervals(x**2 - 3, eps=1e-2)
[((-26/15, -19/11), 1), ((19/11, 26/15), 1)] 
sympy.polys.polytools.refine_root(f, s, t, eps=None, steps=None, fast=False, check_sqf=False)

将根的隔离区间精确化到给定的精度。

示例

>>> from sympy import refine_root
>>> from sympy.abc import x 
>>> refine_root(x**2 - 3, 1, 2, eps=1e-2)
(19/11, 26/15) 
sympy.polys.polytools.count_roots(f, inf=None, sup=None)

返回在 [inf, sup] 区间内 f 的根数。

如果 infsup 中的一个是复数,则将返回在以 infsup 为角的复数矩形中的根数。

示例

>>> from sympy import count_roots, I
>>> from sympy.abc import x 
>>> count_roots(x**4 - 4, -3, 3)
2
>>> count_roots(x**4 - 4, 0, 1 + 3*I)
1 
sympy.polys.polytools.all_roots(f, multiple=True, radicals=True)

返回 f 的实数和复数根及其重数。

参数:

fExprPoly

一元有理(或 Float)系数的多项式。

multiplebool(默认为 True)。

是否返回根的 list 或根/重数对的列表。

radicalsbool(默认为 True

对于一些无理根,使用简单的根式公式而不是 ComplexRootOf

返回:

Expr 的列表(通常是 ComplexRootOf)表示

返回的根根据其重数重复显示每个根

作为 f 的根。根总是以实根唯一的顺序排列

在复数根之前。实根按增加顺序排列。

复数根按递增的实部和递增的顺序排列

虚部。

如果传递 multiple=False 则会返回根/重数对的列表

替代返回。

如果传递 radicals=False 则所有根将表示为

要么是有理数,要么是 ComplexRootOf

解释

准确找到具有任意次有理系数的一元多项式的所有实数和复数根。根据 rootof() 给出的形式表示根。这等同于使用 rootof() 找到每个索引根。

示例

>>> from sympy import all_roots
>>> from sympy.abc import x, y 
>>> print(all_roots(x**3 + 1))
[-1, 1/2 - sqrt(3)*I/2, 1/2 + sqrt(3)*I/2] 

在某些情况下使用简单的根式公式,但避免使用三次和四次公式。相反,大多数非有理根将表示为 ComplexRootOf

>>> print(all_roots(x**3 + x + 1))
[CRootOf(x**3 + x + 1, 0), CRootOf(x**3 + x + 1, 1), CRootOf(x**3 + x + 1, 2)] 

任何次数的有理系数多项式的所有根都可以用 ComplexRootOf 表示。 使用 ComplexRootOf 可以绕过关于五次及更高次多项式根式公式可用性的限制 _[1]:

>>> p = x**5 - x - 1
>>> for r in all_roots(p): print(r)
CRootOf(x**5 - x - 1, 0)
CRootOf(x**5 - x - 1, 1)
CRootOf(x**5 - x - 1, 2)
CRootOf(x**5 - x - 1, 3)
CRootOf(x**5 - x - 1, 4)
>>> [r.evalf(3) for r in all_roots(p)]
[1.17, -0.765 - 0.352*I, -0.765 + 0.352*I, 0.181 - 1.08*I, 0.181 + 1.08*I] 

目前无法处理无理代数或超越系数 all_roots()(或一般上更广义的 rootof()):

>>> from sympy import sqrt, expand
>>> p = expand((x - sqrt(2))*(x - sqrt(3)))
>>> print(p)
x**2 - sqrt(3)*x - sqrt(2)*x + sqrt(6)
>>> all_roots(p)
Traceback (most recent call last):
...
NotImplementedError: sorted roots not supported over EX 

对于代数或超越系数,ground_roots() 可能能够通过因式分解找到一些根:

>>> from sympy import ground_roots
>>> ground_roots(p, x, extension=True)
{sqrt(2): 1, sqrt(3): 1} 

如果系数是数值的,则可以使用nroots()来找到所有根的近似值:

>>> from sympy import nroots
>>> nroots(p, 5)
[1.4142, 1.732] 

如果系数是符号的,则应使用sympy.polys.polyroots.roots()ground_roots()

>>> from sympy import roots, ground_roots
>>> p = x**2 - 3*x*y + 2*y**2
>>> roots(p, x)
{y: 1, 2*y: 1}
>>> ground_roots(p, x)
{y: 1, 2*y: 1} 

另见

Poly.all_roots

all_roots() 使用的底层 Poly 方法。

rootof

计算单个一元多项式的编号根。

real_roots

使用 rootof() 计算所有实根。

ground_roots

通过因式分解计算地域域中的一些根。

nroots

使用近似数值技术计算所有根。

sympy.polys.polyroots.roots

使用根式公式计算根的符号表达式。

参考资料

[R808]

en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem

sympy.polys.polytools.real_roots(f, multiple=True, radicals=True)

返回 f 的实根及其重数。

参数:

fExprPoly

一元有理(或Float)系数的多项式。

多重bool(默认True)。

是否返回根的列表或根/重数对列表。

根式bool(默认True

对于一些无理根,使用简单的根式公式而不是ComplexRootOf

返回:

一个Expr列表(通常为ComplexRootOf)表示

返回实根。 根据增加顺序排列的根和

根据它们作为f的根的重数重复。

如果传递了multiple=False,则将返回根/重数对列表

返回。

如果传递了radicals=False,则所有根将表示为

要么有理数,要么ComplexRootOf

解释

找到具有任意次数有理系数的一元多项式的所有实根。 根据rootof()给出的形式表示根。 这相当于使用rootof()all_roots()并仅过滤出实根。 但是,如果只需要实根,则real_roots()all_roots()更有效,因为它仅计算实根,并避免昂贵的复数根隔离程序。

示例

>>> from sympy import real_roots
>>> from sympy.abc import x, y 
>>> real_roots(2*x**3 - 7*x**2 + 4*x + 4)
[-1/2, 2, 2]
>>> real_roots(2*x**3 - 7*x**2 + 4*x + 4, multiple=False)
[(-1/2, 1), (2, 2)] 

任何次数的具有有理系数的多项式的实根可以使用ComplexRootOf表示:

>>> p = x**9 + 2*x + 2
>>> print(real_roots(p))
[CRootOf(x**9 + 2*x + 2, 0)]
>>> [r.evalf(3) for r in real_roots(p)]
[-0.865] 

所有有理根将作为有理数返回。 一些简单因子的根将使用根式或其他公式表示(除非传递了radicals=False)。 所有其他根将表示为ComplexRootOf

>>> p = (x + 7)*(x**2 - 2)*(x**3 + x + 1)
>>> print(real_roots(p))
[-7, -sqrt(2), CRootOf(x**3 + x + 1, 0), sqrt(2)]
>>> print(real_roots(p, radicals=False))
[-7, CRootOf(x**2 - 2, 0), CRootOf(x**3 + x + 1, 0), CRootOf(x**2 - 2, 1)] 

返回的所有根表达式将数值评估为没有虚部的实数。 这与由roots()使用的三次或四次公式生成的表达式形成对比,这些表达式受到由 casus irreducibilis 引起的影响[R809]

>>> from sympy import roots
>>> p = 2*x**3 - 9*x**2 - 6*x + 3
>>> [r.evalf(5) for r in roots(p, multiple=True)]
[5.0365 - 0.e-11*I, 0.33984 + 0.e-13*I, -0.87636 + 0.e-10*I]
>>> [r.evalf(5) for r in real_roots(p, x)]
[-0.87636, 0.33984, 5.0365]
>>> [r.is_real for r in roots(p, multiple=True)]
[None, None, None]
>>> [r.is_real for r in real_roots(p)]
[True, True, True] 

使用real_roots()等同于使用all_roots()(或rootof())并仅过滤出实根:

>>> from sympy import all_roots
>>> r = [r for r in all_roots(p) if r.is_real]
>>> real_roots(p) == r
True 

如果只想要实根,则使用 real_roots() 比使用 all_roots() 更快。使用 real_roots() 避免了复杂根的隔离,后者在处理高阶多项式时通常比实根隔离要慢得多,因为高阶多项式通常有比实根多得多的复杂根。

无法处理无理代数或超越系数的 real_roots()(或更一般地 rootof()):

>>> from sympy import sqrt, expand
>>> p = expand((x - sqrt(2))*(x - sqrt(3)))
>>> print(p)
x**2 - sqrt(3)*x - sqrt(2)*x + sqrt(6)
>>> real_roots(p)
Traceback (most recent call last):
...
NotImplementedError: sorted roots not supported over EX 

对于代数或超越系数的情况,ground_roots() 可能通过因式分解找到一些根:

>>> from sympy import ground_roots
>>> ground_roots(p, x, extension=True)
{sqrt(2): 1, sqrt(3): 1} 

如果系数是数字的话,可以使用 nroots() 大致找出所有根:

>>> from sympy import nroots
>>> nroots(p, 5)
[1.4142, 1.732] 

如果系数是符号的话,则应使用 sympy.polys.polyroots.roots()ground_roots()

>>> from sympy import roots, ground_roots
>>> p = x**2 - 3*x*y + 2*y**2
>>> roots(p, x)
{y: 1, 2*y: 1}
>>> ground_roots(p, x)
{y: 1, 2*y: 1} 

另见

Poly.real_roots

real_roots() 使用的底层 Poly 方法。

rootof

计算单个多项式的编号根。

all_roots

使用 rootof() 计算所有实根和非实根。

ground_roots

通过因式分解在基域中计算一些根。

nroots

使用近似数值技术计算所有根。

sympy.polys.polyroots.roots

使用根式公式计算 f 的根。

参考

[R809] (1,2)

en.wikipedia.org/wiki/Casus_irreducibilis

sympy.polys.polytools.nroots(f, n=15, maxsteps=50, cleanup=True)

使用数值近似方法计算 f 的根。

示例

>>> from sympy import nroots
>>> from sympy.abc import x 
>>> nroots(x**2 - 3, n=15)
[-1.73205080756888, 1.73205080756888]
>>> nroots(x**2 - 3, n=30)
[-1.73205080756887729352744634151, 1.73205080756887729352744634151] 
sympy.polys.polytools.ground_roots(f, *gens, **args)

通过因式分解在基域中计算 f 的根。

示例

>>> from sympy import ground_roots
>>> from sympy.abc import x 
>>> ground_roots(x**6 - 4*x**4 + 4*x**3 - x**2)
{0: 2, 1: 2} 
sympy.polys.polytools.nth_power_roots_poly(f, n, *gens, **args)

构造一个多项式,其根的 n 次方是 f 的根。

示例

>>> from sympy import nth_power_roots_poly, factor, roots
>>> from sympy.abc import x 
>>> f = x**4 - x**2 + 1
>>> g = factor(nth_power_roots_poly(f, 2)) 
>>> g
(x**2 - x + 1)**2 
>>> R_f = [ (r**2).expand() for r in roots(f) ]
>>> R_g = roots(g).keys() 
>>> set(R_f) == set(R_g)
True 
sympy.polys.polytools.cancel(f, *gens, _signsimp=True, **args)

取消有理函数 f 中的公因子。

示例

>>> from sympy import cancel, sqrt, Symbol, together
>>> from sympy.abc import x
>>> 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 

注意: 由于有理数的自动分布,由整数除以和会显示为和。要恢复有理数形式,请在结果上使用(\text{together}):

>>> cancel(x/2 + 1)
x/2 + 1
>>> together(_)
(x + 2)/2 
sympy.polys.polytools.reduced(f, G, *gens, **args)

将多项式f减少为一组多项式G的模。

给定多项式f和一组多项式G = (g_1, ..., g_n),计算一组商q = (q_1, ..., q_n)和余数r,使得f = q_1*g_1 + ... + q_n*g_n + r,其中r消失或者r是相对于G完全归约的多项式。

示例

>>> from sympy import reduced
>>> from sympy.abc import x, y 
>>> reduced(2*x**4 + y**2 - x**2 + y**3, [x**3 - x, y**3 - y])
([2*x, 1], x**2 + y**2 + y) 
sympy.polys.polytools.groebner(F, *gens, **args)

计算一组多项式的简化格罗布纳基。

使用order参数设置用于计算基础的单项式顺序。允许的顺序有lexgrlexgrevlex。如果未指定顺序,则默认为lex

有关格罗布纳基的更多信息,请参见参考文献和solve_poly_system()的文档字符串。

示例

示例来自[1]。

>>> from sympy import groebner
>>> from sympy.abc import x, y 
>>> F = [x*y - 2*y, 2*y**2 - x**2] 
>>> groebner(F, x, y, order='lex')
GroebnerBasis([x**2 - 2*y**2, x*y - 2*y, y**3 - 2*y], x, y,
 domain='ZZ', order='lex')
>>> groebner(F, x, y, order='grlex')
GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
 domain='ZZ', order='grlex')
>>> groebner(F, x, y, order='grevlex')
GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
 domain='ZZ', order='grevlex') 

默认情况下,使用改进后的布赫伯格算法的实现。可选择使用 F5B 算法的实现。可以使用method标志或sympy.polys.polyconfig.setup()函数来设置算法。

>>> F = [x**2 - x - 1, (2*x - 1) * y - (x**10 - (1 - x)**10)] 
>>> groebner(F, x, y, method='buchberger')
GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex')
>>> groebner(F, x, y, method='f5b')
GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex') 

参考文献

  1. [Buchberger01]

  2. [Cox97]

sympy.polys.polytools.is_zero_dimensional(F, *gens, **args)

检查由格罗布纳基生成的理想是否是零维的。

该算法检查不可被F的任何元素的主导单项式整除的单项式集是否有界。

参考文献

David A. Cox, John B. Little, Donal O’Shea. 理想、变量与算法, 第三版, 第 230 页

class sympy.polys.polytools.Poly(rep, *gens, **args)

用于表示和操作多项式表达式的通用类。

查看多项式操作以获取通用文档。

Poly 是 Basic 的子类而不是 Expr,但实例可以使用as_expr()方法转换为 Expr。

自版本 1.6 起已弃用: 在二元操作中,将 Poly 与非 Poly 对象结合使用已弃用。请先明确将两个对象都转换为 Poly 或 Expr。参见在二元操作中混合 Poly 和非多项式表达式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 

创建一个单变量多项式:

>>> Poly(x*(x**2 + x - 1)**2)
Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ') 

创建一个带有特定定义域的单变量多项式:

>>> from sympy import sqrt
>>> Poly(x**2 + 2*x + sqrt(3), domain='R')
Poly(1.0*x**2 + 2.0*x + 1.73205080756888, x, domain='RR') 

创建一个多变量多项式:

>>> Poly(y*x**2 + x*y + 1)
Poly(x**2*y + x*y + 1, x, y, domain='ZZ') 

创建一个单变量多项式,其中y是一个常数:

>>> Poly(y*x**2 + x*y + 1,x)
Poly(y*x**2 + y*x + 1, x, domain='ZZ[y]') 

您可以将上述多项式作为y的函数进行评估:

>>> Poly(y*x**2 + x*y + 1,x).eval(2)
6*y + 1 

另请参见

sympy.core.expr.Expr

EC(order=None)

返回f的最后一个非零系数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x**2 + 3*x, x).EC()
3 
EM(order=None)

返回f的最后一个非零单项式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).EM()
x**0*y**1 
ET(order=None)

返回f的最后一个非零项。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).ET()
(x**0*y**1, 3) 
LC(order=None)

返回f的主导系数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(4*x**3 + 2*x**2 + 3*x, x).LC()
4 
LM(order=None)

返回f的主导单项式。

主导单项式表示表达式 f 中主生成器的最高幂次的单项式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LM()
x**2*y**0 
LT(order=None)

返回 f 的主导项。

主导项表示表达式 f 中主生成器的最高幂次的项及其系数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LT()
(x**2*y**0, 4) 
TC()

返回 f 的尾部系数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x**2 + 3*x, x).TC()
0 
abs()

使 f 中的所有系数为正。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).abs()
Poly(x**2 + 1, x, domain='ZZ') 
add(g)

添加两个多项式 fg

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).add(Poly(x - 2, x))
Poly(x**2 + x - 1, x, domain='ZZ') 
>>> Poly(x**2 + 1, x) + Poly(x - 2, x)
Poly(x**2 + x - 1, x, domain='ZZ') 
add_ground(coeff)

f 添加基础域的元素。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x + 1).add_ground(2)
Poly(x + 3, x, domain='ZZ') 
all_coeffs()

返回单变量多项式 f 的所有系数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x - 1, x).all_coeffs()
[1, 0, 2, -1] 
all_monoms()

返回单变量多项式 f 的所有单项式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x - 1, x).all_monoms()
[(3,), (2,), (1,), (0,)] 

另见

all_terms

all_roots(multiple=True, radicals=True)

返回具有重数的实数和复数根的列表。

更多说明见 all_roots()

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**3 - 7*x**2 + 4*x + 4).all_roots()
[-1/2, 2, 2]
>>> Poly(x**3 + x + 1).all_roots()
[CRootOf(x**3 + x + 1, 0),
 CRootOf(x**3 + x + 1, 1),
 CRootOf(x**3 + x + 1, 2)] 
all_terms()

返回单变量多项式 f 的所有项。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x - 1, x).all_terms()
[((3,), 1), ((2,), 0), ((1,), 2), ((0,), -1)] 
as_dict(native=False, zero=False)

切换到 dict 表示。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 2*x*y**2 - y, x, y).as_dict()
{(0, 1): -1, (1, 2): 2, (2, 0): 1} 
as_expr(*gens)

将 Poly 实例转换为 Expr 实例。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = Poly(x**2 + 2*x*y**2 - y, x, y) 
>>> 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 
as_list(native=False)

切换到 list 表示。

as_poly(*gens, **args)

self 转换为多项式或返回 None

>>> from sympy import sin
>>> from sympy.abc import x, y 
>>> print((x**2 + x*y).as_poly())
Poly(x**2 + x*y, x, y, domain='ZZ') 
>>> print((x**2 + x*y).as_poly(x, y))
Poly(x**2 + x*y, x, y, domain='ZZ') 
>>> print((x**2 + sin(y)).as_poly(x, y))
None 
cancel(g, include=False)

取消有理函数 f/g 中的公共因子。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x))
(1, Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ')) 
>>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x), include=True)
(Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ')) 
clear_denoms(convert=False)

清除分母,但保留基础域。

示例

>>> from sympy import Poly, S, QQ
>>> from sympy.abc import x 
>>> f = Poly(x/2 + S(1)/3, x, domain=QQ) 
>>> 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)

如果存在,则返回 fmonom 的系数,否则返回 None

示例

>>> from sympy import Poly, exp
>>> from sympy.abc import x, y 
>>> p = Poly(24*x*y*exp(8) + 23*x, x, y) 
>>> p.coeff_monomial(x)
23
>>> p.coeff_monomial(y)
0
>>> p.coeff_monomial(x*y)
24*exp(8) 

注意 Expr.coeff() 的行为不同,如果可能的话会收集项;但是必须将 Poly 转换为 Expr 才能使用该方法:

>>> p.as_expr().coeff(x)
24*y*exp(8) + 23
>>> p.as_expr().coeff(y)
24*x*exp(8)
>>> p.as_expr().coeff(x*y)
24*exp(8) 

另见

nth

使用单项式生成器的指数进行更高效的查询

coeffs(order=None)

返回 f 中所有非零系数的字典顺序。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 + 2*x + 3, x).coeffs()
[1, 2, 3] 

另见

all_coeffs, coeff_monomial, nth

cofactors(g)

返回 fg 的最大公因式及其余项。

返回多项式 f 的最大公因式 (h, cff, cfg),使得 h = gcd(f, g),并且 cff = quo(f, h)cfg = quo(g, h) 是称为 fg 的余式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).cofactors(Poly(x**2 - 3*x + 2, x))
(Poly(x - 1, x, domain='ZZ'),
 Poly(x + 1, x, domain='ZZ'),
 Poly(x - 2, x, domain='ZZ')) 
compose(g)

计算 fg 的函数复合。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + x, x).compose(Poly(x - 1, x))
Poly(x**2 - x, x, domain='ZZ') 
content()

返回多项式系数的最大公因式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(6*x**2 + 8*x + 12, x).content()
2 
count_roots(inf=None, sup=None)

返回 f[inf, sup] 区间内的根数。

示例

>>> from sympy import Poly, I
>>> from sympy.abc import x 
>>> Poly(x**4 - 4, x).count_roots(-3, 3)
2
>>> Poly(x**4 - 4, x).count_roots(0, 1 + 3*I)
1 
decompose()

计算 f 的函数分解。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**4 + 2*x**3 - x - 1, x, domain='ZZ').decompose()
[Poly(x**2 - x - 1, x, domain='ZZ'), Poly(x**2 + x, x, domain='ZZ')] 
deflate()

通过将 x_i**m 映射到 y_i 来减少 f 的次数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**6*y**2 + x**3 + 1, x, y).deflate()
((3, 2), Poly(x**2*y + x + 1, x, y, domain='ZZ')) 
degree(gen=0)

返回 fx_j 中的次数。

0 的次数为负无穷大。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + y*x + 1, x, y).degree()
2
>>> Poly(x**2 + y*x + y, x, y).degree(y)
1
>>> Poly(0, x).degree()
-oo 
degree_list()

返回 f 的次数列表。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + y*x + 1, x, y).degree_list()
(2, 1) 
diff(*specs, **kwargs)

计算 f 的偏导数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 2*x + 1, x).diff()
Poly(2*x + 2, x, domain='ZZ') 
>>> Poly(x*y**2 + x, x, y).diff((0, 0), (1, 1))
Poly(2*x*y, x, y, domain='ZZ') 
discriminant()

计算 f 的判别式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 2*x + 3, x).discriminant()
-8 
dispersion(g=None)

计算多项式的离散度

对于两个多项式 (f(x)) 和 (g(x)),其中 (\deg f > 0) 和 (\deg g > 0),离散度 (\operatorname{dis}(f, g)) 定义为:

[\begin{split}\operatorname{dis}(f, g) & := \max{ J(f,g) \cup {0} } \ & = \max{ {a \in \mathbb{N} | \gcd(f(x), g(x+a)) \neq 1} \cup {0} }\end{split}]

对于单个多项式 (\operatorname{dis}(f) := \operatorname{dis}(f, f))。

示例

>>> from sympy import poly
>>> from sympy.polys.dispersion import dispersion, dispersionset
>>> from sympy.abc import x 

简单多项式的离散集和离散:

>>> fp = poly((x - 3)*(x + 3), x)
>>> sorted(dispersionset(fp))
[0, 6]
>>> dispersion(fp)
6 

注意,离散的定义不对称:

>>> fp = poly(x**4 - 3*x**2 + 1, x)
>>> gp = fp.shift(-3)
>>> sorted(dispersionset(fp, gp))
[2, 3, 4]
>>> dispersion(fp, gp)
4
>>> sorted(dispersionset(gp, fp))
[]
>>> dispersion(gp, fp)
-oo 

计算离散也适用于域扩展:

>>> from sympy import sqrt
>>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
>>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
>>> sorted(dispersionset(fp, gp))
[2]
>>> sorted(dispersionset(gp, fp))
[1, 4] 

我们甚至可以为具有符号系数的多项式执行计算:

>>> from sympy.abc import a
>>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
>>> sorted(dispersionset(fp))
[0, 1] 

参见

dispersionset

参考文献

  1. [ManWright94]

  2. [Koepf98]

  3. [Abramov71]

  4. [Man93]

dispersionset(g=None)

计算两个多项式的 离散集

对于两个多项式 (f(x)) 和 (g(x)),其中 (\deg f > 0) 和 (\deg g > 0),定义了离散集合 (\operatorname{J}(f, g)) 如下:

[\begin{split}\operatorname{J}(f, g) & := {a \in \mathbb{N}_0 | \gcd(f(x), g(x+a)) \neq 1} \ & = {a \in \mathbb{N}_0 | \deg \gcd(f(x), g(x+a)) \geq 1}\end{split}]

对于单个多项式,定义为 (\operatorname{J}(f) := \operatorname{J}(f, f))。

示例

>>> from sympy import poly
>>> from sympy.polys.dispersion import dispersion, dispersionset
>>> from sympy.abc import x 

简单多项式的离散集和离散:

>>> fp = poly((x - 3)*(x + 3), x)
>>> sorted(dispersionset(fp))
[0, 6]
>>> dispersion(fp)
6 

注意,离散的定义不对称:

>>> fp = poly(x**4 - 3*x**2 + 1, x)
>>> gp = fp.shift(-3)
>>> sorted(dispersionset(fp, gp))
[2, 3, 4]
>>> dispersion(fp, gp)
4
>>> sorted(dispersionset(gp, fp))
[]
>>> dispersion(gp, fp)
-oo 

计算离散也适用于域扩展:

>>> from sympy import sqrt
>>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
>>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
>>> sorted(dispersionset(fp, gp))
[2]
>>> sorted(dispersionset(gp, fp))
[1, 4] 

我们甚至可以为具有符号系数的多项式执行计算:

>>> from sympy.abc import a
>>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
>>> sorted(dispersionset(fp))
[0, 1] 

参见

dispersion

参考文献

  1. [ManWright94]

  2. [Koepf98]

  3. [Abramov71]

  4. [Man93]

div(g, auto=True)

通过 gf 进行多项式除法的余数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x))
(Poly(1/2*x + 1, x, domain='QQ'), Poly(5, x, domain='QQ')) 
>>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x), auto=False)
(Poly(0, x, domain='ZZ'), Poly(x**2 + 1, x, domain='ZZ')) 
property domain

获取 Poly 的地面域。

返回:

Domain:

Poly 的地面域。

示例

>>> from sympy import Poly, Symbol
>>> x = Symbol('x')
>>> p = Poly(x**2 + x)
>>> p
Poly(x**2 + x, x, domain='ZZ')
>>> p.domain
ZZ 
eject(*gens)

将选定的生成器弹出到地面域。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = Poly(x**2*y + x*y**3 + x*y + 1, x, y) 
>>> 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)

在给定变量中的 a 处评估 f

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y, z 
>>> Poly(x**2 + 2*x + 3, x).eval(2)
11 
>>> Poly(2*x*y + 3*x + y + 2, x, y).eval(x, 2)
Poly(5*y + 8, y, domain='ZZ') 
>>> f = Poly(2*x*y + 3*x + y + 2*z, x, y, z) 
>>> 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()

f 中移除不必要的生成器。

示例

>>> from sympy import Poly
>>> from sympy.abc import a, b, c, d, x 
>>> Poly(a + x, a, b, c, d, x).exclude()
Poly(a + x, a, x, domain='ZZ') 
exquo(g, auto=True)

计算 fg 的多项式精确商。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).exquo(Poly(x - 1, x))
Poly(x + 1, x, domain='ZZ') 
>>> Poly(x**2 + 1, x).exquo(Poly(2*x - 4, x))
Traceback (most recent call last):
...
ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1 
exquo_ground(coeff)

精确地通过地面域中的一个元素 f 的商。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x + 4).exquo_ground(2)
Poly(x + 2, x, domain='ZZ') 
>>> Poly(2*x + 3).exquo_ground(2)
Traceback (most recent call last):
...
ExactQuotientFailed: 2 does not divide 3 in ZZ 
factor_list()

返回 f 的不可约因子列表。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y 
>>> Poly(f).factor_list()
(2, [(Poly(x + y, x, y, domain='ZZ'), 1),
 (Poly(x**2 + 1, x, y, domain='ZZ'), 2)]) 
factor_list_include()

返回 f 的不可约因子列表。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y 
>>> Poly(f).factor_list_include()
[(Poly(2*x + 2*y, x, y, domain='ZZ'), 1),
 (Poly(x**2 + 1, x, y, domain='ZZ'), 2)] 
property free_symbols

多项式表达式的自由符号。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y, z 
>>> Poly(x**2 + 1).free_symbols
{x}
>>> Poly(x**2 + y).free_symbols
{x, y}
>>> Poly(x**2 + y, x).free_symbols
{x, y}
>>> Poly(x**2 + y, x, z).free_symbols
{x, y} 
property free_symbols_in_domain

self 域的自由符号。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 1).free_symbols_in_domain
set()
>>> Poly(x**2 + y).free_symbols_in_domain
set()
>>> Poly(x**2 + y, x).free_symbols_in_domain
{y} 
classmethod from_dict(rep, *gens, **args)

从一个 dict 构造一个多项式。

classmethod from_expr(rep, *gens, **args)

从表达式构造一个多项式。

classmethod from_list(rep, *gens, **args)

从一个 list 构造一个多项式。

classmethod from_poly(rep, *gens, **args)

从一个多项式构造一个多项式。

galois_group(by_name=False, max_tries=30, randomize=False)

计算此多项式的 Galois 群。

示例

>>> from sympy import Poly
>>> from sympy.abc import x
>>> f = Poly(x**4 - 2)
>>> G, _ = f.galois_group(by_name=True)
>>> print(G)
S4TransitiveSubgroups.D4 

参见

sympy.polys.numberfields.galoisgroups.galois_group

gcd(g)

返回 fg 的多项式最大公因式。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).gcd(Poly(x**2 - 3*x + 2, x))
Poly(x - 1, x, domain='ZZ') 
gcdex(g, auto=True)

扩展欧几里得算法应用于 fg

返回 (s, t, h),使得 h = gcd(f, g)s*f + t*g = h

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
>>> g = x**3 + x**2 - 4*x - 4 
>>> Poly(f).gcdex(Poly(g))
(Poly(-1/5*x + 3/5, x, domain='QQ'),
 Poly(1/5*x**2 - 6/5*x + 2, x, domain='QQ'),
 Poly(x + 1, x, domain='QQ')) 
property gen

返回主要生成元。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).gen
x 
get_domain()

获取 f 的底域。

get_modulus()

获取 f 的模。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, modulus=2).get_modulus()
2 
gff_list()

计算 f 的最大阶乘分解。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = x**5 + 2*x**4 - x**3 - 2*x**2 
>>> Poly(f).gff_list()
[(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)] 
ground_roots()

通过在底域中进行因式分解计算 f 的根。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**6 - 4*x**4 + 4*x**3 - x**2).ground_roots()
{0: 2, 1: 2} 
half_gcdex(g, auto=True)

fg 的半扩展欧几里得算法。

返回 (s, h),使得 h = gcd(f, g)s*f = h (mod g)

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
>>> g = x**3 + x**2 - 4*x - 4 
>>> Poly(f).half_gcdex(Poly(g))
(Poly(-1/5*x + 3/5, x, domain='QQ'), Poly(x + 1, x, domain='QQ')) 
has_only_gens(*gens)

如果 Poly(f, *gens) 保留底域,则返回 True

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y, z 
>>> Poly(x*y + 1, x, y, z).has_only_gens(x, y)
True
>>> Poly(x*y + z, x, y, z).has_only_gens(x, y)
False 
homogeneous_order()

返回 f 的齐次阶数。

齐次多项式是所有非零系数的单项式具有相同总次数的多项式。这个次数就是 f 的齐次阶数。如果你只想检查一个多项式是否是齐次的,则使用 Poly.is_homogeneous()

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = Poly(x**5 + 2*x**3*y**2 + 9*x*y**4)
>>> f.homogeneous_order()
5 
homogenize(s)

返回 f 的齐次多项式。

齐次多项式是所有非零系数的单项式具有相同总次数的多项式。如果你只想检查一个多项式是否是齐次的,则使用 Poly.is_homogeneous()。如果你不仅想检查一个多项式是否是齐次的,还想计算其齐次阶数,请使用 Poly.homogeneous_order()

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y, z 
>>> f = Poly(x**5 + 2*x**2*y**2 + 9*x*y**3)
>>> f.homogenize(z)
Poly(x**5 + 2*x**2*y**2*z + 9*x*y**3*z, x, y, z, domain='ZZ') 
inject(front=False)

将底域生成元注入到 f 中。

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = Poly(x**2*y + x*y**3 + x*y + 1, 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)

计算 f 的不定积分。

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 2*x + 1, x).integrate()
Poly(1/3*x**3 + x**2 + x, x, domain='QQ') 
>>> Poly(x*y**2 + x, x, y).integrate((0, 1), (1, 0))
Poly(1/2*x**2*y**2 + 1/2*x**2, x, y, domain='QQ') 
intervals(all=False, eps=None, inf=None, sup=None, fast=False, sqf=False)

计算 f 的根的隔离区间。

对于实根,使用文森特-阿克里塔斯-斯特泽邦斯基(VAS)连分数法。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 3, x).intervals()
[((-2, -1), 1), ((1, 2), 1)]
>>> Poly(x**2 - 3, x).intervals(eps=1e-2)
[((-26/15, -19/11), 1), ((19/11, 26/15), 1)] 

参考文献

invert(g, auto=True)

在可能时对 fg 反演。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).invert(Poly(2*x - 1, x))
Poly(-4/3, x, domain='QQ') 
>>> Poly(x**2 - 1, x).invert(Poly(x - 1, x))
Traceback (most recent call last):
...
NotInvertible: zero divisor 
property is_cyclotomic

返回 True 如果 f 是一个周期多项式。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1 
>>> Poly(f).is_cyclotomic
False 
>>> g = x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1 
>>> Poly(g).is_cyclotomic
True 
property is_ground

返回 True 如果 f 是底域的元素。

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x, x).is_ground
False
>>> Poly(2, x).is_ground
True
>>> Poly(y, x).is_ground
True 
property is_homogeneous

返回 True 如果 f 是一个齐次多项式。

齐次多项式是所有非零系数的单项式具有相同总次数的多项式。如果你不仅想检查一个多项式是否是齐次的,还想计算其齐次阶数,请使用 Poly.homogeneous_order()

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + x*y, x, y).is_homogeneous
True
>>> Poly(x**3 + x*y, x, y).is_homogeneous
False 
property is_irreducible

返回 True 如果 f 在其域上没有因子。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + x + 1, x, modulus=2).is_irreducible
True
>>> Poly(x**2 + 1, x, modulus=2).is_irreducible
False 
property is_linear

返回 True 如果 f 在所有变量中是线性的。

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x + y + 2, x, y).is_linear
True
>>> Poly(x*y + 2, x, y).is_linear
False 
property is_monic

返回 True 如果 f 的首项系数为一。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x + 2, x).is_monic
True
>>> Poly(2*x + 2, x).is_monic
False 
property is_monomial

返回 True 如果 f 是零或仅有一个项。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(3*x**2, x).is_monomial
True
>>> Poly(3*x**2 + 1, x).is_monomial
False 
property is_multivariate

返回 True 如果 f 是一个多变量多项式。

例子

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + x + 1, x).is_multivariate
False
>>> Poly(x*y**2 + x*y + 1, x, y).is_multivariate
True
>>> Poly(x*y**2 + x*y + 1, x).is_multivariate
False
>>> Poly(x**2 + x + 1, x, y).is_multivariate
True 
property is_one

返回 True 如果 f 是一个单位多项式。

例子

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(0, x).is_one
False
>>> Poly(1, x).is_one
True 
property is_primitive

如果 f 的系数的最大公约数是一,则返回 True

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**2 + 6*x + 12, x).is_primitive
False
>>> Poly(x**2 + 3*x + 6, x).is_primitive
True 
property is_quadratic

如果 f 在所有变量上都是二次的,则返回 True

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x*y + 2, x, y).is_quadratic
True
>>> Poly(x*y**2 + 2, x, y).is_quadratic
False 
property is_sqf

如果 f 是一个无平方因子的多项式,则返回 True

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 2*x + 1, x).is_sqf
False
>>> Poly(x**2 - 1, x).is_sqf
True 
property is_univariate

如果 f 是一元多项式,则返回 True

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + x + 1, x).is_univariate
True
>>> Poly(x*y**2 + x*y + 1, x, y).is_univariate
False
>>> Poly(x*y**2 + x*y + 1, x).is_univariate
True
>>> Poly(x**2 + x + 1, x, y).is_univariate
False 
property is_zero

如果 f 是零多项式,则返回 True

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(0, x).is_zero
True
>>> Poly(1, x).is_zero
False 
l1_norm()

返回 f 的 l1 范数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(-x**2 + 2*x - 3, x).l1_norm()
6 
lcm(g)

返回 fg 的多项式最小公倍数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).lcm(Poly(x**2 - 3*x + 2, x))
Poly(x**3 - 2*x**2 - x + 2, x, domain='ZZ') 
length()

返回 f 中非零项的数量。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 2*x - 1).length()
3 
lift()

将代数系数转换为有理数。

示例

>>> from sympy import Poly, I
>>> from sympy.abc import x 
>>> Poly(x**2 + I*x + 1, x, extension=I).lift()
Poly(x**4 + 3*x**2 + 1, x, domain='QQ') 
ltrim(gen)

f 中删除左边指定的 gen 生成器的虚拟生成器。当 gen 是整数时,它指的是 f 的生成器元组中位于该位置的生成器。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y, z 
>>> Poly(y**2 + y*z**2, x, y, z).ltrim(y)
Poly(y**2 + y*z**2, y, z, domain='ZZ')
>>> Poly(z, x, y, z).ltrim(-1)
Poly(z, z, domain='ZZ') 
make_monic_over_integers_by_scaling_roots()

将任意一元多项式在 QQ 或 ZZ 上转换为 ZZ 上的首一多项式,必要时通过缩放根来进行。

返回:

对偶 (g, c)

g 是多项式。

c 是根必须缩放的整数

解释

无论 f 是否是不可约的,都可以执行此操作;当 f 是不可约的时,可以理解为确定一个生成与 f 的根相同的域的代数整数。

示例

>>> from sympy import Poly, S
>>> from sympy.abc import x
>>> f = Poly(x**2/2 + S(1)/4 * x + S(1)/8, x, domain='QQ')
>>> f.make_monic_over_integers_by_scaling_roots()
(Poly(x**2 + 2*x + 4, x, domain='ZZ'), 4) 
match(*args, **kwargs)

匹配 Poly 中的表达式。参见 Basic.match()

max_norm()

返回 f 的最大范数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(-x**2 + 2*x - 3, x).max_norm()
3 
monic(auto=True)

将所有系数除以 LC(f)

示例

>>> from sympy import Poly, ZZ
>>> from sympy.abc import x 
>>> Poly(3*x**2 + 6*x + 9, x, domain=ZZ).monic()
Poly(x**2 + 2*x + 3, x, domain='QQ') 
>>> Poly(3*x**2 + 4*x + 2, x, domain=ZZ).monic()
Poly(x**2 + 4/3*x + 2/3, x, domain='QQ') 
monoms(order=None)

返回 f 的所有非零单项式按词典序。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).monoms()
[(2, 0), (1, 2), (1, 1), (0, 1)] 

另见

all_monoms

mul(g)

将两个多项式 fg 相乘。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).mul(Poly(x - 2, x))
Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ') 
>>> Poly(x**2 + 1, x)*Poly(x - 2, x)
Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ') 
mul_ground(coeff)

f 乘以地面域的元素。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x + 1).mul_ground(2)
Poly(2*x + 2, x, domain='ZZ') 
neg()

f 的所有系数取反。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).neg()
Poly(-x**2 + 1, x, domain='ZZ') 
>>> -Poly(x**2 - 1, x)
Poly(-x**2 + 1, x, domain='ZZ') 
classmethod new(rep, *gens)

从原始表示构造 Poly 实例。

norm()

计算定义在数域 K 上的多项式 f 共轭的乘积 Norm(f)

示例

>>> from sympy import Poly, sqrt
>>> from sympy.abc import x 
>>> a, b = sqrt(2), sqrt(3) 

二次扩展上的多项式。两个共轭根 x - a 和 x + a。

>>> f = Poly(x - a, x, extension=a)
>>> f.norm()
Poly(x**2 - 2, x, domain='QQ') 

四次扩展上的多项式。四个共轭根 x - a, x - a, x + a 和 x + a。

>>> f = Poly(x - a, x, extension=(a, b))
>>> f.norm()
Poly(x**4 - 4*x**2 + 4, x, domain='QQ') 
nroots(n=15, maxsteps=50, cleanup=True)

计算 f 的根的数值近似。

参数:

n … 计算的数字位数

maxsteps … 最大迭代次数

如果在 maxsteps 中无法达到精度 n,它将引发异常

exception. 需要使用更高的 maxsteps 重新运行。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 3).nroots(n=15)
[-1.73205080756888, 1.73205080756888]
>>> Poly(x**2 - 3).nroots(n=30)
[-1.73205080756887729352744634151, 1.73205080756887729352744634151] 
nth(*N)

返回 f 的第 n 个系数,其中 N 是感兴趣项中生成器的指数。

示例

>>> from sympy import Poly, sqrt
>>> from sympy.abc import x, y 
>>> Poly(x**3 + 2*x**2 + 3*x, x).nth(2)
2
>>> Poly(x**3 + 2*x*y**2 + y**2, x, y).nth(1, 2)
2
>>> Poly(4*sqrt(x)*y)
Poly(4*y*(sqrt(x)), y, sqrt(x), domain='ZZ')
>>> _.nth(1, 1)
4 

另见

coeff_monomial

nth_power_roots_poly(n)

f 的根的 n 次幂构造一个多项式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = Poly(x**4 - x**2 + 1) 
>>> f.nth_power_roots_poly(2)
Poly(x**4 - 2*x**3 + 3*x**2 - 2*x + 1, x, domain='ZZ')
>>> f.nth_power_roots_poly(3)
Poly(x**4 + 2*x**2 + 1, x, domain='ZZ')
>>> f.nth_power_roots_poly(4)
Poly(x**4 + 2*x**3 + 3*x**2 + 2*x + 1, x, domain='ZZ')
>>> f.nth_power_roots_poly(12)
Poly(x**4 - 4*x**3 + 6*x**2 - 4*x + 1, x, domain='ZZ') 
property one

返回具有 self 属性的一个多项式。

pdiv(g)

f 除以 g 的多项式伪除法。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).pdiv(Poly(2*x - 4, x))
(Poly(2*x + 4, x, domain='ZZ'), Poly(20, x, domain='ZZ')) 
per(rep, gens=None, remove=None)

用给定的表示创建一个 Poly。

示例

>>> from sympy import Poly, ZZ
>>> from sympy.abc import x, y 
>>> from sympy.polys.polyclasses import DMP 
>>> a = Poly(x**2 + 1) 
>>> a.per(DMP([ZZ(1), ZZ(1)], ZZ), gens=[y])
Poly(y + 1, y, domain='ZZ') 
pexquo(g)

f 除以 g 的多项式精确伪商。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 1, x).pexquo(Poly(2*x - 2, x))
Poly(2*x + 2, x, domain='ZZ') 
>>> Poly(x**2 + 1, x).pexquo(Poly(2*x - 4, x))
Traceback (most recent call last):
...
ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1 
pow(n)

f 提升到非负幂 n

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x - 2, x).pow(3)
Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ') 
>>> Poly(x - 2, x)**3
Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ') 
pquo(g)

f 除以 g 的多项式伪商。

请参见函数 prem(f, g) 中的注意事项。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).pquo(Poly(2*x - 4, x))
Poly(2*x + 4, x, domain='ZZ') 
>>> Poly(x**2 - 1, x).pquo(Poly(2*x - 2, x))
Poly(2*x + 2, x, domain='ZZ') 
prem(g)

多项式伪余数 f 除以 g

注意:函数 prem(f, g, x) 可以安全地用于计算。

在 Z[x] only 中的子结果多项式余数序列 (PRS)。

若要在 Z[x] 中安全地计算欧几里德和斯图米尔 PRS,请使用模块 sympy.polys.subresultants_qq_zz 中找到的相应函数之一。带有后缀 _pg 的模块函数使用 rem(f, g, x) 在 Z[x] 中计算 PRS,而带有后缀 _amv 的函数使用 rem_z(f, g, x) 在 Z[x] 中计算 PRS。

函数 rem_z(f, g, x) 不同于 prem(f, g, x),因为它在计算 Z[x]中的余式多项式时,将被除数预乘以除数的绝对值的次数,即 degree(f, x) - degree(g, x) + 1。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).prem(Poly(2*x - 4, x))
Poly(20, x, domain='ZZ') 
primitive()

返回 f 的内容和原始形式。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**2 + 8*x + 12, x).primitive()
(2, Poly(x**2 + 4*x + 6, x, domain='ZZ')) 
quo(g, auto=True)

计算 f 除以 g 的多项式商。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).quo(Poly(2*x - 4, x))
Poly(1/2*x + 1, x, domain='QQ') 
>>> Poly(x**2 - 1, x).quo(Poly(x - 1, x))
Poly(x + 1, x, domain='ZZ') 
quo_ground(coeff)

f 除以基本定义域元素的商。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x + 4).quo_ground(2)
Poly(x + 2, x, domain='ZZ') 
>>> Poly(2*x + 3).quo_ground(2)
Poly(x + 1, x, domain='ZZ') 
rat_clear_denoms(g)

清除有理函数 f/g 中的分母。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> f = Poly(x**2/y + 1, x)
>>> g = Poly(x**3 + y, 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)

返回带有重数的实根列表。

参见 real_roots() 以获取更多解释。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**3 - 7*x**2 + 4*x + 4).real_roots()
[-1/2, 2, 2]
>>> Poly(x**3 + x + 1).real_roots()
[CRootOf(x**3 + x + 1, 0)] 
refine_root(s, t, eps=None, steps=None, fast=False, check_sqf=False)

优化根的隔离区间至指定精度。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 3, x).refine_root(1, 2, eps=1e-2)
(19/11, 26/15) 
rem(g, auto=True)

计算 f 除以 g 的多项式余数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x))
Poly(5, x, domain='ZZ') 
>>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x), auto=False)
Poly(x**2 + 1, x, domain='ZZ') 
reorder(*gens, **args)

高效应用新的生成器顺序。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + x*y**2, x, y).reorder(y, x)
Poly(y**2*x + x**2, y, x, domain='ZZ') 
replace(x, y=None, **_ignore)

在生成器列表中用 y 替换 x

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 1, x).replace(x, y)
Poly(y**2 + 1, y, domain='ZZ') 
resultant(g, includePRS=False)

计算 fg 的结果通过 PRS。

如果 includePRS=True,则在结果中包含子结果 PRS。因为 PRS 用于计算结果,所以这比单独调用 subresultants() 更有效。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = Poly(x**2 + 1, x) 
>>> f.resultant(Poly(x**2 - 1, x))
4
>>> f.resultant(Poly(x**2 - 1, x), 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)

重新计算多项式的基本定义域。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = Poly(x**2 + 1, x, domain='QQ[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') 
revert(n)

计算 f**(-1) mod x**n.

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(1, x).revert(2)
Poly(1, x, domain='ZZ') 
>>> Poly(1 + x, x).revert(1)
Poly(1, x, domain='ZZ') 
>>> Poly(x**2 - 2, x).revert(2)
Traceback (most recent call last):
...
NotReversible: only units are reversible in a ring 
>>> Poly(1/x, x).revert(1)
Traceback (most recent call last):
...
PolynomialError: 1/x contains an element of the generators set 
root(index, radicals=True)

获取多项式的索引根。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = Poly(2*x**3 - 7*x**2 + 4*x + 4) 
>>> 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 
>>> Poly(x**5 + x + 1).root(0)
CRootOf(x**3 - x**2 + 1, 0) 
same_root(a, b)

决定该多项式的两个根是否相等。

抛出:

域错误

如果多项式的定义域不是 ZZ, QQ, RR, 或 CC。

多变量多项式错误

如果多项式不是单变量的。

多项式错误

如果多项式的次数 < 2。

示例

>>> from sympy import Poly, cyclotomic_poly, exp, I, pi
>>> f = Poly(cyclotomic_poly(5))
>>> r0 = exp(2*I*pi/5)
>>> indices = [i for i, r in enumerate(f.all_roots()) if f.same_root(r, r0)]
>>> print(indices)
[3] 
set_domain(domain)

设置 f 的基本定义域。

set_modulus(modulus)

设置 f 的模数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(5*x**2 + 2*x - 1, x).set_modulus(2)
Poly(x**2 + 1, x, modulus=2) 
shift(a)

高效计算泰勒移位 f(x + a)

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 2*x + 1, x).shift(2)
Poly(x**2 + 2*x + 1, x, domain='ZZ') 

另见

shift_list

多变量多项式的类似方法。

shift_list(a)

高效计算泰勒移位 f(X + A)

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x*y, [x,y]).shift_list([1, 2]) == Poly((x+1)*(y+2), [x,y])
True 

另见

shift

单变量多项式的类似方法。

slice(x, m, n=None)

f 的连续子序列。

sqf_list(all=False)

返回 f 的无平方因子列表。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16 
>>> Poly(f).sqf_list()
(2, [(Poly(x + 1, x, domain='ZZ'), 2),
 (Poly(x + 2, x, domain='ZZ'), 3)]) 
>>> Poly(f).sqf_list(all=True)
(2, [(Poly(1, x, domain='ZZ'), 1),
 (Poly(x + 1, x, domain='ZZ'), 2),
 (Poly(x + 2, x, domain='ZZ'), 3)]) 
sqf_list_include(all=False)

返回 f 的无平方因子列表。

示例

>>> from sympy import Poly, expand
>>> from sympy.abc import x 
>>> f = expand(2*(x + 1)**3*x**4)
>>> f
2*x**7 + 6*x**6 + 6*x**5 + 2*x**4 
>>> Poly(f).sqf_list_include()
[(Poly(2, x, domain='ZZ'), 1),
 (Poly(x + 1, x, domain='ZZ'), 3),
 (Poly(x, x, domain='ZZ'), 4)] 
>>> Poly(f).sqf_list_include(all=True)
[(Poly(2, x, domain='ZZ'), 1),
 (Poly(1, x, domain='ZZ'), 2),
 (Poly(x + 1, x, domain='ZZ'), 3),
 (Poly(x, x, domain='ZZ'), 4)] 
sqf_norm()

计算 f 的无平方法则。

返回 sfr,使得 g(x) = f(x-sa)r(x) = Norm(g(x)) 是在 K 上的一个无平方多项式,其中 a 是地域域的代数扩展。

示例

>>> from sympy import Poly, sqrt
>>> from sympy.abc import x 
>>> s, f, r = Poly(x**2 + 1, x, 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()

计算 f 的无平方部分。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 - 3*x - 2, x).sqf_part()
Poly(x**2 - x - 2, x, domain='ZZ') 
sqr()

对多项式 f 进行平方。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x - 2, x).sqr()
Poly(x**2 - 4*x + 4, x, domain='ZZ') 
>>> Poly(x - 2, x)**2
Poly(x**2 - 4*x + 4, x, domain='ZZ') 
sturm(auto=True)

计算 f 的斯图姆序列。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**3 - 2*x**2 + x - 3, x).sturm()
[Poly(x**3 - 2*x**2 + x - 3, x, domain='QQ'),
 Poly(3*x**2 - 4*x + 1, x, domain='QQ'),
 Poly(2/9*x + 25/9, x, domain='QQ'),
 Poly(-2079/4, x, domain='QQ')] 
sub(g)

减去两个多项式 fg

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).sub(Poly(x - 2, x))
Poly(x**2 - x + 3, x, domain='ZZ') 
>>> Poly(x**2 + 1, x) - Poly(x - 2, x)
Poly(x**2 - x + 3, x, domain='ZZ') 
sub_ground(coeff)

从地域域的元素中减去 f

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x + 1).sub_ground(2)
Poly(x - 1, x, domain='ZZ') 
subresultants(g)

计算 fg 的子结果 PRS。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x).subresultants(Poly(x**2 - 1, x))
[Poly(x**2 + 1, x, domain='ZZ'),
 Poly(x**2 - 1, x, domain='ZZ'),
 Poly(-2, x, domain='ZZ')] 
terms(order=None)

按词典顺序返回 f 的所有非零项。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).terms()
[((2, 0), 1), ((1, 2), 2), ((1, 1), 1), ((0, 1), 3)] 

另见

all_terms

terms_gcd()

从多项式 f 中移除项的最大公因子。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**6*y**2 + x**3*y, x, y).terms_gcd()
((3, 1), Poly(x**3*y + 1, x, y, domain='ZZ')) 
termwise(func, *gens, **args)

f 的所有项应用函数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> def func(k, coeff):
...     k = k[0]
...     return coeff//10**(2-k) 
>>> Poly(x**2 + 20*x + 400).termwise(func)
Poly(x**2 + 2*x + 4, x, domain='ZZ') 
to_exact()

使地域域变得精确。

示例

>>> from sympy import Poly, RR
>>> from sympy.abc import x 
>>> Poly(x**2 + 1.0, x, domain=RR).to_exact()
Poly(x**2 + 1, x, domain='QQ') 
to_field()

使地域域成为一个域。

示例

>>> from sympy import Poly, ZZ
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, x, domain=ZZ).to_field()
Poly(x**2 + 1, x, domain='QQ') 
to_ring()

使地域域成为一个环。

示例

>>> from sympy import Poly, QQ
>>> from sympy.abc import x 
>>> Poly(x**2 + 1, domain=QQ).to_ring()
Poly(x**2 + 1, x, domain='ZZ') 
total_degree()

返回 f 的总次数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x, y 
>>> Poly(x**2 + y*x + 1, x, y).total_degree()
2
>>> Poly(x + y**5, x, y).total_degree()
5 
transform(p, q)

高效地评估函数变换 q**n * f(p/q)

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(x**2 - 2*x + 1, x).transform(Poly(x + 1, x), Poly(x - 1, x))
Poly(4, x, domain='ZZ') 
trunc(p)

f 模化为常数 p 的余数。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> Poly(2*x**3 + 3*x**2 + 5*x + 7, x).trunc(3)
Poly(-x**3 - x + 1, x, domain='ZZ') 
unify(g)

使 fg 属于相同的地域域。

示例

>>> from sympy import Poly
>>> from sympy.abc import x 
>>> f, g = Poly(x/2 + 1), Poly(2*x + 1) 
>>> f
Poly(1/2*x + 1, x, domain='QQ')
>>> g
Poly(2*x + 1, x, domain='ZZ') 
>>> F, G = f.unify(g) 
>>> F
Poly(1/2*x + 1, x, domain='QQ')
>>> G
Poly(2*x + 1, x, domain='QQ') 
property unit

返回与 self 属性相同的单位多项式。

property zero

返回与 self 属性相同的零多项式。

class sympy.polys.polytools.PurePoly(rep, *gens, **args)

用于表示纯多项式的类。

property free_symbols

多项式的自由符号。

示例

>>> from sympy import PurePoly
>>> from sympy.abc import x, y 
>>> PurePoly(x**2 + 1).free_symbols
set()
>>> PurePoly(x**2 + y).free_symbols
set()
>>> PurePoly(x**2 + y, x).free_symbols
{y} 
class sympy.polys.polytools.GroebnerBasis(F, *gens, **args)

表示简化的 Groebner 基础。

contains(poly)

检查 poly 是否属于由 self 生成的理想。

示例

>>> from sympy import groebner
>>> from sympy.abc import x, y 
>>> 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 
fglm(order)

将一个 Groebner 基础从一种排序转换到另一种排序。

FGLM 算法将零维理想的简化 Groebner 基从一种排序转换到另一种排序。 当直接计算与特定排序相关的 Groebner 基不可行时,通常使用此方法。

示例

>>> from sympy.abc import x, y
>>> from sympy import groebner 
>>> F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1]
>>> G = groebner(F, x, y, order='grlex') 
>>> list(G.fglm('lex'))
[2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7]
>>> list(groebner(F, x, y, order='lex'))
[2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7] 

参考

[R810]

J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient Computation of Zero-dimensional Groebner Bases by Change of Ordering

property is_zero_dimensional

检查由 Groebner 基生成的理想是否是零维的。

算法检查 F 的任何元素的领导单项式不可整除的单项式集是否是有界的。

参考

David A. Cox, John B. Little, Donal O’Shea. Ideals, Varieties and Algorithms, 第 3 版, p. 230

reduce(expr, auto=True)

将多项式模化为 Groebner 基的余数。

给定多项式 f 和一组多项式 G = (g_1, ..., g_n),计算商集 q = (q_1, ..., q_n) 和余项 r,使得 f = q_1*f_1 + ... + q_n*f_n + r,其中 r 为零或者相对于 G 完全约简的多项式。

示例

>>> from sympy import groebner, expand
>>> from sympy.abc import x, y 
>>> 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 

额外的多项式操作函数

sympy.polys.polyfuncs.symmetrize(F, *gens, **args)

将一个多项式重写为基本对称多项式的形式。

对称多项式是一个多元多项式,在任何变量置换下保持不变,即如果 (f = f(x_1, x_2, \dots, x_n)),那么 (f = f(x_{i_1}, x_{i_2}, \dots, x_{i_n})),其中 ((i_1, i_2, \dots, i_n)) 是 ((1, 2, \dots, n)) 的一个排列(即 (S_n) 群的一个元素)。

返回对称多项式元组 (f1, f2, ..., fn),使得 f = f1 + f2 + ... + fn

示例

>>> from sympy.polys.polyfuncs import symmetrize
>>> from sympy.abc import x, y 
>>> 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)]) 
sympy.polys.polyfuncs.horner(f, *gens, **args)

将一个多项式重写为 Horner 形式。

在其他应用中,使用 Horner 方案([1])来在点处求多项式的值是最优的。

示例

>>> from sympy.polys.polyfuncs import horner
>>> from sympy.abc import x, y, a, b, c, d, 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)) 

参考

[1] - en.wikipedia.org/wiki/Horner_scheme

sympy.polys.polyfuncs.interpolate(data, x)

为数据点在点 x 处插值多项式。

示例

>>> from sympy.polys.polyfuncs import interpolate
>>> from sympy.abc import a, b, x 

列表被解释为与从 1 开始的范围配对:

>>> interpolate([1, 4, 9, 16], x)
x**2 

通过提供坐标列表来明确表示:

>>> interpolate([(1, 1), (2, 4), (3, 9)], x)
x**2 

(x, y)坐标也可以作为字典的键和值给出(且点不需要等间距):

>>> interpolate([(-1, 2), (1, 2), (2, 5)], x)
x**2 + 1
>>> interpolate({-1: 2, 1: 2, 2: 5}, x)
x**2 + 1 

如果插值仅会被使用一次,那么可以传递感兴趣的值而不是传递符号:

>>> interpolate([1, 4, 9], 5)
25 

符号坐标也受支持:

>>> [(i,interpolate((a, b), i)) for i in range(1, 4)]
[(1, a), (2, b), (3, -a + 2*b)] 
sympy.polys.polyfuncs.viete(f, roots=None, *gens, **args)

f生成 Vieta 公式。

示例

>>> from sympy.polys.polyfuncs import viete
>>> from sympy import symbols 
>>> x, a, b, c, r1, r2 = symbols('x,a:c,r1:3') 
>>> viete(a*x**2 + b*x + c, [r1, r2], x)
[(r1 + r2, -b/a), (r1*r2, c/a)] 

域构造器

sympy.polys.constructor.construct_domain(obj, **args)

构建表达式列表的最小域。

参数:

obj: 列表或字典

用于构建域的表达式。

**args: 关键字参数

影响域选择的选项。

返回:

(K, elements): 域及其域元素列表

能表示表达式的域 K,以及表示同一表达式为 K 元素的列表或字典。

解释

给定一组正常的 SymPy 表达式(类型为Expr),construct_domain将找到能表示这些表达式的最小Domain。表达式将被转换为域的元素,并返回域和域元素。

示例

给定Integer列表construct_domain将返回域 ZZ,以及作为 ZZ 元素的整数列表。

>>> from sympy import construct_domain, S
>>> expressions = [S(2), S(3), S(4)]
>>> K, elements = construct_domain(expressions)
>>> K
ZZ
>>> elements
[2, 3, 4]
>>> type(elements[0])  
<class 'int'>
>>> type(expressions[0])
<class 'sympy.core.numbers.Integer'> 

如果存在Rational,则返回 QQ。

>>> construct_domain([S(1)/2, S(3)/4])
(QQ, [1/2, 3/4]) 

如果存在符号,则返回一个多项式环K[x]

>>> from sympy import symbols
>>> x, y = symbols('x, y')
>>> construct_domain([2*x + 1, S(3)/4])
(QQ[x], [2*x + 1, 3/4])
>>> construct_domain([2*x + 1, y])
(ZZ[x,y], [2*x + 1, y]) 

如果任何符号具有负指数,则将返回一个有理函数域 K(x)。

>>> construct_domain([y/x, x/(1 - y)])
(ZZ(x,y), [y/x, -x/(y - 1)]) 

无理数代数会默认返回 EX 域。关键字参数extension=True会导致构造代数数域 QQ

>>> from sympy import sqrt
>>> construct_domain([sqrt(2)])
(EX, [EX(sqrt(2))])
>>> construct_domain([sqrt(2)], extension=True)  
(QQ<sqrt(2)>, [ANP([1, 0], [1, 0, -2], QQ)]) 

另请参阅

DomainExpr

单项式编码为元组

class sympy.polys.monomials.Monomial(monom, gens=None)

表示单项式的类,即幂的乘积。

as_expr(*gens)

将单项式实例转换为 SymPy 表达式。

gcd(other)

单项式的最大公因子。

lcm(other)

单项式的最小公倍数。

sympy.polys.monomials.itermonomials(variables, max_degrees, min_degrees=None)

max_degreesmin_degrees 都是整数或列表。除非另有说明,否则 min_degrees 要么是 0 要么是 [0, ..., 0]

返回所有单项式 monom 的生成器,使得 min_degree <= total_degree(monom) <= max_degree,或对于所有 imin_degrees[i] <= degree_list(monom)[i] <= max_degrees[i]

情况 I. max_degreesmin_degrees 都是整数

给定变量集合 (V) 和最小次数 (N) 以及最大次数 (M),生成次数小于等于 (N) 且大于等于 (M) 的单项式集合。在可交换变量的情况下,单项式的总数巨大,并由以下公式给出,如果 (M = 0):

[\frac{(#V + N)!}{#V! N!}]

例如,如果我们想生成一个总次数为 (N = 50),(M = 0) 的密集多项式,这是最坏的情况,在 5 个变量中,假设指数和所有系数都是 32 位长,并存储在一个数组中,我们将需要接近 80 GiB 的内存!幸运的是,我们将遇到的大多数多项式都是稀疏的。

考虑在可交换变量 (x) 和 (y) 中以及非交换变量 (a) 和 (b) 中的单项式:

>>> from sympy import symbols
>>> from sympy.polys.monomials import itermonomials
>>> from sympy.polys.orderings import monomial_key
>>> from sympy.abc import x, y

>>> sorted(itermonomials([x, y], 2), key=monomial_key('grlex', [y, x]))
[1, x, y, x**2, x*y, y**2]

>>> sorted(itermonomials([x, y], 3), key=monomial_key('grlex', [y, x]))
[1, x, y, x**2, x*y, y**2, x**3, x**2*y, x*y**2, y**3]

>>> a, b = symbols('a, b', commutative=False)
>>> set(itermonomials([a, b, x], 2))
{1, a, a**2, b, b**2, x, x**2, a*b, b*a, x*a, x*b}

>>> sorted(itermonomials([x, y], 2, 1), key=monomial_key('grlex', [y, x]))
[x, y, x**2, x*y, y**2] 

情况 II. max_degreesmin_degrees 都是列表

如果 max_degrees = [d_1, ..., d_n]min_degrees = [e_1, ..., e_n],生成的单项式数量为:

[(d_1 - e_1 + 1) (d_2 - e_2 + 1) \cdots (d_n - e_n + 1)]

让我们生成所有变量为 (x) 和 (y) 的单项式 monom,使得 [1, 2][i] <= degree_list(monom)[i] <= [2, 4][i],其中 i = 0, 1

>>> from sympy import symbols
>>> from sympy.polys.monomials import itermonomials
>>> from sympy.polys.orderings import monomial_key
>>> from sympy.abc import x, y

>>> sorted(itermonomials([x, y], [2, 4], [1, 2]), reverse=True, key=monomial_key('lex', [x, y]))
[x**2*y**4, x**2*y**3, x**2*y**2, x*y**4, x*y**3, x*y**2] 
sympy.polys.monomials.monomial_count(V, N)

计算单项式的数量。

单项式的数量由以下公式给出:

[\frac{(#V + N)!}{#V! N!}]

其中 (N) 是总次数,(V) 是变量集合。

例子

>>> from sympy.polys.monomials import itermonomials, monomial_count
>>> from sympy.polys.orderings import monomial_key
>>> from sympy.abc import x, y 
>>> monomial_count(2, 2)
6 
>>> M = list(itermonomials([x, y], 2)) 
>>> sorted(M, key=monomial_key('grlex', [y, x]))
[1, x, y, x**2, x*y, y**2]
>>> len(M)
6 

单项式的排列顺序

class sympy.polys.orderings.MonomialOrder

单项式排序的基类。

class sympy.polys.orderings.LexOrder

单项式的词典序。

class sympy.polys.orderings.GradedLexOrder

单项式的分级字典序。

class sympy.polys.orderings.ReversedGradedLexOrder

单项式的逆分级字典序。

多项式根的形式推导

sympy.polys.rootoftools.rootof(f, x, index=None, radicals=True, expand=True)

一元多项式的索引根。

返回一个 ComplexRootOf 对象或涉及根式的显式表达式。

参数:

f : 表达式

一元多项式。

x : 符号,可选

生成 f 的生成器。

index : int 或 Integer

radicals : bool

如果可能,返回一个根式表达式。

expand : bool

展开 f

class sympy.polys.rootoftools.RootOf(f, x, index=None, radicals=True, expand=True)

表示一元多项式的根。

不同类型多项式根的基类。目前仅支持复数根。

class sympy.polys.rootoftools.ComplexRootOf(f, x, index=None, radicals=False, expand=True)

表示多项式的索引复数根。

将一元多项式的根分离成不相交的实数或复数区间,并按固定顺序进行索引:

  • 实根先来,按增加顺序排序;

  • 复数根接下来,并按照增加的实部和次要地按增加的虚部排序。

目前只允许有理系数。可以导入为 CRootOf。为了避免混淆,生成器必须是一个符号。

例子

>>> from sympy import CRootOf, rootof
>>> from sympy.abc import x 

CRootOf 是引用多项式特定根的一种方式。如果有有理根,则将返回它:

>>> CRootOf.clear_cache()  # for doctest reproducibility
>>> CRootOf(x**2 - 4, 0)
-2 

是否返回涉及根式的根取决于radicals标志是否为真(在rootof中设为 True):

>>> CRootOf(x**2 - 3, 0)
CRootOf(x**2 - 3, 0)
>>> CRootOf(x**2 - 3, 0, radicals=True)
-sqrt(3)
>>> rootof(x**2 - 3, 0)
-sqrt(3) 

以下不能用根式表达:

>>> r = rootof(4*x**5 + 16*x**3 + 12*x**2 + 7, 0); r
CRootOf(4*x**5 + 16*x**3 + 12*x**2 + 7, 0) 

可见根边界,它们被评估方法用于获取根的数值近似。

>>> interval = r._get_interval(); interval
(-1, 0)
>>> r.evalf(2)
-0.98 

evalf方法会细化根的边界宽度,直到保证这些边界内的任何小数近似都满足所需的精度。然后,它会存储细化后的区间,因此在请求的精度范围内,后续请求不必重新计算根的边界,会非常快速地返回。

在上述评估之前,区间是

>>> interval
(-1, 0) 

在评估之后,现在是

>>> r._get_interval() 
(-165/169, -206/211) 

要重置给定多项式的所有区间,可以从多项式的任何 CRootOf 实例调用_reset()方法:

>>> r._reset()
>>> r._get_interval()
(-1, 0) 

eval_approx()方法也会按所需精度找到根,但除非在根边界内搜索失败以收敛,否则不会修改区间。使用弦割法找到根。(evalf方法使用二分法,并始终更新区间。)

>>> r.eval_approx(2)
-0.98 

需要稍微更新区间以找到该根:

>>> r._get_interval()
(-1, -1/2) 

evalf_rational会计算根的有理近似,以达到所需的准确度或精度。

>>> r.eval_rational(n=2)
-69629/71318 
>>> t = CRootOf(x**3 + 10*x + 1, 1)
>>> t.eval_rational(1e-1)
15/256 - 805*I/256
>>> t.eval_rational(1e-1, 1e-4)
3275/65536 - 414645*I/131072
>>> t.eval_rational(1e-4, 1e-4)
6545/131072 - 414645*I/131072
>>> t.eval_rational(n=2)
104755/2097152 - 6634255*I/2097152 

注意

虽然可以从非符号生成器 RootOf 实例构造 PurePoly,但不允许使用非符号来避免对所表示的根的混淆。

>>> from sympy import exp, PurePoly
>>> PurePoly(x) == PurePoly(exp(x))
True
>>> CRootOf(x - 1, 0)
1
>>> CRootOf(exp(x) - 1, 0)  # would correspond to x == 0
Traceback (most recent call last):
...
sympy.polys.polyerrors.PolynomialError: generator must be a Symbol 

参见

eval_approxeval_rational

classmethod _all_roots(poly, use_cache=True)

获取复合多项式的实根和复根。

classmethod _complexes_index(complexes, index)

将初始复根索引映射到根所属因子中的索引。

classmethod _complexes_sorted(complexes)

使复数隔离区间不相交并排序根。

classmethod _count_roots(roots)

计算具有重数的实根或复根的数量。

_ensure_complexes_init()

确保我们的多项式在复数缓存中有条目。

_ensure_reals_init()

确保我们的多项式在实数缓存中有条目。

_eval_evalf(prec, **kwargs)

对给定精度评估此复根。

_eval_is_imaginary()

如果根是虚数则返回True

_eval_is_real()

如果根是实数则返回True

classmethod _get_complexes(factors, use_cache=True)

为一组因子计算复数根隔离区间。

classmethod _get_complexes_sqf(currentfactor, use_cache=True)

获取一个无平方因子的复数根隔离区间。

_get_interval()

从缓存中检索隔离区间的内部函数。

classmethod _get_reals(factors, use_cache=True)

为一组因子计算实根隔离区间。

classmethod _get_reals_sqf(currentfactor, use_cache=True)

获取一个无平方因子的实根隔离区间。

classmethod _get_roots(method, poly, radicals)

返回指定类型的后处理根。

classmethod _indexed_root(poly, index, lazy=False)

按索引获取复合多项式的一个根。

classmethod _new(poly, index)

从原始数据构造新的CRootOf对象。

classmethod _postprocess_root(root, radicals)

如果根是微不足道的或者是CRootOf对象,则返回根。

classmethod _preprocess_roots(poly)

采取英雄般的措施使polyCRootOf兼容。

classmethod _real_roots(poly)

获取复合多项式的实根。

classmethod _reals_index(reals, index)

将初始实根索引映射到根所属因子的索引。

classmethod _reals_sorted(reals)

使实数隔离区间不重叠并排序根。

classmethod _refine_complexes(complexes)

返回复数,使非共轭根的包围矩形不相交。此外,确保 ay 和 by 都不为 0,以确保非实根在 y 边界上与实根有所不同。

_reset()

重置所有区间

classmethod _roots_trivial(poly, radicals)

在线性、二次和二项情况下计算根。

_set_interval(interval)

更新缓存中隔离区间的内部函数。

classmethod all_roots(poly, radicals=True)

获取多项式的实根和复根。

classmethod clear_cache()

重置实数和复数的缓存。

用于近似根实例的区间根据需要进行更新。当请求查看区间时,显示最新的值。(clear_cache)将所有CRootOf实例重置为其原始状态。

另见

_reset

eval_approx(n, return_mpmath=False)

对给定精度评估此复根。

此方法使用割线法,根边界用于生成初始猜测并检查返回的根是否有效。如果方法在根边界外收敛,边界将变小并更新。

eval_rational(dx=None, dy=None, n=15)

返回self的有理数近似,其实部和虚部近似值分别在dxdy内。或者,可以指定n位精度。

通过二分法细化区间,并确保收敛。当细化完成时更新根的边界,因此在相同或更低的精度下重新计算不需要重复细化,应该会快得多。

下面的示例首先获得 4 阶 Legendre 多项式所有根的 1e-8 精度的有理数近似。由于所有根都小于 1,这将确保近似的十进制表示(包括四舍五入)正确到 6 位小数:

>>> from sympy import legendre_poly, Symbol
>>> x = Symbol("x")
>>> p = legendre_poly(4, x, polys=True)
>>> r = p.real_roots()[-1]
>>> r.eval_rational(10**-8).n(6)
0.861136 

不必进行两步计算,然而:可以直接计算十进制表示:

>>> r.evalf(17)
0.86113631159405258 
classmethod real_roots(poly, radicals=True)

获取多项式的实根。

class sympy.polys.rootoftools.RootSum(expr, func=None, x=None, auto=True, quadratic=False)

表示一元多项式所有根的和。

classmethod new(poly, func, auto=True)

构造新的RootSum实例。

符号根查找算法

sympy.polys.polyroots.roots(f, *gens, auto=True, cubics=True, trig=False, quartics=True, quintics=False, multiple=False, filter=None, predicate=None, strict=False, **flags)

计算一元多项式的符号根。

给定具有符号系数的一元多项式 f(或多项式系数的列表),返回包含其根及其重数的字典。

只有可以用根式表达的根将被返回。要获得完整的根集,请改用 RootOf 类或数值方法。默认情况下,算法中使用三次和四次公式。要禁用它们以避免不可读的输出,请设置cubics=Falsequartics=False。如果三次根是实数但表达为复数形式(casus irreducibilis [1]),则可以将trig标志设置为 True,以便将解以余弦和反余弦函数的形式返回。

要从特定域获取根,使用filter标志并设置以下其中之一的说明符:Z,Q,R,I,C。默认情况下返回所有根(相当于设置filter='C')。

默认情况下,返回一个字典,给出多根的紧凑结果。但是,要获取包含所有这些根的列表,请将multiple标志设置为 True;该列表将在结果中相同的根旁边出现。(对于给定的 Poly,all_roots 方法将以排序的数值顺序给出根。)

如果strict标志为 True,则如果找到的根已知不完整(因为某些根无法用根式表达),将引发UnsolvableFactorError

示例

>>> from sympy import Poly, roots, degree
>>> from sympy.abc import x, y 
>>> roots(x**2 - 1, x)
{-1: 1, 1: 1} 
>>> p = Poly(x**2-1, x)
>>> roots(p)
{-1: 1, 1: 1} 
>>> p = Poly(x**2-y, x, y) 
>>> roots(Poly(p, 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} 

roots只会返回可以用根式表达的根。如果给定的多项式有部分或全部根不能用根式表达,则roots的结果将分别是不完整或空的。

结果不完整的示例:

>>> roots((x-1)*(x**5-x+1), x)
{1: 1} 

在这种情况下,多项式有一个无法解决的五次因子,其根无法用根式表达。由于总是能找到所有有理根,因此返回了一个有理根(因为因子((x-1))),该根由roots返回。

结果为空的示例:

>>> roots(x**7-3*x**2+1, x)
{} 

在这里,多项式没有可以用根式表达的根,因此roots返回一个空字典。

函数roots的结果仅当每个根的重数之和等于多项式的次数时才是完整的。如果strict=True,则如果结果不完整,将引发UnsolvableFactorError

结果可以通过以下方式检查完整性:

>>> f = x**3-2*x**2+1
>>> sum(roots(f, x).values()) == degree(f, x)
True
>>> f = (x-1)*(x**5-x+1)
>>> sum(roots(f, x).values()) == degree(f, x)
False 

参考

[R811]

en.wikipedia.org/wiki/Cubic_equation#Trigonometric_and_hyperbolic_solutions

特殊多项式

sympy.polys.specialpolys.swinnerton_dyer_poly(n, x=None, polys=False)

生成(x)的第(n)个 Swinnerton-Dyer 多项式。

参数:

n:整数

(n)决定多项式的阶数

x:可选

polys:布尔型,可选

polys=True返回一个表达式,否则(默认)返回一个表达式。

sympy.polys.specialpolys.interpolating_poly(n, x, X='x', Y='y')

构造拉格朗日插值多项式以适应n个数据点。如果为XY给出了一系列值,则将使用前n个值。

sympy.polys.specialpolys.cyclotomic_poly(n, x=None, polys=False)

生成(x)的阶为(n)的旋轮多项式。

参数:

n:整数

(n)决定多项式的阶数

x:可选

polys:布尔型,可选

polys=True返回一个表达式,否则(默认)返回一个表达式。

sympy.polys.specialpolys.symmetric_poly(n, *gens, polys=False)

生成阶为(n)的对称多项式。

参数:

polys: bool, optional (default: False)

polys=True时返回一个多项式对象,否则(默认)返回一个表达式。

sympy.polys.specialpolys.random_poly(x, n, inf, sup, domain=ZZ, polys=False)

生成一个系数在[inf, sup]内的阶数为n的多项式。

参数:

x

(x)是多项式的独立项

n:整数

(n)决定多项式的阶数

inf

系数所在范围的下限

sup

系数所在范围的上限

domain:可选

决定系数应属于哪个环。默认设置为整数。

polys:布尔型,可选

polys=True返回一个表达式,否则(默认)返回一个表达式。

正交多项式

sympy.polys.orthopolys.chebyshevt_poly(n, x=None, polys=False)

生成第一类 Chebyshev 多项式(T_n(x))。

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.chebyshevu_poly(n, x=None, polys=False)

生成第二类 Chebyshev 多项式(U_n(x))。

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.gegenbauer_poly(n, a, x=None, polys=False)

生成 Gegenbauer 多项式(C_n^{(a)}(x))。

参数:

n:整数

多项式的次数。

x:可选

a

决定系数列表的最小定义域。

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.hermite_poly(n, x=None, polys=False)

生成 Hermite 多项式(H_n(x))。

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.hermite_prob_poly(n, x=None, polys=False)

生成概率论的 Hermite 多项式(He_n(x))。

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.jacobi_poly(n, a, b, x=None, polys=False)

生成 Jacobi 多项式(P_n^{(a,b)}(x))。

参数:

n:整数

多项式的次数。

a

系数列表的最小定义域的下限。

b

系数列表的最小定义域的上限。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.legendre_poly(n, x=None, polys=False)

生成 Legendre 多项式(P_n(x))。

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.laguerre_poly(n, x=None, alpha=0, polys=False)

生成 Laguerre 多项式(L_n^{(\alpha)}(x))。

参数:

n:整数

多项式的次数。

x:可选

alpha:可选

决定系数列表的最小定义域。

polys:布尔型,可选

如果为真,返回一个多项式,否则(默认)返回一个表达式。

sympy.polys.orthopolys.spherical_bessel_fn(n, x=None, polys=False)

球形贝塞尔函数的系数。

仅在 jn()函数中需要这些。

系数由以下计算:

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)

参数:

n:整数

多项式的次数。

x:可选

polys:布尔型,可选

如果为真,则返回一个 Poly,否则(默认)返回一个表达式。

示例

>>> from sympy.polys.orthopolys import spherical_bessel_fn as fn
>>> from sympy import Symbol
>>> z = Symbol("z")
>>> fn(1, z)
z**(-2)
>>> fn(2, z)
-1/z + 3/z**3
>>> fn(3, z)
-6/z**2 + 15/z**4
>>> fn(4, z)
1/z - 45/z**3 + 105/z**5 

Appell 序列

sympy.polys.appellseqs.bernoulli_poly(n, x=None, polys=False)

生成伯努利多项式 (\operatorname{B}_n(x))。

(\operatorname{B}_n(x))是满足以下唯一性质的多项式:

[\int_{x}^{x+1} \operatorname{B}_n(t) ,dt = x^n.]

基于此,我们对非负整数(s)和整数(a)和(b)有:

[\sum_{k=a}^{b} k^s = \frac{\operatorname{B}{s+1}(b+1) - \operatorname{B}(a)}{s+1}]

这与 Jakob Bernoulli 引入伯努利数的最初动机有关,这些多项式在(x = 1)处的值。

参数:

n : 整数

多项式的次数。

x : 可选

polys : 布尔值,可选

如果为真,则返回一个 Poly,否则(默认)返回一个表达式。

示例

>>> from sympy import summation
>>> from sympy.abc import x
>>> from sympy.polys import bernoulli_poly
>>> bernoulli_poly(5, x)
x**5 - 5*x**4/2 + 5*x**3/3 - x/6 
>>> def psum(p, a, b):
...     return (bernoulli_poly(p+1,b+1) - bernoulli_poly(p+1,a)) / (p+1)
>>> psum(4, -6, 27)
3144337
>>> summation(x**4, (x, -6, 27))
3144337 
>>> psum(1, 1, x).factor()
x*(x + 1)/2
>>> psum(2, 1, x).factor()
x*(x + 1)*(2*x + 1)/6
>>> psum(3, 1, x).factor()
x**2*(x + 1)**2/4 

参见

sympy.functions.combinatorial.numbers.bernoulli

参考文献

[R812]

en.wikipedia.org/wiki/Bernoulli_polynomials

sympy.polys.appellseqs.bernoulli_c_poly(n, x=None, polys=False)

生成中心伯努利多项式 (\operatorname{B}_n^c(x))。

这些是普通伯努利多项式的缩放和平移版本,以便(\operatorname{B}_n^c(x))分别为偶函数或奇函数,对应于偶数或奇数的(n):

[\operatorname{B}_n^c(x) = 2^n \operatorname{B}_n \left(\frac{x+1}{2}\right)]

参数:

n : 整数

多项式的次数。

x : 可选

polys : 布尔值,可选

如果为真,则返回一个 Poly,否则(默认)返回一个表达式。

sympy.polys.appellseqs.genocchi_poly(n, x=None, polys=False)

生成 Genocchi 多项式 (\operatorname{G}_n(x))。

(\operatorname{G}_n(x))是普通和中心伯努利多项式之差的两倍,因此次数为(n-1):

[\operatorname{G}_n(x) = 2 (\operatorname{B}_n(x) - \operatorname{B}_n^c(x))]

定义中的因子 2 赋予(\operatorname{G}_n(x))整数系数。

参数:

n : 整数

多项式的次数加一。

x : 可选

polys : 布尔值,可选

如果为真,则返回一个 Poly,否则(默认)返回一个表达式。

参见

sympy.functions.combinatorial.numbers.genocchi

sympy.polys.appellseqs.euler_poly(n, x=None, polys=False)

生成 Euler 多项式 (\operatorname{E}_n(x))。

这些是 Genocchi 多项式的缩放和重新索引版本:

[\operatorname{E}n(x) = -\frac{\operatorname{G}(x)}{n+1}]

参数:

n : 整数

多项式的次数。

x : 可选

polys : 布尔值,可选

如果为真,则返回一个 Poly,否则(默认)返回一个表达式。

参见

sympy.functions.combinatorial.numbers.euler

sympy.polys.appellseqs.andre_poly(n, x=None, polys=False)

生成 Andre 多项式 (\mathcal{A}_n(x))。

这是 Appell 序列,其中常数系数形成欧拉数序列euler(n)。因此它们具有整数系数,并且与( n )的奇偶性匹配。

Luschny 称之为瑞士军刀多项式,因为它们在 0 和 1 处的值可以简单地转化为伯努利数和欧拉数。在这里它们被称为 Andre 多项式,因为对于( n \ge 0 ),( |\mathcal{A}_n(n\bmod 2)| )生成了 Luschny 所称的Andre 数,在 OEIS 中是 A000111。

参数:

n : int

多项式的次数。

x : optional

polys : bool, optional

如果为 True,则返回 Poly,否则(默认)返回一个表达式。

示例

>>> from sympy import bernoulli, euler, genocchi
>>> from sympy.abc import x
>>> from sympy.polys import andre_poly
>>> andre_poly(9, x)
x**9 - 36*x**7 + 630*x**5 - 5124*x**3 + 12465*x 
>>> [andre_poly(n, 0) for n in range(11)]
[1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521]
>>> [euler(n) for n in range(11)]
[1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521]
>>> [andre_poly(n-1, 1) * n / (4**n - 2**n) for n in range(1, 11)]
[1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0, 5/66]
>>> [bernoulli(n) for n in range(1, 11)]
[1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0, 5/66]
>>> [-andre_poly(n-1, -1) * n / (-2)**(n-1) for n in range(1, 11)]
[-1, -1, 0, 1, 0, -3, 0, 17, 0, -155]
>>> [genocchi(n) for n in range(1, 11)]
[-1, -1, 0, 1, 0, -3, 0, 17, 0, -155] 
>>> [abs(andre_poly(n, n%2)) for n in range(11)]
[1, 1, 1, 2, 5, 16, 61, 272, 1385, 7936, 50521] 

另见

sympy.functions.combinatorial.numbers.andre

参考

[R813]

Peter Luschny,“伯努利函数简介”,arxiv.org/abs/2009.06743

操作有理函数

sympy.polys.rationaltools.together(expr, deep=False, fraction=True)

使用符号方法去除并组合有理表达式。

此函数接受表达式或表达式容器,并通过去除嵌套和组合有理子表达式将其放在一起。不会采取英雄般的措施来最小化生成的分子和分母的次数。要获取完全简化的表达式,请使用cancel()。然而,together()可以尽可能地保留输入表达式的结构(不会执行扩展)。

可以组合多种对象,包括列表、元组、集合、关系对象、积分等。还可以通过将deep标志设置为True来转换函数应用的内部。

根据定义,together()apart()的补充,因此apart(together(expr))应该返回未改变的表达式。然而,请注意,together()仅使用符号方法,因此可能需要使用cancel()进行代数化简并最小化分子和分母的次数。

示例

>>> from sympy import together, exp
>>> from sympy.abc import x, y, z 
>>> 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))
exp(1/y + 1/x)
>>> together(exp(1/x + 1/y), deep=True)
exp((x + y)/(x*y)) 
>>> together(1/exp(x) + 1/(x*exp(x)))
(x + 1)*exp(-x)/x 
>>> together(1/exp(2*x) + 1/(x*exp(3*x)))
(x*exp(x) + 1)*exp(-3*x)/x 

部分分解

sympy.polys.partfrac.apart(f, x=None, full=False, **options)

计算有理函数的部分分解。

给定有理函数f,计算f的部分分解。有两种算法可用:一种基于未知系数方法,另一种是 Bronstein 的完全部分分解算法。

使用未知系数法(通过 full=False 选择)使用多项式因式分解(因此接受与因子相同的选项)用于分母。默认情况下它在有理数上工作,因此不支持具有非有理根(例如无理数,复根)的分母的分解(参见因子的选项)。

通过使用 full=True 可选择 Bronstein 算法,并允许分解具有非有理根的分母。可以通过 doit() 获得一个易于理解的结果(见下面的示例)。

示例

>>> from sympy.polys.partfrac import apart
>>> from sympy.abc import x, y 

默认情况下,使用待定系数法:

>>> apart(y/(x + 2)/(x + 1), x)
-y/(x + 2) + y/(x + 1) 

当分母的根不是有理数时,待定系数法不会给出结果:

>>> apart(y/(x**2 + x + 1), x)
y/(x**2 + x + 1) 

通过设置 full=True 可选择 Bronstein 的算法:

>>> apart(y/(x**2 + x + 1), x, full=True)
RootSum(_w**2 + _w + 1, Lambda(_a, (-2*_a*y/3 - y/3)/(-_a + x))) 

调用 doit() 会产生一个易于理解的结果:

>>> 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) 

参见

apart_list, assemble_partfrac_list

sympy.polys.partfrac.apart_list(f, x=None, dummies=None, **options)

计算有理函数的部分分解,并以结构化形式返回结果。

给定有理函数 f,计算 f 的部分分解。此方法仅支持 Bronstein 的完全部分分解算法。返回值结构化且非常适合进一步的算法处理,而不是易于理解的人类阅读。函数返回一个包含三个元素的元组:

  • 第一项是通用系数,不涉及用于分解的变量 (x)。(它是基础域 (K) 的元素。)

  • 第二项是分解的多项式部分。这可以是零多项式。(它是 (K[x]) 的元素。)

  • 第三部分本身是一个四元组列表。每个四元组按照以下顺序具有以下元素:

    • 多个相关分式项的线性分母中出现的根 (w_i) 的多项式 (D)(不一定是不可约的)。(该项也可以是显式根的列表。然而,目前 apart_list 从未以这种方式返回结果,但相关的 assemble_partfrac_list 函数接受此格式作为输入。)

    • 分数的分子,写成关于根 (w) 的函数

    • 分数的线性分母 不包括其幂指数,写成根 (w) 的函数。

    • 分母必须提升的幂。

可以始终通过使用函数 assemble_partfrac_list 重建简单表达式。

示例

第一个例子:

>>> from sympy.polys.partfrac import apart_list, assemble_partfrac_list
>>> from sympy.abc import x, t 
>>> 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, -_a + x), 1)]) 
>>> assemble_partfrac_list(pfd)
2*x + 4 + 4/(x - 1) 

第二个例子:

>>> 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, -_a + x), 1)]) 
>>> assemble_partfrac_list(pfd)
-2/3 - 2/(x - 2) 

另一个例子,展示符号参数:

>>> 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*_a*t/(4*t - 1) - t/(4*t - 1)),
Lambda(_a, -_a + x),
1)]) 
>>> assemble_partfrac_list(pfd)
RootSum(_w**2 + _w + t, Lambda(_a, (-2*_a*t/(4*t - 1) - t/(4*t - 1))/(-_a + x))) 

此示例摘自 Bronstein 的原始论文:

>>> 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, -_a + x), 1),
(Poly(_w**2 - 1, _w, domain='ZZ'), Lambda(_a, -3*_a - 6), Lambda(_a, -_a + x), 2),
(Poly(_w + 1, _w, domain='ZZ'), Lambda(_a, -4), Lambda(_a, -_a + x), 1)]) 
>>> assemble_partfrac_list(pfd)
-4/(x + 1) - 3/(x + 1)**2 - 9/(x - 1)**2 + 4/(x - 2) 

参见

apart, assemble_partfrac_list

参考文献

[R814]

[Bronstein93]

sympy.polys.partfrac.assemble_partfrac_list(partial_list)

通过函数 apart_list 获得的结构化结果重新组装完整的部分分数分解。

示例

此示例取自 Bronstein 的原始论文:

>>> from sympy.polys.partfrac import apart_list, assemble_partfrac_list
>>> from sympy.abc import x 
>>> 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, -_a + x), 1),
(Poly(_w**2 - 1, _w, domain='ZZ'), Lambda(_a, -3*_a - 6), Lambda(_a, -_a + x), 2),
(Poly(_w + 1, _w, domain='ZZ'), Lambda(_a, -4), Lambda(_a, -_a + x), 1)]) 
>>> assemble_partfrac_list(pfd)
-4/(x + 1) - 3/(x + 1)**2 - 9/(x - 1)**2 + 4/(x - 2) 

如果我们恰好知道一些根,则可以轻松地在结构内提供它们:

>>> 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, -_a + x),
1)]) 
>>> pfda = assemble_partfrac_list(pfd)
>>> pfda
RootSum(_w**2 - 2, Lambda(_a, _a/(-_a + x)))/2 
>>> pfda.doit()
-sqrt(2)/(2*(x + sqrt(2))) + sqrt(2)/(2*(x - sqrt(2))) 
>>> from sympy import Dummy, Poly, Lambda, sqrt
>>> a = Dummy("a")
>>> pfd = (1, Poly(0, x, domain='ZZ'), [([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))) 

参见

apart, apart_list

多项式的分散

sympy.polys.dispersion.dispersionset(p, q=None, *gens, **args)

计算两个多项式的分散集

对于两个多项式 (f(x)) 和 (g(x)),其中 (\deg f > 0) 和 (\deg g > 0),分散集 (\operatorname{J}(f, g)) 定义如下:

[\begin{split}\operatorname{J}(f, g) & := {a \in \mathbb{N}_0 | \gcd(f(x), g(x+a)) \neq 1} \ & = {a \in \mathbb{N}_0 | \deg \gcd(f(x), g(x+a)) \geq 1}\end{split}]

对于单个多项式,定义为 (\operatorname{J}(f) := \operatorname{J}(f, f))。

示例

>>> from sympy import poly
>>> from sympy.polys.dispersion import dispersion, dispersionset
>>> from sympy.abc import x 

简单多项式的分散集和分散度:

>>> fp = poly((x - 3)*(x + 3), x)
>>> sorted(dispersionset(fp))
[0, 6]
>>> dispersion(fp)
6 

请注意分散的定义不对称:

>>> fp = poly(x**4 - 3*x**2 + 1, x)
>>> gp = fp.shift(-3)
>>> sorted(dispersionset(fp, gp))
[2, 3, 4]
>>> dispersion(fp, gp)
4
>>> sorted(dispersionset(gp, fp))
[]
>>> dispersion(gp, fp)
-oo 

分散计算也适用于域扩展:

>>> from sympy import sqrt
>>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
>>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
>>> sorted(dispersionset(fp, gp))
[2]
>>> sorted(dispersionset(gp, fp))
[1, 4] 

我们甚至可以为具有符号系数的多项式执行计算:

>>> from sympy.abc import a
>>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
>>> sorted(dispersionset(fp))
[0, 1] 

参见

dispersion

参考文献

[R815]

[ManWright94]

[R816]

[Koepf98]

[R817]

[Abramov71]

[R818]

[Man93]

sympy.polys.dispersion.dispersion(p, q=None, *gens, **args)

计算多项式的分散

对于两个多项式 (f(x)) 和 (g(x)),其中 (\deg f > 0) 和 (\deg g > 0),分散 (\operatorname{dis}(f, g)) 定义如下:

[\begin{split}\operatorname{dis}(f, g) & := \max{ J(f,g) \cup {0} } \ & = \max{ {a \in \mathbb{N} | \gcd(f(x), g(x+a)) \neq 1} \cup {0} }\end{split}]

对于单个多项式 (\operatorname{dis}(f) := \operatorname{dis}(f, f)),请注意我们定义 (\max{} := -\infty)。

示例

>>> from sympy import poly
>>> from sympy.polys.dispersion import dispersion, dispersionset
>>> from sympy.abc import x 

简单多项式的分散集和分散度:

>>> fp = poly((x - 3)*(x + 3), x)
>>> sorted(dispersionset(fp))
[0, 6]
>>> dispersion(fp)
6 

请注意分散的定义不对称:

>>> fp = poly(x**4 - 3*x**2 + 1, x)
>>> gp = fp.shift(-3)
>>> sorted(dispersionset(fp, gp))
[2, 3, 4]
>>> dispersion(fp, gp)
4
>>> sorted(dispersionset(gp, fp))
[]
>>> dispersion(gp, fp)
-oo 

空集的最大值定义为 (-\infty),如本例所示。

分散计算也适用于域扩展:

>>> from sympy import sqrt
>>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
>>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
>>> sorted(dispersionset(fp, gp))
[2]
>>> sorted(dispersionset(gp, fp))
[1, 4] 

我们甚至可以为具有符号系数的多项式执行计算:

>>> from sympy.abc import a
>>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
>>> sorted(dispersionset(fp))
[0, 1] 

参见

dispersionset

参考文献

[R819]

[ManWright94]

[R820]

[Koepf98]

[R821]

[Abramov71]

[R822]

[Man93]

posted @ 2024-06-27 17:15  绝不原创的飞龙  阅读(49)  评论(0编辑  收藏  举报