Use Do to evaluate an expression over two indices i≠ji≠ji \ne j (over a list of tuples)?

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