I'm doing some computations that involve summations with many indices over the same range - consider the simplified example Sum[a[i,j],{i,1,2},{j,1,2}]. To prettify my code I'm attempting to define a helper function so I can write this as S2[a[i,j],i,j]. My first thought was pretty simple - just build the sequence of inputs to Sum and fire it off:

S2[expr_, indices__] :=  Sum @@ Join[{expr}, Map[{#, 1, 2} &, {indices}]];

This works for many inputs, but has some issues with premature evaluation that Sum,Table, etc. do not. Consider for example the input function a[i_,j_]:=D[u[i],u[j]], which should produce the same outputs as KroneckerDelta. With our long-hand code we get the expected output:

In[1] := Sum[a[i, j], {i, 1, 2}, {j, 1, 2}]
Out[1] = 2

but with our S2 we do not:

In[2] := S2[a[i, j], i, j]
Out[2] = 0

This is due to a being evaluated before the values of i and j are assigned. I've tried setting HoldFirst on S2, replacing expr with Hold[expr] and releasing the hold at various places in the definition, but nothing I can think of gives me the desired behaviour.

What's the best way to accomplish what I want here (robust evaluation behaviour similar to that of Sum)?


2 Answers 2


The following also works

SetAttributes[S3, HoldFirst];

S3[expr_, indices__] := 
 With[{ex = Unevaluated[expr]}, (Sum @@ 
    Join[{ex}, Map[{#, 1, 2} &, {indices}]])]

One possibility:

a[i_, j_] := D[u[i], u[j]]
SetAttributes[S2, HoldFirst]
S2[expr_, indices__] := Sum @@ Join[Inactivate@{expr}, Map[{#, 1, 2} &, {indices}]] // Activate;
S2[b[i, j], i, j]
S2[a[i, j], i, j]

enter image description here

  • $\begingroup$ Thanks, but I'm stuck on Mathematica 9 at the moment - any way to do it without the new Activate/Inactivate? $\endgroup$ Commented Jan 15, 2016 at 6:58

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.