在 sympy 中获取 coefficient/exponent 对的列表

Getting a list of coefficient/exponent pairs in 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 或 ...

[(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 浮点数,正如你所看到的,结果数组中仍然有 zs。

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

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]]