在 Sympy 中,我们可以通过 Grobner 基获得多项式约简的表示:
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])
Q, r = G.reduce(f)
assert f == expand(sum(q*g for q, g in zip(Q, G)) + r)
但我正在寻找的是一种根据定义 Groebner 基的多项式来获取 Groebner 基的元素表达式的方法,本质上只是存储在生成基时使用的 Buchberger 算法中执行的计算。
例如
groebner([2*x+3*y+5, 3*x+5*y+2, 5*x+2*y+3]) # GroebnerBasis([1], x, y, domain='ZZ', order='lex')
它表明这三个多项式生成单位理想值,但我想要这些多项式的显式组合等于 1。在给出的示例中,它是线性组合,但我想要一种也适用于非线性的方法。
在第一个例子中我获得了
Q,r
。在第二个示例中,我获得了余数 r
的模拟,但我希望多项式 Q
实现它。
类似地,方法
G.contains()
将指示理想是否包含多项式,但它不会告诉您如何产生它。有没有办法也做到这一点?
代替
reduce
使用 reduced
:
from sympy import groebner, expand, reduced
from sympy.abc import x, y
f = 2*x**4 - x**2 + y**3 + y**2
G = groebner([x**3 - x, y**3 - y])
(q, r) = reduced(f, G)
print(q,r)
# Out:
# [2*x, 1] x**2 + y**2 + y
现在
q
是关于 G 的多项式标准形式的多项式系数列表,r
是其余部分。
print(f"{[q[i]*G[i] for i in range(len(q)) if q[i]!=0]+[r]}")
display(f)
# Out:
# [2*x*(x**3 - x), y**3 - y, x**2 + y**2 + y]
# 2*x**4 - x**2 + y**3 + y**2
求和得到原始多项式:
display(sum([q[i]*G[i] for i in range(len(q))]+[r]))
# Out:
# x**2 + 2*x*(x**3 - x) + y**3 + y**2
检查:
f == expand(sum([q[i]*G[i] for i in range(len(q))]+[r]))
# Out:
# True
请注意,这适用于任何一组多项式,不一定是 Gröbner 基(带有相应的警告)。