SymPy:如何收集多变量术语?

我在sympy中有一个长表达式,看起来像这样:

2?^2??? + 3?^2 ??^2 − 4???^2 − 5???? + 2???^2 − 3??^2 − 4??? − 5??^2 ...

其中变量是w,x,y,z的组合,并且也可以具有2的幂。

我想收集项[x,y,z],以便最终得到w中的二次多项式作为每个项的系数,例如:

xyz(−0.285?^2 - 1.09⋅10−5?,1.60⋅10−10) + xy^2(...w^2,...w,...) + x^2y(...) + xz^2(...) + ...

当我使用collect(exp,[x,y,z])时,我无法实现; sympy似乎想嵌套一些术语:

?(?2(−0.00341083824360158?−2.60668077412341⋅10−8) + 
??(−0.28569359766975?2−1.09161331685904⋅10−5?−1.60378772636814⋅10−10) + ?2(0.000708269071473656?2+1.72432957139821⋅10−10?−2.29362549750881⋅10−13))

我还尝试了几种收集术语的组合,一次简化,扩展等,但无济于事。任何帮助将不胜感激!

谢谢!

owenlixuan 回答:SymPy:如何收集多变量术语?

我不知道SymPy中是否有针对这种情况的就绪函数。但是,我对SymPy的满意之处在于,一旦您熟悉内部结构,它就会为您定义此类基本操作提供很多功能。

这可能有效,或者希望至少可以提供一个起点:

In [124]: x,y,z,w = symbols('x,w')                                                                                      

In [125]: expr = 2*w**2*x*y*z + 3*w**2*x*z**2 - 4*w*x*y**2 - 5*w*x*y*z + 2*w*x*z**2 - 3*x*y**2 - 4*x*y*z - 5*x*z**2               

In [126]: expr                                                                                                                    
Out[126]: 
   2            2    2          2                      2        2                  2
2⋅w ⋅x⋅y⋅z + 3⋅w ⋅x⋅z  - 4⋅w⋅x⋅y  - 5⋅w⋅x⋅y⋅z + 2⋅w⋅x⋅z  - 3⋅x⋅y  - 4⋅x⋅y⋅z - 5⋅x⋅z 

In [127]: terms = set(e.as_coeff_Mul()[1] for c in expr.as_poly(w).all_coeffs() for e in Add.make_args(c))                        

In [128]: new_expr = sum(t * expr.coeff(t) for t in terms)                                                                        

In [129]: new_expr                                                                                                                
Out[129]: 
   2                    ⎛   2          ⎞      2 ⎛   2          ⎞
x⋅y ⋅(-4⋅w - 3) + x⋅y⋅z⋅⎝2⋅w  - 5⋅w - 4⎠ + x⋅z ⋅⎝3⋅w  + 2⋅w - 5⎠
,

重申Oscar关于让SymPy进行所需操作的观点,这是另一种使用gsutil -DD cp s3://NDAR_Central_1/submission_13364/00m/0.C.2/9007827/20041006/10263603.tar.gz gs://my-bucket 的方法,该方法收集一个表达式中重复的多个操作项。由于它还会收集重复的方块,因此我们将cse替换为w**2,以便不会收集它。

u

这是cse的输出

>>> r,e = cse(expr.subs(w**2,u))

现在收集模式:

>>> r
[(x0,x*y*z),(x1,x*y**2),(x2,x*z**2)]
>>> e
[2*u*x0 + 3*u*x2 - 5*w*x0 - 4*w*x1 + 2*w*x2 - 4*x0 - 3*x1 - 5*x2]

并恢复原图

>>> collect(e,[v for v,_ in r])

该收集方案之所以有效,是因为在所有情况下都存在>>> _.subs(list(reversed(r))).subs(u,w**2) x*y**2*(-4*w - 3) + x*y*z*(2*w**2 - 5*w - 4) + x*z**2*(3*w**2 + 2*w - 5) 相关因子的多因子系数。如果w上存在一些线性因子,则需要进行一些额外的调整(对于这种方法和其他方法):

w
,

我遇到了同样的问题,并编写了此递归函数。

def collect_with_respect_to_vars(eq,vars):
    assert isinstance(vars,list)
    eq = eq.expand()
    if len(vars) == 0:
        return {1: eq}

    var_map = eq.collect(vars[0],evaluate=False)
    final_var_map = {}
    for var_power in var_map:
        sub_expression = var_map[var_power]
        sub_var_map = collect_with_respect_to_vars(sub_expression,vars[1:])
        for sub_var_power in sub_var_map:
            final_var_map[var_power*sub_var_power] = sub_var_map[sub_var_power]
    return final_var_map

它返回一个以给定var的所有组合幂作为键的映射。

collect_with_respect_to_vars(x*2 + y**2*z*5 + x**3*y*4,[x,z])
=> {x: 2,x**3*y: 4,y**2*z: 5}

collect_with_respect_to_vars(x*2 + x*4 + z**3 + x*z*2,y])
=> {x: 2*z + 6,1: z**3}

我想在您的情况下,您可以像这样使用它。

collect_with_respect_to_vars(your_expr,z])
本文链接:https://www.f2er.com/2910644.html

大家都在问