sympy laurent多项式因子

Fel*_*lix 5 symbolic-math sympy

我想这一定有一个简单的答案,但我搜索了很长时间,没有找到。

例子:一个简单的洛朗多项式,所以

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

分解给出

>> factor(p) 2*y*(x**3 + 2)/x 我如何提取因子2*y/x?当表达式不是多项式时,是否有一种简单的方法来获得表达式中的公因数?我尝试了很多,但没有发现任何令人满意的东西。分解一定存在于 的步骤中factor(),对吗?

asm*_*rer 3

正如@unutbu 指出的,从这个问题你可以看到,它factor_list以更易于使用的方式给出了多项式的因子。

不幸的是,SymPy 实际上并不处理洛朗多项式(请参阅https://github.com/sympy/sympy/issues/5131)。您实际上可能无法得到您对高阶项的期望。SymPy 所做的是它认为p是一个有理函数,因此它分别对分子和分母进行因式分解。

如果您也想这样做,您可以使用类似的东西

n, d = fraction(cancel(p))
factor_list(n)
factor_list(d)
Run Code Online (Sandbox Code Playgroud)

并分别操纵这些因素。

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
Run Code Online (Sandbox Code Playgroud)

(有一天 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)])
Run Code Online (Sandbox Code Playgroud)

请注意,这里的因子并不相同,因此您想要如何解释和因式分解洛朗多项式确实很重要。