PAYATHON 2026

SymPy 的 random_poly 为什么没有显示 GF(2) 系数域?

数据小陈

结论

调用 random_poly 时加上 polys=True,返回的就是系数域为 GF(2) 的 Poly 对象。默认返回的是普通 SymPy 表达式,不会显示 modulus=2;这并不说明 domain=GF(2) 没有生效。

为什么输出看起来像 ZZ 上的多项式?

random_poly 先按指定的 domain 构造多项式,再根据 polys 参数选择返回形式:polys=True 时返回 Poly,默认则调用 poly.as_expr() 返回表达式。具体实现可以查看 SymPy 的 random_poly 源码。

普通表达式 x**5 + x**3 + 1 不携带 Poly 的系数域信息。如果再用 Poly(pp, x) 构造多项式,SymPy 会重新推断系数域。这个例子中的整数系数会被推断为属于 ZZ。

直接生成 GF(2) 上的 Poly

保留原来的参数,只增加 polys=True:

from sympy import symbols, Poly, GF
from sympy.polys.specialpolys import random_poly

x = symbols('x')

pp = random_poly(x, 5, 0, 1, domain=GF(2), polys=True)

print(pp)
print(pp.domain)         # GF(2)
print(pp.get_modulus())  # 2

每次生成的多项式可能不同。如果恰好生成了问题中的表达式,Poly 会显示为:

Poly(x**5 + x**3 + 1, x, modulus=2)

其中,5 指定多项式的次数,0, 1 指定系数的取值范围,domain=GF(2) 指定系数域,polys=True 控制返回对象的形式。

已经得到表达式时怎么办?

可以在构造 Poly 时显式指定系数域:

expr = x**5 + x**3 + 1
pp = Poly(expr, x, domain=GF(2))

对这个表达式,也可以使用等价写法:

pp = Poly(expr, x, modulus=2)

后续运算应保留什么?

需要按模 2 规则计算时,继续使用系数域为 GF(2) 的 Poly 对象。例如,同一个多项式与自身相加,结果应为零:

p = Poly(x**2 + 1, x, domain=GF(2))

print(p + p)
# Poly(0, x, modulus=2)

expr = p.as_expr()
print(expr + expr)
# 2*x**2 + 2

调用 as_expr() 后,普通表达式运算不会自动沿用原来的模 2 规则。要确认系数域,应检查 Poly 对象的 domain 或 get_modulus();即使表达式中的系数都是 0 和 1,也不能据此判断系数域。

备注:内容仅供参考。