Random numbers
| Seed once | |
| Scalar draws | |
| Fill arrays | |
| Normal via Box-Muller |
Seed once
Seed the generator once at startup so runs differ or repeat on demand. Ask random_seed for the seed size, fill an array with your seed, then put it back. Never run the seeding code before every draw.
program seed_demo
implicit none
integer :: n
integer, allocatable :: seed(:)
call random_seed(size=n)
allocate(seed(n))
seed = 20261006
call random_seed(put=seed)
end program seed_demo
Scalar draws
Random_number fills a scalar or an array with uniform values from 0 up to but excluding 1. One call gives one draw for a scalar variable.
program scalar_demo
implicit none
real :: x
call random_number(x)
print *, x
end program scalar_demo
Fill arrays
Pass a whole array to fill it with one call. Scale and shift the result to move it into the range you need. The code below maps the unit interval onto 5 to 15.
program array_demo
implicit none
real :: a(5)
call random_number(a)
! map unit values onto 5 to 15
a = 5.0 + 10.0 * a
print *, a
end program array_demo
Normal via Box-Muller
Uniform draws become normal draws with the Box-Muller transform. Draw two uniforms, then combine them with log, sqrt, and cos. The result has mean 0 and standard deviation 1. Redraw u1 when it is exactly zero so log never sees zero.
program normal_demo
implicit none
real :: u1, u2, z
real, parameter :: pi = 3.14159265
call random_number(u1)
call random_number(u2)
z = sqrt(-2.0 * log(u1)) * cos(2.0 * pi * u2)
print *, z
end program normal_demo
Next: String tools
Article author: Arthur Isaev