Sympy:使用 "assumptions" 来评估 Piecewise,专门针对 IndexedBase

Sympy: Using "assumptions" to evaluate Piecewise, specifically for IndexedBase

我正在尝试在考虑假设的情况下评估某个表达式。具体来说,我的问题与 indexedBase 对象有关。

见以下代码:

from sympy import *
init_printing(use_latex="mathjax")


ntot = symbols("n_tot", integer = True)
i = Idx("i",(1,ntot))
k = Idx("k", (1,ntot))
j = Idx("j",(1,ntot))
x = IndexedBase("x")

举个例子,让我们对 x[i] 求两个求和的导数。

expr = Sum(Sum(x[i],(i,1,ntot)),(k,1,ntot)).diff(x[j])

(注意: 这在当前的 SymPy 1.0 版本中是不可能的,开发版本是可能的,并将在未来的 SymPy 稳定版本中提供。)

我想计算表达式并得到分段答案:

print(expr.doit())
OUTPUT: n_tot*Piecewise((1, And(1 <= j, j <= n_tot)), (0, True))

所以我的问题是,我如何告诉 sympy 我确定 j 在 1 和 ntot 之间。所以我的结果是 1:

我尝试了以下但没有成功:

with assuming(j==2):
     expr=Sum(Sum(x[i],(i,1,ntot)),(k,1,ntot)).diff(x[j]).doit()

关于不等式的假设是 SymPy 中非常缺少的功能。

从技术上讲,创建 Idx 对象是为了允许符号包含定义范围,从而对索引符号设置限制。您的 j 已有此信息:

In [28]: j.upper
Out[28]: n_tot

In [29]: j.lower
Out[29]: 1

不幸的是,不等式 class 并不意味着处理 Idx 个对象,因此它的范围被忽略了。

您实际上可以尝试:

In [32]: simplify(expr.doit()).args[0][0]
Out[32]: n_tot

这会手动提取 Piecewise 表达式的第一项。

显然,当前的算法需要改进,它应该已经告诉 Sum j 在正确的范围内,以便给出 1 作为结果。