我有一笔象征性的款项:
import sympy
x = sympy.IndexedBase('x')
n = sympy.symbols('n')
i = sympy.symbols('i', cls=sympy.Idx)
my_sum = sympy.summation(x[i], (i,1,n))
[在各种计算中,有时我会得到嵌套的总和。有时,这些总和具有“自由变量”,有时则没有。例如,我可能会得到以下结果:
my_double_sum = sympy.summation(my_sum, (i,1,n))
现在,由于my_sum
从外部总和的角度来看没有“自由” i
,所以这应该简化为:
n*Sum(x[i], (i, 1, n))
但是,sympy.simplify(my_double_sum)
给出:
Sum(x[i], (i, 1, n), (i, 1, n))
如何使sympy
相对于自由求和索引智能地简化求和?
此行为确实看起来有点怪异。这就是它发生的原因。
首先,summation
只是创建summation
并运行Sum
的语法糖。 .doit()
的Sum
在其余的doit
中使用,当极限变量不是函数的自由变量时,它将提取极限范围,并且简单的检查表明确实这应该在这里成立! (而且正如您所显示的那样):
eval_sum
所以我做了一些eval_sum
模块的挖掘。
现在,>>> i in my_sum.free_symbols
False
有一个称为summation
的父对象。在其类创建器中,它使用Sum
函数拒绝它接收的函数。
[这会将Sum
转换为AddWithLimits
(在调用AddWithLimits
之前),因此内部函数是_common_new
,而不是您在_common_new
中定义的Sum(Sum(x[i], (i, 1, n)), (i, 1, n))
对象(不会在以下位置弹出)一见钟情,所以极限变量实际上是函数的自由变量。
[我试图手动取消删节,在评论Sum(x[i], (i, 1, n), (i, 1, n))
下评论了三行,实际上,我收到了]]
,但如果您认为应该将其涵盖,则可能必须在doit
当然,简单地进行更改可能会损害代码的其他部分,因为在许多其他
x[i]
函数中假定了嵌套。 是否这是预期的行为,可以赞成
Sum
内部明确指定。