如何在 Sympy 上用条件求和? [英] How to Sum with conditions on Sympy?

查看:39
本文介绍了如何在 Sympy 上用条件求和?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,如果这听起来很愚蠢.我是 Sympy 的初学者,我真的试图克服这个问题.失败的.就这样吧:

如果我这样做,例如:

<预><代码>>>>i, j = Dummy('i'), Dummy('j')>>>N = 符号('N')>>>expr = Sum(KroneckerDelta(i,j), (i,0,N))>>>expr.doit()

我明白

分段((1, And(0 <= _j ,_j <= N)), (0, else))

这意味着在给定条件下有两种不同的结果.我的问题是:如果我先验地知道确实满足第一个条件(0<=j<=N),我如何让 Sympy 知道它,所以它只输出第一个结果?

解决方案

我不确定您是否在问是否有一种方法可以定义 j 以便最终结果只是 1 或者您是否想知道如何使用你所知道的(即 j 是非负且小于或等于 N)来得到简化的结果.

我不知道前者怎么做,但后者可以.如果您知道条件为真,您可以在结果中使用它:

<预><代码>>>>ans = expr.doit()

天真的方法是尝试按照您所见进行替换,记住 _j 就是 Dumm('j') 的表示方式:

<预><代码>>>>ans.subs(And(0 <= j, j <= N), True)分段((1, (0 <= _j) & (_j <= N)), (0, True))

这没有任何作用,因为 0 是一个 Python 整数,输入 0 0 j 把它变成 j >0 并且无法识别替换.

<预><代码>>>>0<j_j >0

您也可以尝试用一个值替换 j 使其为真

<预><代码>>>>ans.subs(j,0)分段((1, 0 <= N), (0, True))

但这失败了,因为 N 可能是正数或负数.如果您知道 N 是非负的,您可以在开始时使用该假设创建它:

<预><代码>>>>N = var('N', nonnegative=True)>>>expr = Sum(KroneckerDelta(i, j), (i, 0, N))>>>ans = expr.doit()>>>ans.subs(j, 0)1

或者,您可以通过原子访问您知道为 True 的确切表达式.你知道为真的条件是一个 And.我们可以得到 ans 中出现的所有 Ands 的集合

<预><代码>>>>ans.atoms(Ans)set([(0 <= _j) & (_j <= N)])

只有这个,所以我们简单地从集合中弹出它并在 ans 中用 True 替换它:

<预><代码>>>>ans.subs(_.pop(), True)1

(如果原子数超过 1 个,则必须将集合转换为列表并使用索引来选择您感兴趣的原子.)

Sorry if this sounds dumb. I'm a beginner with Sympy and really tried to get over this. Failed. So here it goes:

If I do, for example:

>>> i, j = Dummy('i'), Dummy('j')
>>> N = symbols('N')
>>> expr = Sum(KroneckerDelta(i,j), (i,0,N))
>>> expr.doit()

I get

Piecewise((1, And(0 <= _j ,_j <= N)), (0, otherwise))

It means there's two different results, given conditions. My question is: if I know a priori that indeed the first condition is satisfied (0<=j<=N), how do I let Sympy know of it, so it only outputs the first result?

解决方案

I am not sure if you are asking if there is a way you could have defined j so the final result would have simply been 1 or if you want to know how to use what you know (that j is nonnegative and less than or equal to N) to get the result to simplify.

I am not sure how to do the former, but the latter can be done. If you know the condition is true you can use that in your result:

>>> ans = expr.doit()

The naive approach is to try do the replacement as you see it, remembering that _j is just how Dumm('j') is represented:

>>> ans.subs(And(0 <= j, j <= N), True)
Piecewise((1, (0 <= _j) & (_j <= N)), (0, True))

This doesn't do anything because 0 is a python integer and typing 0 < j turns it into j > 0 and the replacement is not recognized.

>>> 0 < j
_j > 0

You also might try to substitute in a value for j that should make it true

>>> ans.subs(j,0)
Piecewise((1, 0 <= N), (0, True))

But this fails because N could be positive or negative. If you know that N is nonnegative, you could have created it with that assumption at the start:

>>> N = var('N', nonnegative=True)
>>> expr = Sum(KroneckerDelta(i, j), (i, 0, N))
>>> ans = expr.doit()
>>> ans.subs(j, 0)
1

Alternatively, you could access the exact expression that you know is True through the atoms. The condition that you know is true is an And. We can get a set of all Ands that appear in the ans

>>> ans.atoms(Ans)
set([(0 <= _j) & (_j <= N)])

There is only this one, so we simply pop it from the set and replace it with True in the ans:

>>> ans.subs(_.pop(), True)
1

(If there were more than 1 atom, you would have to convert the set to a list and use an index to select the one in which you were interested.)

这篇关于如何在 Sympy 上用条件求和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆