# Simplification of products of KroneckerDelta[]

What is the reason why the following expression does not simplify to True?

Assuming[
i > 0 && j > 0 && k > 0 && Element[{i, j, k}, Integers],
FullSimplify[
KroneckerDelta[i, j] * KroneckerDelta[i, k] == KroneckerDelta[i, j, k]
]
]

(* KroneckerDelta[i, j] KroneckerDelta[i, k] == KroneckerDelta[i, j, k] *)


Is there a corner case where this equation is actually false? Does Mathematica simply not know about this identity? If the latter is the case, how could I define a rule for FullSimplify to simplify products like the one on the left hand side?

• If you use Einstein summation convention then you would probably prefer KroneckerDelta[i, j] * KroneckerDelta[i, k] to simplify to KroneckerDelta[j,k], for example. So it is likely easier to just allow the user to specify their desired behavior. Oct 21, 2015 at 18:44

You may be able to "teach" KroneckerDelta about this:

Unprotect[KroneckerDelta];
KroneckerDelta /: (Times[KroneckerDelta[i_, j_], KroneckerDelta[k_, m_]] /; i == k) :=
KroneckerDelta[i, j, m]
Protect[KroneckerDelta];


After the above, here is the new behavior:

KroneckerDelta[a, b] KroneckerDelta[c, d] (* this doesn't match *)
KroneckerDelta[a, b] KroneckerDelta[a, d] (* your use case *)

(* Out:
KroneckerDelta[a, b] KroneckerDelta[c, d]
KroneckerDelta[a, b, d]
*)

• Thanks. That got me on the right track. I currently use KroneckerDelta /: (Times[KroneckerDelta[i_, j__], KroneckerDelta[i_, k__]]) := KroneckerDelta[i, j, k], which is a little bit more general, I think. Oct 21, 2015 at 20:09
• @DavidZwicker Glad it helped! Oct 21, 2015 at 20:15

Adding PiecewiseExpand[] forces the conversion of KroneckerDelta[] into Piecewise[] equivalents, which play nicer with simplification:

Assuming[i > 0 && j > 0 && k > 0 && {i, j, k} ∈ Integers,
KroneckerDelta[i, j] KroneckerDelta[i, k] == KroneckerDelta[i, j, k]
// PiecewiseExpand // Simplify]


Another method consists of converting KroneckerDelta[] expressions into the equivalent Iverson brackets (i.e., Boole[]):

KroneckerDelta[i, j] KroneckerDelta[i, k] == KroneckerDelta[i, j, k] /.
k_KroneckerDelta :> Boole[Equal @@ k] // FullSimplify