1
$\begingroup$

Function AppendTo seems to be very slow for generating a lot of scenarios, is there any chance to change it and make it faster?

alphaxt= 100; betaxt=130; 
     q=RandomReal[{0,1},106]
        fun[n0_, q_] := 
         Module[{DD = {}, t = 41, j, a = alphaxt, b = betaxt},
           For[j = 0, j <= t - 1, j++, 
           AppendTo[DD, 
            Min[RandomInteger[
              NegativeBinomialDistribution[a, 
               b/((n0 - Total[DD])*q[[66 + j]] + b)]], n0 - Total[DD]]]]; 
          DD]

SeedRandom[123];
 Map[fun[5000, q] &, Range[5000]]
$\endgroup$
  • $\begingroup$ Why don't you use Table[]? $\endgroup$ – J. M. will be back soon Mar 26 '16 at 0:40
  • $\begingroup$ because of the overflow of memory $\endgroup$ – Radka Mar 26 '16 at 0:44
  • 1
    $\begingroup$ But you are then gradually forming DD anyway… $\endgroup$ – J. M. will be back soon Mar 26 '16 at 0:49
  • $\begingroup$ I typically use Associations now instead of Lists with AppendTo, as they scale better. In this case replacing the list with an Association does not change the timing. I'm inclined to believe that list appending is not the rate determining step in this code. $\endgroup$ – bobthechemist Mar 26 '16 at 2:15
3
$\begingroup$

As J.M. has pointed out: using Table[] is a better idea, or else i modified your code a little bit with the use of Reap[] and Sow[] functions. It is on average 12 seconds faster:

alphaxt = 100; betaxt = 130;
q = RandomReal[{0, 1}, 106];
fun[n0_, q_] := Reap@Module[{t = 41, j, a = alphaxt, b = betaxt},
DD = 0;
For[j = 0, j <= t - 1, j++,
 DD += 
  Sow[Min[RandomInteger[
     NegativeBinomialDistribution[a, 
      b/((n0 - DD)*q[[66 + j]] + b)]], n0 - DD]]
 ];
];

Map[fun[5000, q] &, Range[5000]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.