同情多项式因子

时间:2017-12-12 22:14:47

标签: sympy symbolic-math

我认为必须有一个简单的答案,但我搜索的时间很长,无法找到它。

示例:一个简单的Laurent多项式,所以

>> p = 2*y*x**2+4*y/x

分解给出

>> factor(p) 2*y*(x**3 + 2)/x 如何提取因子2*y/x?当表达式不是多项式时,是否有一种简单的方法可以在表达式中得到公因子?我已经尝试了很多,但没有找到任何令人满意的东西。分解必须存在于factor()的某个位置,对吧?

1 个答案:

答案 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()跳过此步骤(如果它最终变慢)。

或者,您可能希望将x1/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多项式非常重要。