When doing numerical simulations on a computer, there is often a need for “random” numbers, The most important application where they are needed is probably Monte Carlo simulations, which are used for things like computing approximate ground state wavefunctions and energy eigenvalues for quantum systems, and the calculation of position- and direction-dependent light intensity functions in an optical system where emission, reflection and absorption of light takes place.
The fact about these random numbers is that they are actually not random at all, and should be described as pseudorandom numbers. A digital computer works deterministically, which means that the same input always produces the same result. This situation might change when quantum computing becomes more commonplace. Those who have studied quantum mechanics may remember that if we have a quantum observable (some measurable quantity) that has eigenstates and corresponding to eigenvalues a and b, and we prepare the quantum system to a state
(or more generally any state where and are real numbers), and measure the value of the observable in this state, the result of the measurement can be or with equal probabilities, otherwise being completely random. Here randomness means that it’s not possible to know beforehand which one of the possible values is obtained in any particular repetition of the experiment.
When one sees the sequence with
it seems to be intuitively obvious that it is not something we’d call random, as every number in the sequence is the previous one plus number 1. Neither is the sequence
because it is alternating in sign, with a positive number always being followed by a negative number and vice versa. In addition to the appearance of randomness as evaluated by a human observer, there are also many kinds of statistical tests that can be performed on a sequence to see whether there are correlations between the numbers and (or and etc.).
Fortunately it is quite easy to construct sequences of numbers that lie in some desired interval of the real number line and are otherwise seemingly random, in the sense of not following any obvious logic/pattern. The best-known example of this is probably the behaviour of the sequence of complex numbers
, with .
The numbers in this sequence all lie on the unit circle of the complex plane, and as the difference between and is always incommensurate with the period , the numbers have an appearance of randomness.
The visual evaluation of the randomness of a number sequence is easiest if the x and y coordinates of a set of points on a plane are assigned values from the sequence. To test this, let us make two sequences, and , defined in a way similar to the real and complex components of the function mentioned above:
The factors 7 and 17, constant “phases” 13 and 27 and “offsets” 11 and 23 are something I just “pulled from the hat”, and they could as well be any other set of numbers that don’t have common factors.
Now make a C++ code that prints the coordinates of points from n=1 to n=nmax:
double nmax = 5000;
for(n=1; n<nmax; n++)
printf(“%f %f\n”, sin(13.0 + 7.0 *(n+11)*(n+11)), sin(27.0 + 17.0 * (n+23)*(n+23)));
Suppose this code was compiled into an executable file randnum.exe. Now writing
randnum > out.txt
on the Windows command line (or something equivalent in Linux), print the coordinates in the file “out.txt”.
Next draw the data point in the file in a 2D coordinate system, using Grace or some other graphing program. The results for the values nmax = 5000, nmax = 10000 and nmax = 20000 are below:
The points seem to be rather random except that they are more likely to be near the borders of the rectangle that in the middle. The reason for this is the same as why an oscillating pendulum is most likely to be found near the edges of its trajectory at a randomly chosen moment – the derivative of the sine function with respect to t has its minimum absolute value when the sine function itself is at its maximum or minimum values. To correct this, change the code so that it converts the sine terms back to angles in interval and divides by :
for(n=1; n<nmax; n++)
printf(“%f %f\n”, 2*asin(sin(13.0 + 7.0*(n+11)*(n+11)))/3.141, 2*asin(sin(27.0 + 17.0*(n+23)*(n+23)))/3.141);
Below you see a plot of the data points (x,y) obtained with this code.
Seems to be random enough for most purposes. Note, however, that you have to be careful with what kind of sequence you use when producing pseudorandom numbers in this way. If we do the same thing but use the same number as n-offset in the two sine functions:
for(n=1; n<nmax; n++)
printf(“%f %f\n”, sin(13.0 + 7.0 *(n+11)*(n+11)), sin(27.0 + 17.0 * (n+11)*(n+11)));
the plot of the data points looks like this:
which doesn’t appear random at all.