Sympy:如何从总和中分解常数?

Sympy: how to factor constants out of sum?

作为 Sympy 的新手,我试图通过在一个简单的案例(简单的最小二乘拟合直线)上进行测试来学习如何使用它。这是我之前计算的结果(下一行是 iPython 的 output):

Sum(2*a*x(i)**2, (i, 1, N)) + Sum(2*b*x(i), (i, 1, N)) + Sum(-2*x(i)**2, (i, 1, N))

我现在希望 Sympy 从总和 中得到常量(例如 2*a、2*b 和 -2)作为乘法因子,但我不知道不知道如何实现。我试过使用 collect、factor 和其他函数都无济于事。您能帮我指出正确的方向吗?

看看这个 GitHub issue 似乎目前没有任何方法可以分解出与求和无关的项。也许这将在 SymPy 的未来版本中实现。

对于单个 Sum 术语,@smichr(在该 GitHub 页面上)建议如下解决方法:

s = Sum(2*a*x(i)**2, (i, 1, N)) # your first Sum term 
con, dep = factor_terms(s.function.as_independent(*s.variables));
factored_s = con*Sum(dep, *s.args[1:])

产生术语 factored_s 为:

2*a*Sum(x(i)**2, (i, 1, N))

对于包含多个 Sum 项的表达式,您可以将它们拆分为一个列表,其中包含 as_ordered_terms()、运行 每个项的变通方法,然后将它们添加回去组合成一个表达式。

同样的@smichr,解决方案基本相同:

def cSum(s):
  con, dep = factor_terms(s.function.as_independent(*s.variables))
  return con*Sum(dep, *s.args[1:])

var('a b x N i')
eq = Sum(2*a*x(i)**2, (i, 1, N)) + Sum(2*b*x(i), (i, 1, N)) + \
     Sum(-2*x(i)**2, (i, 1, N))
>>> pprint(eq.replace(lambda s: isinstance(s, Sum), lambda s: cSum(s)))
      N                 N              N
     ___               __             ___
     \  `              \ `            \  `
2*a*  \    2    + 2*b*  )   x(i) - 2*  \    2
      /   x (i)        /_,             /   x (i)
     /__,             i = 1           /__,
    i = 1                            i = 1