如何 return 为 sympy 中缺失的单项式归零

How to return zero for a missing monomial in sympy

我想 return 为缺少的单项式归零,但在 sympy 的文档中找不到任何指针。我的意图是从多个表达式构建一个稀疏数组。是否有捷径可寻? MWE:

import sympy
x, y, z = sympy.symbols('x, y, z')
func_1 = 3 + x + 5 * y + 2 * z
func_2 = 1 + x + 2 * y

expr_2 = [func_1, func_2]
func_vars = [x, y, z]

eqs = sympy.parallel_poly_from_expr(expr_2, func_vars)
[[eqn.coeff_monomial(m) for m in eqn.monoms()][:-1] for eqn in eqs[0]]

# >>> [[1, 5, 2], [1, 2]]
# expected [[1,5,2],[1,2,0]]

根据 smichr 的建议使用带非线性变量的 indexedbase 更新了 MWE:

def get_coeffs(coeff_dict, func_vars):
    c = coeff_dict
    for i in list(c.keys()):
        b, _ = i.as_base_exp()
        if b == i:
            continue
        if b in c:
            raise ValueError('multiple generators with %s' % b)
        if any(k.has(b) for k in c):
            raise ValueError('cross terms detected with %s' % b)
        c[b] = c[i]  

    return [coeff_dict[val] for val in func_vars]  


x =  sympy.IndexedBase('x')
func_1 = 3 + x[0]**2 + 5 * x[1] + 2 * x[2]
func_2 = 1 + x[0] + 2 * x[1]

expr_2 = [func_1, func_2]
func_vars = [x[0], x[1], x[2]]


([get_coeffs(i.as_coefficients_dict(), func_vars) for i in expr_2])
# I get [[1, 5, 2], [1, 2, 0]]

如果它只是一个普通的列表,你可以post-处理它。要在右侧用 0 填充二维列表 x,您可以这样做:

width = max(map(len, x))
for row in x:
    row.extend([0] * (width - len(row)))

基本上,您可以通过找到所有行的最大宽度来获得整个内容的宽度。然后,对于每一行,您只需在其后插入多少 0 即可使其达到正确的宽度。

如果您使用的是线性方程,那么 linear_eq_to_matrix 可以处理原始(非多边形)表达式,为您提供系数矩阵:

>>> linear_eq_to_matrix([i.as_expr() for i in eqs[0]],[x,y,z])
(Matrix([
[1, 5, 2],
[1, 2, 0]]), Matrix([
[-3],
[-1]]))

as_coefficients_dict 方法可能是更好的选择。如果您拥有某个变量的幂,则可以修改生成的字典以存储具有相同系数的幂的底数。

>>> x=IndexedBase('x')
>>> eq=3 + x[0]**2 + 5 * x[1] + 2 * x[2]
>>> eq.as_coefficients_dict()
defaultdict(<class 'int'>, {1: 3, x[0]**2: 1, x[2]: 2, x[1]: 5})
>>> c=_
>>> for i in list(c.keys()):
...   c[i.as_base_exp()[0]] = c[i]  # set values bases of powers
...
>>> [_[x[i]] for i in range(4)]  # default dict will supply 0
[1, 5, 2, 0]