我认为必须有一个简单的答案,但我搜索的时间很长,无法找到它。
示例:一个简单的Laurent多项式,所以
>> p = 2*y*x**2+4*y/x
分解给出
>> factor(p)
2*y*(x**3 + 2)/x
如何提取因子2*y/x
?当表达式不是多项式时,是否有一种简单的方法可以在表达式中得到公因子?我已经尝试了很多,但没有找到任何令人满意的东西。分解必须存在于factor()
的某个位置,对吧?
答案 0 :(得分:3)
正如@unutbu指出的那样,从this question可以看出factor_list
给出了一个更容易使用的多项式的多项式因子。
不幸的是,SymPy实际上并没有处理Laurent多项式(参见https://github.com/sympy/sympy/issues/5131)。实际上,您可能无法获得更高阶条款的预期。 SymPy所做的是它看到p
是一个有理函数,因此它分别对分子和分母进行分解。
如果您还想这样做,可以使用类似
的内容n, d = fraction(cancel(p))
factor_list(n)
factor_list(d)
分别操纵因素。
cancel
将确保没有重复项,否则会自动与factor(p)
一起发生重复项,并且它还会将表达式置于合理的形式,以便fraction
起作用。您也可以使用p.as_numer_denom()
跳过此步骤(如果它最终变慢)。
或者,您可能希望将x
和1/x
视为多项式的单独生成器。这是上述问题的一个(更正的)函数
def aspoly1t(p, t, z=Symbol('z')):
"""
Rewrite p, a polynomial in t and 1/t, as a polynomial in t and z=1/t
"""
pa, pd = cancel(p).as_numer_denom()
pa, pd = Poly(pa, t), Poly(pd, t)
assert pd.is_monomial
d = pd.degree(t)
one_t_part = pa.slice(0, d + 1)
t_part = pa - one_t_part
t_part = t_part.to_field().quo(pd)
one_t_part = Poly.from_list(reversed(one_t_part.rep.rep), *one_t_part.gens, domain=one_t_part.domain)
one_t_part = one_t_part.replace(t, z) # z will be 1/t
ans = t_part.as_poly(t, z) + one_t_part.as_poly(t, z)
return ans
(有一天,Poly会以Poly(p, x, 1/x)
为原生支持这一点)然后您可以使用factor_list
:
>>> aspoly1t(p, x)
Poly(2*y*x**2 + 4*y*z, x, z, domain='ZZ[y]')
>>> factor_list(aspoly1t(p, x))
(2, [(Poly(y, x, y, z, domain='ZZ'), 1), (Poly(x**2 + 2*z, x, y, z, domain='ZZ'), 1)])
请注意,这里的因素并不相同,因此您想要如何解释和计算Laurent多项式非常重要。