2016-09-06 17 views
3

我有一個理性的(這裏:雙線性)表達式,並希望我sympy收集 係數。但是如何?在sympy中,我如何獲得理性表達的係數?

from sympy import symbols, Wild, pretty_print 

a, b, c, d, x, s = symbols("a b c d x s") 

def coeffs(expr): 
    n0 = Wild("n0", exclude=[x]) 
    n1 = Wild("n1", exclude=[x]) 
    d0 = Wild("d0", exclude=[x]) 
    d1 = Wild("d1", exclude=[x]) 
    match = expr.match((n0 + n1*x)/(d0 + d1*x)) 
    n0 = n0.xreplace(match) 
    n1 = n1.xreplace(match) 
    d0 = d0.xreplace(match) 
    d1 = d1.xreplace(match) 
    return [n0, n1, d0, d1] 

if __name__ == '__main__': 
    pretty_print(coeffs((a + b*x)/(c + d*x))) 
    pretty_print(coeffs(2 * (a + b*x)/(c + d*x))) 
    pretty_print(coeffs(s * (a + b*x)/(c + d*x))) 

這個我試過用match,但失敗幾乎總是,例如在最後一行(一個與「S」符號前因子),我得到

Traceback (most recent call last): 
    File "...", line 20, in <module> 
    pretty_print(coeffs(s * (a + b*x)/(c + d*x))) 
    File "...", line 11, in coeffs 
    n0 = n0.xreplace(match) 
    File "/usr/lib/python3/dist-packages/sympy/core/basic.py", line 1626, in xreplace 
    return rule.get(self, self) 
AttributeError: 'NoneType' object has no attribute 'get' 

所以比賽做不行。

回答

3

如果你知道表達式你會認爲是合理的,你可以提取它們的分子和分母並獨立地找到它們的係數。

這裏有一個方法可以這樣做:

import sympy as sp 

def get_rational_coeffs(expr): 
    num, denom = expr.as_numer_denom() 

    return [sp.Poly(num, x).all_coeffs(), sp.Poly(denom, x).all_coeffs()] 

a, b, c, d, x, s = sp.symbols("a b c d x s") 
expr = (a + b*x)/(c + d*x) 

# note the order of returned coefficients 
((n1, n0), (d1, d0)) = get_rational_coeffs(s*expr) 
print(((n0, n1), (d0, d1))) 

((a*s, b*s), (c, d))

上述方法也快於coeffs。我得到(其中coeffs成功案例),在需要的expr係數的情況下定時(基於Jupyter的%timeit魔術):

%timeit get_rational_coeffs(expr) 
%timeit coeffs(expr) 

1000 loops, best of 3: 1.33 ms per loop

1000 loops, best of 3: 1.99 ms per loop