首页 > 解决方案 > Sympy 基于自由参数简化总和

问题描述

我有一个同情的总和:

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智能地简化关于自由和指数的求和?

标签: sympy

解决方案


这种行为确实看起来有点奇怪。这就是它发生的原因(看看底部什么是错误,什么不是)。


首先,summation它只是创建Sum和运行的语法糖.doit()Sumdoit使用在其余部分eval_sum中,当限制变量不是函数的自由变量时提取限制边界,并且简单的检查表明这确实应该在这里成立!(正如你所展示的,它没有):

>>> i in my_sum.free_symbols
False

所以我对模块做了一些研究summation

现在,Sum有一个叫AddWithLimits. 在它的类创建器中,它使用了_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你定义的对象my_sum(乍一看不会弹出),所以限制变量实际上是函数的自由变量


我尝试手动取消去嵌套,在评论下评论三行# denest any nested calls,确实,我收到了

n*Sum(x[i], (i, 1, n))

当然,简单地改变它可能会损害代码的其他部分,因为在许多其他ExprWithLimits函数中都假设了嵌套。这是否是一种预期的行为可以得到支持,但如果您认为应该涵盖它,则可能必须在内部明确指定它eval_sum作为一种特殊情况。


但是,我希望与另一个变量的总和可以正常简化,例如

summation(x[i], (i, 1, n), (j, 1, n))

没有。我怀疑,这更像是一种预期的行为(这是因为第一次迭代eval_sum返回None,所以它跳过了j符号扩展)。


推荐阅读