I have an expression of the form:

expr1[i_,j_] = Sum[\[Beta][j]*\[Phi][i, j]* C[i]

I would like to evaluate this expression over i=1:4, j=1:4 with i!= j.

One way of doing this is to evaluate this expression over a list of tuples, say:

A = {{1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 3}, {2, 4}, {3, 1}, {3, 2}, {3, 4}, {4, 1}, {4, 2}, {4, 3}}.

I would like to use “Do” or something similar to “loop” over my list of tuples A. Is there a way to do this in Mathematica?

I know I can do

expr1 @@@ A

but is there a way to do this using Do ?

=================

One possibility might be to sum over all combinations of iii and jjj and then subtract out the combinations where i=ji=j. This might not be the most machine efficient approach but if you only have 4*4 combinations to look at, it won’t matter.

– Jim Baldwin

May 22 ’15 at 21:42

=================

3 Answers

3

=================

Update

You could just make the equal indices vanish:

Sum[Sign[Abs[i – j]] c[i] \[Phi][i, j] \[Beta][j], {i, 1, 4}, {j, 1,

4}]

or better as @Guesswhoitis. using Iverson notation concept:

Sum[Boole[i!=j] c[i] \[Phi][i, j] \[Beta][j], {i, 1, 4}, {j, 1,

4}]

or somewhat ridiculous:

mat[sym_, m_, n_] :=

Normal@SparseArray[{i_, j_} :> sym[i, j] /; i != j, {m, n}]

cm = Array[c, 4]

be = Array[\[Beta], 4]

cm.mat[\[Phi], 4, 4].be

where you must match up row and column lengths.

Iverson brackets seem clearer to me for this, tho: Boole[i != j]. Also, since you’re using mat for matrix products anyway, you don’t really need the application of Normal[].

– J. M.♦

May 23 ’15 at 5:49

@Guesswhoitis. yes much better agree will update with appropriate (attribution)

– ubpdqn

May 23 ’15 at 5:53

After putting in the Iverson brackets, you don’t need to take signs anymore. 🙂

– J. M.♦

May 23 ’15 at 6:15

@Guesswhoitis. yes…a result of laziness in copying and worse thought…have corrected now

– ubpdqn

May 23 ’15 at 6:21

r1=Plus @@ (\[Beta][#2]*\[Phi][#1, #2]*C[#1] & @@@ A);

or

r2=expr1[i_, j_] =

Sum[If[i == j, 0, \[Beta][j]*\[Phi][i, j]*C[i]], {i, 1, 4}, {j, 1,

4}]

r1 === r2

(*True*)

pairs = ## & @@@ {#, Reverse /@ #} &@Subsets[Range[4], {2}];

{{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}, {2, 1}, {3, 1}, {4,

1}, {3, 2}, {4, 2}, {4, 3}}

Total[Î²[#2] Ï•[##] C[#] & @@@ pairs]

(*or Sum[Î²[k[[2]]] Ï•[##&@@k] C[k[[1]]],{k,pairs}] *)

C[1] Î²[2] Ï•[1, 2] + C[1] Î²[3] Ï•[1, 3] +

C[1] Î²[4] Ï•[1, 4] + C[2] Î²[1] Ï•[2, 1] +

C[2] Î²[3] Ï•[2, 3] + C[2] Î²[4] Ï•[2, 4] +

C[3] Î²[1] Ï•[3, 1] + C[3] Î²[2] Ï•[3, 2] +

C[3] Î²[4] Ï•[3, 4] + C[4] Î²[1] Ï•[4, 1] +

C[4] Î²[2] Ï•[4, 2] + C[4] Î²[3] Ï•[4, 3]

You could also use pairs = Cases[Tuples[Range[4], 2], Except[{i_, i_}]] (or equivalent Select or DeleteCases) instead of maybe slightly more unintuitive reversing trick.

– kirma

May 23 ’15 at 5:57

1

@kirma, you are right; I just wanted to avoid Tuples for cases where i and j range over a large set.

– kglr

May 23 ’15 at 11:42