我在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))
我还尝试了几种收集术语的组合,一次简化,扩展等,但无济于事。任何帮助将不胜感激!
谢谢!
答案 0 :(得分:2)
我不知道SymPy中是否有针对这种情况的就绪函数。但是,我对SymPy的满意之处在于,一旦您熟悉内部结构,它就会为您定义此类基本操作提供很多功能。
这可能有效,或者希望至少可以提供一个起点:
In [124]: x, y, z, w = symbols('x, y, z, 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⎠
答案 1 :(得分:1)
重申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
答案 2 :(得分:0)
我遇到了同样的问题,并编写了此递归函数。
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, y, 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, [x, y])
=> {x: 2*z + 6, 1: z**3}
我想在您的情况下,您可以像这样使用它。
collect_with_respect_to_vars(your_expr, [x, y, z])