Simplify sum of Kronecker delta

The following simplification is correct: $$\sum_{j=1}^{J}\sum_{k=1}^{K} \delta_{a, j}\delta_{b,k}A_{j,k} = A_{a, b}$$

How to make Mathematica do that?

Try:

$$Remove["Global*"]$$Assumptions = Element[a | b, Integers] && 1 <= a <= J && 1 <= b <= K;
expr = Sum[KroneckerDelta[a, j]*KroneckerDelta[b, k]
*A[j, k], {j, 1, J}, {k, 1, K}]
Simplify[expr]


Result:

Simplify can't simplify expr.


One approach is to use DiscreteDelta instead of KroneckerDelta. With this substitution, the setup is:

\$Assumptions = Element[a | b, Integers] && 1 <= a <= J && 1 <= b <= K;
expr = Sum[DiscreteDelta[a - j]*DiscreteDelta[b - k]*A[j, k], {j, 1, J}, {k, 1, K}]

A[Ceiling[a], Ceiling[b]]


Amazingly, it isn't even necessary to invoke Simplify, though I suppose it might in more complicated situations. To see that this substitution of DiscreteDelta for KroneckerDelta is correct, observe that

KroneckerDelta[a, j] == DiscreteDelta[a - j] // FullSimplify
True

• No wonder one question here asked how to replace all KroneckerDelta with DiscreteDelta. – R zu Nov 22 '18 at 1:19
• If a and j are equal, so that KroneckerProduct[a,j] is 1, then DiscreteDelta[a-j] is also 1. Similarly for a and j unequal, both KroneckerProduct[a,j] and DiscreteDelta[a-j] are zero. So they are the same with appropriate translation of the arguments. – bill s Nov 22 '18 at 2:37
• I understand the trick now. Thanks. – R zu Nov 22 '18 at 5:59
• Replace all KroneckerDelta by DiscreteDelta: ReplaceDelta[expr_] = expr /. KroneckerDelta[a_, b_] -> DiscreteDelta[a - b]; This is so simple! Thanks! – R zu Nov 22 '18 at 6:11
• 4 hours and Mathematica is still not done. This looks a bit like a dead-end. – R zu Nov 22 '18 at 23:24

Why not work with symbolic tensors instead? For example, your sum can be represented as:

s = TensorContract[
TensorProduct[
IdentityMatrix[j],
IdentityMatrix[k],
A
],
{{2, 5}, {4, 6}}
];


The built-in function TensorReduce is not quite able to simplify this, but you can install my TensorSimplify paclet to enable simplification. Install with:

PacletInstall[
"TensorSimplify",
"Site" -> "http://raw.githubusercontent.com/carlwoll/TensorSimplify/master"
]


Once installed, load the package with:

<<TensorSimplify


Finally, let's try TensorSimplify on your example:

TensorSimplify[s, Assumptions -> A ∈ Matrices[{j, k}]]


A

• I am not familiar with tensor sum/product yet. The expression is from derivative of matrix equation, which isn't in terms of tensor sum/product (similar to mathematica.stackexchange.com/questions/186330/…) For now, I manually simplify the expression, but I can make mistakes. – R zu Nov 19 '18 at 22:25

Assume each summation is over all possible values of an index.

Assume the two indices of each Kronecker delta have the same domain.

Simplify Kronecker delta sum:

test = Sum[A[j, k, l]*KroneckerDelta[j, a]*KroneckerDelta[k, b]*
B[j, k, l, m] +
A[j, k, m]*KroneckerDelta[l, c]*KroneckerDelta[j, a]*
KroneckerDelta[k, b]*
B[j, k, l, m], {j, 1, J}, {k, 1, K}, {l, 1, L}, {m, 1, L}]

f[exp_] :=
exp /. {(x1_) + (x2__) :> f[x1] + f[Total[{x2}]],
Sum[(x1_) + (x2__), z__] :> f[Sum[x1, z]] + f[Sum[x2, z]],
Sum[c1___*(x1_ + x2__)*c2___, z__] :>
f[Sum[c1*c2*x1, z]] + f[Sum[c1*c2*x2, z]], (c__)*
Sum[x1__, z__]*(c2___) :> c*c2*f[Sum[x1, z]],
Sum[Sum[x1__, z1__], z2__] :> f[Sum[x1, z1, z2]],
Sum[(c1___)*KroneckerDelta[r_, s_]*(c2___), z1__, {s_, 1, p_},
z2___] :> f[Sum[c1*c2 /. s -> r, z1, z2]],
Sum[(c1___)*KroneckerDelta[r_, s_]*(c2___), z1___, {s_, 1, p_},
z2__] :> f[Sum[c1*c2 /. s -> r, z1, z2]],
Sum[(c1___)*KroneckerDelta[r_, s_]*(c2___), {s_, 1, p_}] :>
f[c1*c2 /. s -> r]}

f[test]
`
• Somehow this is faster than assumption + replace Kronecker by discrete + simplify. – R zu Nov 22 '18 at 20:00
• Have problem when it try to expand the product of two summations with the same index. It doesn't know how to rename duplicated indices. – R zu Nov 22 '18 at 23:29