Random number generation
Hi - I'm not sure if this is "specific to C," but I just had a question for all the C/C++ programmers out there.
Currently, in my programs, I generate random numbers using srand() and rand() per usual. However, I am wondering about how good of a random number generator rand() really is. I am beginning to program scientific simulations (thin film nucleation) and I am always a bit nervous about the quality of the results I get.
Is there an accessible, implementable and better random number generator out there? A library or something? Or is rand() good enough? Let me hear your opinions.
rand() generates pseudo-random numbers. The numbers it generates are pretty good, but if you want better random numbers, you could use random() or urandom() if you're on Linux. I'm sure there are other functions in other libraries out there too. (random.org comes to mind.)
It depends on the implementation and your exact requirements, and the C standard does not mandate any particular implementation. The Mersenne Twister is a well known algorithm that you can use, with an implementation available from Prelude's website, but it certainly will not do for a cryptographic PRNG (which you do not seem to require).
The GNU scientific library has a fair number of good PRNGs.
To start from the back, yes, there are other random number generators available. The Mersenne Twister is a good candidate.
However, the question we have to clarify is how you would classify "good" in a random number generator versus a bad one. There are several qualities:
- repeat distance - how many numbers do you need to take out before you get the same sequence of numbers back again?
- spread/variation - if you get a high number, how likely is it that the next number is also high, or much lower - there should be no "pattern" to this.
- Low vs. high bit variability - Do all parts of the number "vary" the equally, or are for example the
- Predictability - If we know what the last few numbers (say 5) are, can we predict what the next number should be?
Of course, some of those variables will be more important than others for a particular system. An encryption mechanism would be more concerned with repeat distance and predictability than spread/variation. Note also the a long repeat distance doesn't necessarily mean a good randomness - just counting a 32-bit number up by 1 each time will get a 4 billion repeat distance, but very predictable.
There is a lot of research on various randum number generators...
Additionally, you may not want the numbers to be evenly distributed, e.g. you may want to have a gaussian distribution (normal/bell-shape distribution) where 50% of samples are in the middle 30% of the range, and much less than average likelyhood to hit the outer 10% of the range.
There are other ways to distribute numbers in a range too.
rand is "even" in it's distribution, that is it's equally likely that you get a number anywhere in the range [or at least, it should be if it's a decent implementation].
The best attempt I've ever seen at a random number generator:
return 4; /* randomly chosen by throw of a dice */
Well, I am not interested in a PRNG for crytographic purposes. Of the 4 criteria matsp listed, spread/variation is most important to me.
I am not sure if a uniform or normal distribution would be better for my purposes - but I would like to try a PRNG with a normal distribution, if there is one readily available. (Does Mersenne twister have normal distribution?)
I am so behind, I don't really have a way of clearly articulating what I'm looking for. My simulations with rand() are reproducing model results just fine, but I want to be sure that I'm not overlooking any significant "hidden" biases or issues stemming from use of rand(). I really don't know anything about rand() - but somehow, I don't think that other, mainstream, "scientific" simulations of interface growth are using rand() for random number generation.
Is rand() good enough, would any of you say? Does it suit you for your purposes?
Sorry for not having a more well-posed problem. I am looking into all the links/suggestions that have been offered so far and I greatly appreciate them.
If you want to try a normal distribution PRNG, there's one in the GNU library, and there's one in Boost/TR1 (at least I'm pretty sure it's in TR1).
That said, you have to ask yourself what your random number is supposed to mean in the context of thin film nucleation -- is it supposed to be normal? Uniform? Etc.
Despite some of the pulicity, I don't believe rand() is BAD. It is not great either, but for most intents and purposes, and given a good seed (such as time with good spread - don't expect it to give you good variation if you run the same program 60 times in the same minute).
Obviously, as tabstop says, you need to understand what the distribution is like in reality when using random numbers for simulations - it would be rather silly to have a uniform distribution to simulate for example human height - the distribution should be "normal". On the other hand, distribution of throwing a dice should be uniform, because 1, 2, or 6 is equally likely to happen.
I found this:
Not sure how useful it is.