Performance of random number generator
Show older comments
I'm trying to generate a lognormal random number that is truncated, and the only way that I've seen that I can do that is by first fitting the distribution to the data: pd = fitdist(data,'lognormal');
then truncating it: t = truncate(pd,minw,maxw);
and then creating the random numbers with: r = random(t,1,10000);
The problem I have is that I'm doing this for 100 different values of mu-sigma-pairs, and doing 10,000 simulations, and it is taking forever. I started running the code this morning (10 am) in Matlab R2014b in a server and 8 hours later it is still not done.
Before, I was doing this without truncating the values by using R = lognrnd(mu,sigma), and it only took 1.5 to 2 hours to run the exact same code.
What can I do to make it faster? Is there a way to truncate the random number while using lognrnd?
Thanks for your help
7 Comments
the cyclist
on 5 Oct 2015
It would be helpful if you could post your code, or at least a distilled version that helps us understand the slow part.
Sebastián Acevedo Mejia
on 5 Oct 2015
Edited: Sebastián Acevedo Mejia
on 5 Oct 2015
Kirby Fears
on 5 Oct 2015
Edited: Kirby Fears
on 5 Oct 2015
What do you mean by truncation? Are you simply trying to toss out all random draws that are, say, above the 95th percentile or below the 5th percentile?
Or are you trying to truncate the numerical values themselves, like truncating 2.41223 to 2.4?
Either way this should be pretty easy to accomplish after making your random draws from the lognormal distribution.
R=lognrnd(mu,sigma,1,10000);
Sebastián Acevedo Mejia
on 5 Oct 2015
Kirby Fears
on 5 Oct 2015
Edited: Kirby Fears
on 6 Oct 2015
Instead of assigning a value to numbers outside of your desired range, redraw for those.
replaceIdx = (W > maxw)|(W < minw);
while sum(replaceIdx)>0,
W(replaceIdx) = lognrnd(mu,sigma,1,sum(replaceIdx));
replaceIdx = (W > maxw)|(W < minw);
end
Another solution is to draw way more than you need and keep a random subset that is inside the truncation range.
Sebastián Acevedo Mejia
on 5 Oct 2015
Sebastián Acevedo Mejia
on 7 Oct 2015
Answers (1)
Walter Roberson
on 5 Oct 2015
total_samples_needed = 10000;
have_samples = [];
while true
num_needed_now = total_samples_needed - length(have_samples);
if num_needed_now <= 0; break; end
current_samples = RANDOMGENERATOR(1,num_needed_now);
current_samples(current_samples < Lower_Bound | current_samples > Upper_bound) = [];
have_samples = horzcat(have_samples, current_samples);
end
If you want to make it more efficient, you can ask it to generate 1.1 (or as appropriate) times num_needed_now and at the end discard any unneeded ones you generated. An appropriate multiplication factor would be 1 divided by the cdf between Lower_Bound and Upper_Bound.
RANDOMGENERATOR would be replaced by the appropriate call for your purposes.
2 Comments
Sebastián Acevedo Mejia
on 5 Oct 2015
Walter Roberson
on 5 Oct 2015
Just have the current mu and sigma passed to RANDOMGENERATOR . As long as they do not have to change within a run of total_samples_needed there is no problem.
Categories
Find more on Random Number Generation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!