SymPy 多项式操作模块(sympy.polys)API 参考全指南
【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy
SymPy 是一个用纯 Python 编写的符号计算系统,其中sympy.polys模块是其多项式计算的核心引擎。本文以仓库内 doc/src/modules/polys/reference.rst 这份官方 API 参考文档为骨架,系统梳理该模块公开的完整接口清单(从基本多项式操作、因式分解、求根,到正交多项式、部分分式分解与格罗布纳基),并结合 sympy/polys 目录下的源码实现与测试用例,说明每个函数族的设计意图、调用方式与底层原理。读完本文,你将能够按图索骥地在自己的数学计算或算法研究任务中,精准选用 SymPy 多项式工具链,并理解其内部如何组织多项式环、域与各种计算算法。
文档定位:Polynomials Manipulation Module Reference 是什么
reference.rst是 polys 模块的API 索引型文档:它通过 Sphinx 的automodule、autofunction、autoclass指令,把sympy.polys及其子模块中所有公开函数与类的 docstring 自动渲染成手册页面。它不重复讲解入门概念,而是为读者提供一份按功能分区的完整清单。
文档开头即说明:
- 完整文档索引见 doc/src/modules/polys/index.rst(
polys-docs引用目标); - 入门级解释见 doc/src/modules/polys/basics.rst(
polys-basics引用目标)。
basics.rst给出了最基本的概念框架:给定一族生成元x_i,由反复加法、减法、乘法得到的表达式称为多项式表达式;乘积x_1^ν1 x_2^ν2 … x_n^νn称为单项式;合并同类项后得到带系数c_ν的项。多项式在 SymPy 中默认以"单项式字典"形式存储,也可用嵌套系数列表实现。系数所属的环称为domain(域),默认由系数自动推断(例如整数系数得到ZZ,含分数得到QQ)。
而reference.rst则把这些抽象概念落到具体 API 上,分成了 14 个功能分区,下文逐一展开。
基本多项式操作函数:sympy.polys.polytools
这是整个模块使用频率最高的一层,全部位于 sympy/polys/polytools.py,对外通过sympy.polys顶层命名空间导出。
多项式的构造与查询
| 函数 | 用途 |
|---|---|
poly(expr, *gens, **args) | 将表达式高效转换为Poly对象 |
poly_from_expr | 从表达式构造(Poly, 生成元)二元组 |
parallel_poly_from_expr | 同时将一组表达式构造为 Poly(共享同一生成元/域选项) |
degree(f, gen=0) | 某生成元的度数 |
degree_list(f, *gens, **args) | 各生成元度数构成的元组 |
LC / LM / LT | 首项系数(Leading Coefficient)/ 首项单项式 / 首项 |
terms_gcd | 提取所有项公共的单项式因子 |
poly()的源码(polytools.py 中def poly,约第 8232 行)展示了它的"高效"原理:它不是机械地展开整个表达式,而是递归遍历表达式树——对每个加法项,把其中可多项式化的因子(如Add、非负整数指数的Pow)先转成 Poly 再做乘法,避免中间表达式的二次展开开销。例如:
>>> 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')Poly构造时支持的选项在 sympy/polys/polyoptions.py 中统一解析,常见的有domain、modulus、extension、order、field等,测试覆盖见 sympy/polys/tests/test_polyoptions.py。
带余除法与伪除法
| 函数 | 含义 |
|---|---|
div / rem / quo / exquo | 域上的带余除法:商、余式、(伪)商、(精确)商 |
pdiv / prem / pquo / pexquo | 环上的伪除法(pseudo-division),适用于系数不是域的环(如ZZ) |
half_gcdex / gcdex_steps / gcdex | 扩展欧几里得算法;gcdex_steps返回迭代器,逐轮给出中间三元组(s, t, r) |
invert | 模多项式求逆,即求s使s*f ≡ 1 (mod g) |
subresultants | 子结式序列 |
resultant / discriminant | 结式与判别式 |
cofactors / gcd / gcd_list / lcm / lcm_list | 最大公因式(含cofactors返回(gcd, f/gcd, g/gcd))、最小公倍式 |
底层实现位于 sympy/polys/densearith.py(稠密多项式算术,如dup_div、dmp_div、dup_pdiv等)、sympy/polys/euclidtools.py(dup_gcdex、dup_resultant、dup_gcd等)与 sympy/polys/modulargcd.py(模 GCD 算法)。GCD 计算在整数环上会尝试启发式算法(sympy/polys/heuristicgcd.py),多变量情形还支持 Zippel 稀疏插值算法(sympy/polys/zippel.py)。
规范化与分解
| 函数 | 含义 |
|---|---|
trunc | 系数按模p截断 |
monic / content / primitive | 首一化 / 内容(系数的 gcd)/ 本原部分 |
compose / decompose | 复合f(g(x))/ 函数分解(找出f = g∘h的非平凡分解) |
sturm | 生成 Sturm 序列(用于实根隔离) |
gff_list / gff | Greatest Factored Factor(最大分解因式) |
sqf_norm / sqf_part / sqf_list / sqf | 平方自由分解(square-free factorization) |
factor_list / factor | 因式分解(返回(系数, [(因子, 重数), ...])或合并后的表达式) |
factor()的源码(polytools.pydef factor,约第 6999 行)区分两种模式:符号模式(f不是Poly且未指定生成元时)会遍历表达式树、不预展开地分解各组件,因而能处理2**(x**2 + 2*x + 1)这种大指数表达式;形式模式则对Add节点做正式分解。默认在有理数域上分解,可通过extension=sqrt(2)、modulus=2、gaussian=True或domain=切换数域,例如:
>>> from sympy import factor, sqrt >>> 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, modulus=2) (x + 1)**2 >>> factor(x**2 - 2, extension=sqrt(2)) (x - sqrt(2))*(x + sqrt(2))整数环上的分解由 sympy/polys/factortools.py 实现(Zassenhaus 算法 + Hensel 提升、Wang 的多变量提升、分圆因子检测等),有限域上的分解则依赖 sympy/polys/galoistools.py(Berlekamp / Cantor-Zassenhaus / Shoup 算法)。
根的计算
| 函数 | 含义 |
|---|---|
intervals | 用有理区间隔离实根(all=True时同时隔离复根) |
refine_root | 细化已知的根隔离区间到指定精度 |
count_roots | 计算给定区间内的实根(或矩形内的复根)个数 |
all_roots / real_roots | 返回全部(实)根;multiple参数控制是否返回重根列表 |
nroots | 数值求根(默认 15 位精度,maxsteps=50,cleanup清理伪根) |
ground_roots | 仅返回属于基域(系数域)的根 |
nth_power_roots_poly | 构造各根的n次幂对应多项式 |
根隔离算法在 sympy/polys/rootisolation.py 中实现(Sturm 序列、Cauchy 界、Möbius 变换细化等),测试见 sympy/polys/tests/test_rootisolation.py。
有理函数化简与理想
| 函数 | 含义 |
|---|---|
cancel | 约分有理函数,返回(分子, 分母)或合并后的表达式 |
reduced | 计算多项式f对多项式组G的约化余式(余式, 商列表) |
groebner | 计算多项式理想⟨F⟩的格罗布纳基(默认lex序) |
is_zero_dimensional | 判断理想是否是零维的 |
groebner的底层实现见 sympy/polys/groebnertools.py:包含经典 Buchberger 算法与 F5B 算法(_f5b),并支持通过 sympy/polys/fglmtools.py 做 FGLM 换序。测试用例覆盖在 sympy/polys/tests/test_polytools.py 的test_groebner、test_fglm、test_is_zero_dimensional等函数中。
三个核心类:Poly、PurePoly、GroebnerBasis
Poly:带生成元与域信息的正规多项式对象,支持与表达式混合运算(add、mul、div、pow及 Python 运算符重载),可查询degree、LC/LM/LT、coeffs/monoms/terms,并可做diff、integrate、eval、subs、as_expr等操作。PurePoly:Poly的子类,不区分符号对象本身,只按生成元位置区分变量,因此两个生成元符号不同的PurePoly在代数上完全相等,适用于抽象代数场景(如重命名变量不改变对象身份)。GroebnerBasis:格罗布纳基对象,封装了基本身、生成元、域与序信息,提供reduce、contains、fglm(FGLM 换序)、is_zero_dimensional等方法;__getitem__按序号取基元素,__len__给出基的大小。
额外多项式操作:sympy.polys.polyfuncs
该模块收录了 sympy/polys/polyfuncs.py 中的四个高层工具函数:
symmetrize(F, *gens, **args):把多项式改写成初等对称多项式的组合,返回(对称部分, 非对称部分),formal=True时用占位符s1, s2, …表达并返回替换表。例如symmetrize(x**2 + y**2)返回(-2*x*y + (x + y)**2, 0)。horner(f, *gens, **args):将多项式改写为Horner 形式(嵌套乘法),可显著优化求值效率;wrt参数指定按哪个生成元优先提取。源码(polyfuncs.pydef horner)通过poly_from_expr取得系数后循环执行form = form*gen + coeff。interpolate(data, x):构造插值多项式。data可以是列表(默认与1..n配对)、坐标元组列表或字典;支持符号坐标与直接数值求值。内部调用 sympy/polys/specialpolys.py 的interpolating_poly。viete(f, roots=None, *gens, **args):生成Vieta 公式(根与系数的关系式列表),例如对a*x**2 + b*x + c与根[r1, r2]返回[(r1 + r2, -b/a), (r1*r2, c/a)]。要求一元多项式且次数 ≥ 1,否则抛出ValueError。
测试见 sympy/polys/tests/test_polyfuncs.py。
域构造器:sympy.polys.constructor
construct_domain(obj, **args)位于 sympy/polys/constructor.py(def construct_domain,约第 268 行),其作用是:给定一组 SymPy 表达式,自动构造一个能表示它们的最小Domain,并把表达式转换为该域的元素。返回值是(K, elements),其中K是域对象,elements是对应的域元素(保持与输入相同形状)。
>>> from sympy import construct_domain, S >>> K, elements = construct_domain([S(2), S(3), S(4)]) >>> K ZZ >>> elements [2, 3, 4]该函数是Poly与groebner等高层接口自动推断系数域(domain='ZZ'/'QQ'/ 代数扩张等)的底层依赖,其实现通过 sympy/polys/domains 目录下的域类体系完成;相关测试见 sympy/polys/tests/test_constructor.py。
单项式与单项式序:monomials与orderings
单项式编码为元组:sympy.polys.monomials
SymPy 内部把单项式x_1^ν1 x_2^ν2 … x_n^νn编码为指数元组(ν1, ν2, …, νn)(sympy/polys/monomials.py):
Monomial:单项式包装类,提供mul、pow、div、gcd、lcm、as_expr等运算;itermonomials(variables, max_degrees, min_degrees=None):迭代生成指定度数范围内的全部单项式;monomial_count(V, N):计算V个变量中全次数不超过N的单项式个数(组合计数)。
此外该模块还提供monomial_mul/div/gcd/lcm/pow等底层函数,测试见 sympy/polys/tests/test_monomials.py。
单项式序:sympy.polys.orderings
多项式环上的计算(如格罗布纳基)依赖单项式之间的序(sympy/polys/orderings.py):
LexOrder:字典序(lex);GradedLexOrder:分级字典序(grlex,先比全次数再按字典序);ReversedGradedLexOrder:分级反字典序(grevlex);MonomialOrder:序对象的公共基类,实现了__call__(比较元组)、__repr__、is_global等接口。
monomial_key(order, gens)工厂函数把字符串或符号形式的序规格解析为可调用对象,也支持ProductOrder、InverseOrder等组合序。测试见 sympy/polys/tests/test_orderings.py。
根的形式化操作与符号求根
形式化表示根:sympy.polys.rootoftools
当多项式不可用根式求解时,SymPy 提供了根的符号占位对象(sympy/polys/rootoftools.py):
rootof(f, x, index, radicals=True, expand=True):返回多项式的第index个根(按数值序编号),如rootof(x**5 - x + 1, 0);RootOf:代数数根类,real_roots/all_roots类方法返回全部根;每个根内部通过隔离区间(sympy/polys/rootisolation.py 的RootOfInterval/ComplexRootOfInterval)精确定义,可用evalf/eval_rational求任意精度近似;ComplexRootOf:复根类,自动识别实根与虚根性质(_eval_is_real、_eval_is_imaginary);RootSum(expr, func):对多项式的所有根求和Σ func(r),支持有理函数化简(_rational_case)与doit()展开。
测试见 sympy/polys/tests/test_rootoftools.py。
符号求根算法: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)(sympy/polys/polyroots.pydef roots,约第 880 行)只返回能用根式表达(radicals)的根,返回{根: 重数}字典;multiple=True时改为返回按数值序排列的根列表。
其关键行为与源码 docstring 一致:
- 默认启用三次(
cubics)与四次(quartics)公式;casus irreducibilis 情形可用trig=True得到三角函数形式; filter='Z'/'Q'/'R'/'I'/'C'限定根所在数域,默认等价于'C';- 结果可能不完整:若多项式含根式不可解因子(如五次以上不可解因子),未找到的根不会出现在结果中,此时可检查
sum(roots(f, x).values()) == degree(f, x)是否成立;strict=True时直接抛出UnsolvableFactorError;
>>> from sympy import roots, degree >>> from sympy.abc import x >>> roots(x**2 - 1, x) {-1: 1, 1: 1} >>> roots((x-1)*(x**5-x+1), x) # 五次因子不可根式求解,结果不完整 {1: 1} >>> roots(x**7-3*x**2+1, x) # 完全不可根式求解 {}模块内还包含roots_linear、roots_quadratic、roots_cubic、roots_quartic、roots_binomial、roots_cyclotomic、roots_quintic等各次求解器,以及root_factors(生成线性/不可约因子)。
特殊多项式:sympy.polys.specialpolys
sympy/polys/specialpolys.py 提供构造特定用途多项式的工具:
swinnerton_dyer_poly(n, x=None, polys=False):构造 Swinnerton-Dyer 多项式(在整数上不可约、但在每个有限域上可约的经典反例族);interpolating_poly(n, x, X='x', Y='y'):生成通过给定点列的插值多项式;cyclotomic_poly(n, x=None, polys=False):第n个分圆多项式;symmetric_poly(n, *gens, polys=False):n次初等对称多项式;random_poly(x, n, inf, sup, domain=ZZ, polys=False):在[inf, sup]区间随机生成n次多项式。
此外还提供 Fateman 多项式(fateman_poly_F_1/2/3)等用于算法基准测试的构造;测试见 sympy/polys/tests/test_specialpolys.py。
正交多项式:sympy.polys.orthopolys
sympy/polys/orthopolys.py 实现经典正交多项式族,均以(n, x=None, polys=False)形式调用(polys=True时返回Poly):
chebyshevt_poly/chebyshevu_poly:第一类 / 第二类 Chebyshev 多项式(内部dup_chebyshevt提供递归与乘积两种实现);gegenbauer_poly(n, a, x):Gegenbauer(超球)多项式;hermite_poly/hermite_prob_poly:物理学家型 / 概率论型 Hermite 多项式;jacobi_poly(n, a, b, x):Jacobi 多项式;legendre_poly:Legendre 多项式;laguerre_poly(n, x, alpha=0):Laguerre 多项式(alpha为广义参数);spherical_bessel_fn(n, x):球 Bessel 函数fn(x)的(实 / 虚)多项式系数序列。
每个函数都有对应的稠密系数构造器(如dup_legendre(n, K)),测试见 sympy/polys/tests/test_orthopolys.py。
Appell 序列:sympy.polys.appellseqs
sympy/polys/appellseqs.py 提供满足P'(x) = n·P_{n-1}(x)性质的 Appell 多项式序列:
bernoulli_poly(n, x=None, polys=False):Bernoulli 多项式;bernoulli_c_poly:centered Bernoulli 多项式;genocchi_poly:Genocchi 多项式;euler_poly:Euler 多项式;andre_poly:André 多项式。
测试见 sympy/polys/tests/test_appellseqs.py。
有理函数的操作:together与部分分式分解
together(expr, deep=False, fraction=True):sympy.polys.rationaltools
sympy/polys/rationaltools.py 的together把表达式中的有理函数合并为单一分式(通分),deep=True时递归处理子表达式,fraction=False时不做分式化简。测试见 sympy/polys/tests/test_rationaltools.py。
apart与部分分式分解:sympy.polys.partfrac
sympy/polys/partfrac.py 提供对有理函数做部分分式分解(partial fraction decomposition)的完整接口:
apart(f, x=None, full=False, **options):默认(full=False)使用待定系数法,需要对分母做因式分解,因此默认在有理数域上工作,分母含无理/复根时不做分解;full=True时改用Bronstein 的完整分解算法,可处理非有理根,结果以RootSum形式表达,再调用.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) >>> apart(y/(x**2 + x + 1), x, full=True) RootSum(w**2 + w + 1, Lambda(w, (-2*w*y/3 - y/3)/(-w + x)))apart_list(f, x=None, dummies=None, **options):返回分解结果的结构化列表(使用占位符号表示各分式项),可编程处理;assemble_partfrac_list(partial_list):把apart_list的结构化结果重组为表达式。
测试见 sympy/polys/tests/test_partfrac.py,覆盖矩阵分解、符号参数、代数扩张与full模式等场景。
多项式分散度:sympy.polys.dispersion
sympy/polys/dispersion.py 定义两个函数:
dispersionset(p, q=None, *gens, **args):返回集合{deg(p(x+a)) - deg(p(x)) : a ∈ ℤ, gcd(p(x+a), q(x)) ≠ 1},即两个多项式的分散度集合;dispersion(p, q=None, *gens, **args):返回分散度集合的最大值;q缺省时取q = p。
该概念用于分解算法与符号积分研究,Poly对象上也提供同名方法(Poly.dispersionset/Poly.dispersion,见 sympy/polys/polytools.py);测试见 sympy/polys/tests/test_dispersion.py。
类型注解:collections.abc.Iterator
reference.rst最后用py:class记录了collections.abc.Iterator,对应gcdex_steps等返回惰性迭代器的接口:这些函数不一次性生成全部中间结果,而是按需产出(详见 sympy/polys/polytools.py 中gcdex_steps的类型重载签名),适合处理长序列扩展欧几里得过程的内存友好场景。
如何继续深入
- 入门与概念:先读 doc/src/modules/polys/basics.rst,了解多项式环、域与表达式到
Poly的转换; - 完整索引:所有 polys 相关文档入口见 doc/src/modules/polys/index.rst;
- 域系统:
domains与domainmatrix的参考在 doc/src/modules/polys/domainsref.rst 与 doc/src/modules/polys/domainmatrix.rst; - 源码:高层接口集中在 sympy/polys/polytools.py,算法实现散布在
densearith、euclidtools、factortools、galoistools、modulargcd、zippel、rootisolation、groebnertools等文件中,配套测试位于 sympy/polys/tests 目录,可作为每个 API 行为的最直接验证依据。
总结而言,reference.rst是通往 SymPy 多项式世界的地图:从poly/factor/roots这些日常函数,到RootOf、GroebnerBasis、construct_domain这些底层机制,再到正交多项式、Appell 序列与分散度等专门工具,每个接口都能在其对应源码与测试文件中找到可验证的精确行为。掌握这张地图,你就能在 SymPy 的多项式能力上做到"查得到、调得对、知其所以然"。
【免费下载链接】sympyA computer algebra system written in pure Python项目地址: https://gitcode.com/GitHub_Trending/sy/sympy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考