在sympy中获取系数/指数对的列表

时间:2015-06-29 21:47:53

标签: python python-2.7 sympy

我有一个总和的乘积,包含实数编号的指数。成功地将此产品扩展为加权功率之和(因此它几乎是多项式):

0.001953125*z**(7/4) + 0.013671875*z**(5/4) + 0.025390625*z**(3/4) +...

我试图从中获取系数和指数列表。由于非整数指数,Poly()似乎不起作用。

以下是我创建表达式的方法:

from __future__ import division
import sympy as sp
sp.init_printing()
N=3
Pb = 0.25
z,i=sp.symbols('z, i')
G_F = sp.product((1-Pb+Pb/2*(z**(-2**-i)+z**(+2**-i))), (i,0, N-1))
G_F = G_F.expand().as_expr()

我找到了两种不太令人满意的方法来获得这些价值观。第一种方法是列表理解变得丑陋,因为sympy似乎提供了一个不一致的表达式树,这意味着向下到原子的路径可以是Add->Mul->Pow->RationalAdd->Float或...... / p>

[(coeff,e, )
    for addand in G_F.args
        for coeff, zterm in [addand.args or (float(addand),z**0)]
            for _, e in [zterm.args or (None, (zterm))]
]

输出:

[(0.421875, 1), (0.0820312500000000, 1/2), ... ,(0.00195312500000000, 7/4), (0.0703125000000000, z)]

与循环几乎相同:

result = []
for addend in G_F.args:
    if isinstance(addend,(sp.Mul)):
        coeff, zterm = addend.args
        if isinstance(zterm, sp.Pow):
            result.append((coeff.evalf(), zterm.args[1].evalf()))
        else:
            result.append((coeff.evalf(), zterm.evalf()))
    else:
        result.append((coeff.evalf(), 0))
result

输出:

[(0.0703125000000000, 0), (0.0820312500000000, 0.500000000000000), (0.0117187500000000, -1.50000000000000),...  (0.0703125000000000, z)]

但这两种方法都有陷阱。我没有得到正确的python浮点数,你可以看到结果数组中仍然有z个。

是否有(更多)通用方法从这样的几乎多项式中获取列表(或numpy数组)?

1 个答案:

答案 0 :(得分:1)

IIUC,你或许能够将as_coeff_exponentas_ordered_terms结合起来,然后侥幸成功

[[float(x) for x in term.as_coeff_exponent(z)] for term in G_F.as_ordered_terms()]

给了我

>>> terms = [[float(x) for x in term.as_coeff_exponent(z)] for term in G_F.as_ordered_terms()]
>>> terms.sort(key=lambda x: x[1])
>>> terms
[[0.001953125, -1.75], [0.01171875, -1.5], [0.013671875, -1.25], [0.0703125, -1.0], [0.025390625, -0.75], [0.08203125, -0.5], [0.083984375, -0.25], [0.421875, 0.0], [0.083984375, 0.25], [0.08203125, 0.5], [0.025390625, 0.75], [0.0703125, 1.0], [0.013671875, 1.25], [0.01171875, 1.5], [0.001953125, 1.75]]