Reputation: 13
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?
Upvotes: 0
Views: 661
Reputation: 19037
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.)
Upvotes: 1