11
$\begingroup$

I am new to Mathematica so this question may seem rudimentary. Sorry for that! :)

I want to implement the well-known property of Kronecker's Delta

$$\Sigma_{i=1}^{n} a_i \delta_{ij}=a_j,\quad 1 \le j \le n$$

So I wrote the following code

KroDelProp[Eq_] := Module[{R, c, i, j, a, b},
  R = Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] :> (c /. i -> j);
  Eq /. R
  ]
Eq = Inactive[Sum][a[i]*KroneckerDelta[i, j], {i, 1, n}]
KroDelProp[Eq]
(* a[j] *)

So everything looks fine. But when I use Rule instead of RuleDelayed in KroDelProp then I get

KroDelProp[Eq_] := Module[{R, c, i, j, a, b},
  R = Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] -> (c /. i -> j);
  Eq /. R
  ]
Eq = Inactive[Sum][a[i]*KroneckerDelta[i, j], {i, 1, n}]
KroDelProp[Eq]
(* a[i] *)

I read the documentation but I couldn't find out what is happening here!

Can someone shed some light on this? :)


I found reading this documentation very useful. Hope that it helps the future readers of this post too.

$\endgroup$
8
  • $\begingroup$ I invite you to read the documentation that the first sentence could not be more explicit. Rule "represents a rule that transforms lhs to rhs." RuleDelayed "represents a rule that transforms lhs to rhs, evaluating rhs only after the rule is used." $\endgroup$
    – physicien
    Commented Mar 25, 2016 at 14:58
  • 1
    $\begingroup$ @physicien: I read that but I couldn't find why this happens! Why the evaluation of RHS of the rules effects the output here? $\endgroup$ Commented Mar 25, 2016 at 15:00
  • $\begingroup$ @physicien: Can you tell what happens in each of the codes step by step? $\endgroup$ Commented Mar 25, 2016 at 15:04
  • $\begingroup$ @physicien: I had a typo. I mean that the output is $a[i]$ or $a[j]$ in each case. $\endgroup$ Commented Mar 25, 2016 at 15:14
  • 3
    $\begingroup$ Try x = 17; {y -> x, y :> x} $\endgroup$
    – John Doty
    Commented Mar 25, 2016 at 15:22

2 Answers 2

6
$\begingroup$

Perhaps the easiest way to highlight the differences is to isolate the substitution rules you constructed in each case. See what the following rules evaluate to:

(* Rule *)
Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] -> (c /. i -> j)

immediate

(* RuleDelayed *)
Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] :> (c /. i -> j)

delayed

You can clearly see that in the first case (simple Rule), the right hand side of the rule is immediately evaluated; in that case c does not contain i so the second replacement in RHS doesn't apply, and the RHS just evaluates to c. When you apply this substitution rule, c matches a[i] in the expression, so that's what's returned.

With RuleDelayed evaluation of the right hand side is delayed until after a match has been found. In this case, c matches to a[i]; the right hand side then evaluates to a[i] /. i -> j, which produces the correct result.

$\endgroup$
3
  • $\begingroup$ Thanks for the comprehensive answer. :) I am happy now! :D $\endgroup$ Commented Mar 25, 2016 at 17:36
  • 1
    $\begingroup$ @H.R. Glad it helped! Your question provides a nice practical example of the difference in behavior between Rule and RuleDelayed. $\endgroup$
    – MarcoB
    Commented Mar 25, 2016 at 17:38
  • $\begingroup$ thank you! I was struggling with a similar issue. It's clear now! edit: 8 years later :D $\endgroup$
    – youyou
    Commented Sep 27 at 14:32
2
$\begingroup$

It's always useful to see what the fragments of your code do. Compare the result of:

Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] :> (c /. i -> j)

With:

Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}] -> (c /. i -> j)

Note also that localizing the names of patterns with Module does nothing, and there's no need to name your rule. And then, why not pattern match in your definition, deconstruct your argument there?

KroDelProp[Inactive[Sum][c_*KroneckerDelta[i_, j_], {i_, a_, b_}]] := c /. i -> j
KroDelProp[Inactive[Sum][a[i]*KroneckerDelta[i, j], {i, 1, n}]]

(* a[j] *)

Module is rarely useful. It's usually a symptom that you could factor your code better.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.