2
$\begingroup$

I want to evaluate a sum in Mathematica of the form

Sum[g[[i,j,k,l,m,n]] x g[[o,p,q,r,s,t]] x (complicated function of the indices i,j etc), {i,0,3}, {j,0,3}, {k,0,3}, {l,0,3}, {m,0,3}, {n,0,3}, {o,0,3}, {p,0,3}, {q,0,3}, {r,0,3}, {s,0,3}, {t,0,3}]

But all these indices range from 0 to 3, so the total number of cases to sum over is 4^12, which will take an unforgiving amount of time. However, barely any elements of the array g[[i,j,k,l,m,n]] are nonzero -- there are probably around 8 nonzero entries -- so I would like to restrict the sum over {i,j,k,l,m,n,o,p,q,r,s,t} to precisely those combinations of indices for which both factors of g are nonzero.

I can't find a way to do this for summation over multiple indices, where the allowed index choices are particular combinations of {i,j,k,l,m,n} as opposed to specific values of each particular index. Any help appreciated!

$\endgroup$
12
  • 3
    $\begingroup$ tried SparseArray and the property "NonzeroPositions"? See also: What are SparseArray Properties? How and when should they be used? $\endgroup$
    – kglr
    Mar 4, 2022 at 23:04
  • 2
    $\begingroup$ @kglr those properties are now documented and this one is referred to as "ExplicitPositions". reference.wolfram.com/language/ref/SparseArray.html#1948657 $\endgroup$
    – Greg Hurst
    Mar 4, 2022 at 23:37
  • $\begingroup$ Thank you very much @GregHurst (didn't know about the v13.0 update). $\endgroup$
    – kglr
    Mar 4, 2022 at 23:42
  • $\begingroup$ @kglr How does that help me evaluate this sum? I understand that I can use NonzeroPositions to determine which elements of my array g are nonzero, but how do I then restrict the sum to only these values of the indices? $\endgroup$ Mar 4, 2022 at 23:43
  • 1
    $\begingroup$ @kglr No, terribly sorry -- I meant that I have a product of three quantities, which are functions of 12 indices, and I want to sum over those indices. I have edited my question to make this clearer!! $\endgroup$ Mar 4, 2022 at 23:47

1 Answer 1

4
$\begingroup$
complicatedFunctionOfIndices = FOO[FromDigits @ Sort @ #, FromDigits @ ReverseSort @#2]&

SeedRandom[1]
myg = RandomChoice[{3000, 1, 1, 1, 1, 1} -> Range[0, 5], {4, 4, 4, 4, 4, 4}];

Dimensions[myg]
{4, 4, 4, 4, 4, 4}
sa = SparseArray[myg]

enter image description here

nonZeroPositions = sa["NonzeroPositions"]
{{1, 1, 3, 3, 4, 3}, {1, 4, 3, 3, 4, 4}, {2, 2, 1, 2, 2, 4}, 
 {4, 2, 1, 2, 1, 4}, {4, 2, 2, 1, 3, 2}}
nonZeroValues = sa["NonzeroValues"]
 {3, 5, 3, 1, 4}
sum = Sum[sa[[## & @@ i]] sa[[## & @@ j]] complicatedFunctionOfIndices[i, j], 
  {i, nonZeroPositions}, {j, nonZeroPositions}]

enter image description here

As expected sum has 25 terms.

We get the same result using Total:

total = Total[sa[[## & @@ #]] sa[[## & @@ #2]] complicatedFunctionOfIndices[##]  & @@@ 
  Tuples[nonZeroPositions, 2]];

sum == total
True

Note: Per Greg Hurt's comment above, replace "NonzeroPositions" with "ExplicitPositions" if you have version 13.0,

$\endgroup$

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.