'Sympy simplify sum of Kronecker delta
How does one simplify sums of Kronecker delta expressions in sympy?
For example consider Sum(KroneckerDelta(i,j),(i,0,n-1))
or Sum(KroneckerDelta(i, j, (0, n - 1)), (i, 0, n - 1))
:
from sympy import *
from sympy.concrete.delta import _simplify_delta
n = symbols('n')
j = tensor.Idx('j')
i = tensor.Idx('i')
_simplify_delta(simplify(Sum(KroneckerDelta(i,j),(i,0,n-1))))
_simplify_delta(simplify(Sum(KroneckerDelta(i,j,(0,n-1)),(i,0,n-1))))
Outputs Sum(KroneckerDelta(i, j), (i, 0, n - 1))
and Sum(KroneckerDelta(i, j, (0, n - 1)), (i, 0, n - 1))
If j
is constrained to be between 0
and n-1
(how do I tell the sympy that?), then this should reduce to 1, which occurs at i==j. Moreover if the sum is more complicated, I would expect it to remove the sum and replace the sum variable i with the variable j.
Moreover, I would be interested in a resource for all sorts of simplifications in sympy for KroneckerDelta functions. I recently found out how to perform implicit matrix differentiation in sympy and KroneckerDelta functions appear everywhere.
Edit: I found a solution, kind of. Its not automated.
I found more functions inside of sympy.concrete.delta using help(sympy.concrete.delta)
. If we copy the resulting expression and replace Sum
with sympy.concrete.delta.deltasummation
then the desired simplification happens. I am still curious if there is a delta simplification package that tries all these things automatically.
Solution 1:[1]
You can evaluate summations using Sum().doit()
or summation
:
In [1]: from sympy import *
...: from sympy.concrete.delta import _simplify_delta
...:
...: n = symbols("n")
...: j = tensor.Idx("j")
...: i = tensor.Idx("i")
In [2]: s = Sum(KroneckerDelta(i, j), (i, 0, n - 1))
In [3]: s
Out[3]:
n - 1
___
?
? ?
? i,j
?
???
i = 0
In [4]: s.doit()
Out[4]:
?1 for j ? 0 ? j ? n - 1
?
?0 otherwise
In [5]: summation(KroneckerDelta(i, j), (i, 0, n - 1))
Out[5]:
?1 for j ? 0 ? j ? n - 1
?
?0 otherwise
There isn't currently a way to specify in assumptions that j<=n-1
although you can use j = symbols('j', nonnegative=True)
to specify that j>=0
. You can also manually replace those conditions with true though e.g.:
In [8]: s.doit().subs({j >= 0: True, j <= n-1: True})
Out[8]: 1
The second summation where you give bounds for the KroneckerDelta
will compute automatically:
In [11]: s2 = Sum(KroneckerDelta(i, j, (0, n - 1)), (i, 0, n - 1))
In [12]: s2
Out[12]:
n - 1
___
?
? ?
? i,j
?
???
i = 0
In [13]: s2.doit()
Out[13]: 1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Oscar Benjamin |