My function:
sumprob[lst_,size_]:=Sum[Product[x,{x,part}],{part,Tuples[lst,{size}]}];
Example:
sumprob[Range[1, 50, 3], 5]
13865791015625
How might I speed this up?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityFor optimization, worth playing around with and comparing a few different almost identical ways of doing the same thing. What seems like just syntactic sugar can sometimes cost:
In[1]:= sumprobAtCubed[lst__, size_] := Total[Times @@@ Tuples[lst, {size}]]
In[2]:= sumprobAtMap[lst__, size_] := Total[(Times @@ #) & /@ Tuples[lst, {size}]]
In[3]:= AbsoluteTiming[sumprobAtMap[xxx = RandomInteger[{1, 50}, 20], 5]]
Out[3]= {0.743279, 77114156402999}
In[4]:= AbsoluteTiming[sumprobAtCubed[xxx, 5]]
Out[4]= {4.352, 77114156402999}
In[5]:= xxx
Out[5]= {45, 48, 49, 17, 25, 8, 50, 31, 32, 27, 33, 36, 43, 16, 30, 35, 33, 29, 9, 3}
In[6]:= RepeatedTiming[sumprobAtMap[xxx, 5]]
Out[6]= {0.618, 77114156402999}
In[7]:= RepeatedTiming[sumprobAtCubed[xxx, 5]]
Out[7]= {4.3, 77114156402999}
In[8]:= sumprob[lst_, size_] := Sum[Product[x, {x, part}], {part, Tuples[lst, {size}]}];
In[9]:= AbsoluteTiming[sumprob[xxx, 5]] (* Compare with poster's orig *)
Out[9]= {12.4336, 77114156402999}
(V.11.1 Mac OS)
Edit: Thanks ciao -- solving the problem should always win ;-)
In[14]:= AbsoluteTiming[Tr[xxx]^5]
Out[14]= {0.000017, 77114156402999}
sumthing[l_,s_]:=Tr[l]^s;
should do the trick quickly...
$\endgroup$
Although not as fast as ciao's formula the direct computation can be done more quickly like this, assuming the input list is all positive numbers:
sumprob2[lst_, size_] := Tr @ Exp @ Total[Tuples[N @ Log @ lst, {size}], {2}];
sumprob2[Range[1, 50, 3], 5] // Round // RepeatedTiming
{0.0511, 13865791015625}
Reference:
N[#]&
. I.e. Combined with the exp and log games, something like sumprob2[{10^4},5]
will have an error of $O(10^5)$, so best with small integers etc. Still great trick, thanks for sharing! (+1)
$\endgroup$
Aug 11, 2017 at 14:23
Total[Times @@@ Tuples[lst, {size}]]
? $\endgroup$