1
$\begingroup$

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 ?

$\endgroup$
1
  • $\begingroup$ One possibility might be to sum over all combinations of $i$ and $j$ and then subtract out the combinations where $i=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. $\endgroup$
    – JimB
    May 22, 2015 at 21:42

3 Answers 3

2
$\begingroup$

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.

$\endgroup$
4
  • $\begingroup$ 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[]. $\endgroup$ May 23, 2015 at 5:49
  • $\begingroup$ @Guesswhoitis. yes much better agree will update with appropriate (attribution) $\endgroup$
    – ubpdqn
    May 23, 2015 at 5:53
  • $\begingroup$ After putting in the Iverson brackets, you don't need to take signs anymore. :) $\endgroup$ May 23, 2015 at 6:15
  • $\begingroup$ @Guesswhoitis. yes...a result of laziness in copying and worse thought...have corrected now $\endgroup$
    – ubpdqn
    May 23, 2015 at 6:21
1
$\begingroup$
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*)
$\endgroup$
1
$\begingroup$
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]
$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – kirma
    May 23, 2015 at 5:57
  • 1
    $\begingroup$ @kirma, you are right; I just wanted to avoid Tuples for cases where i and j range over a large set. $\endgroup$
    – kglr
    May 23, 2015 at 11:42

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.