I'm a beginner of Prolog. And I'm wondering how to generate normal distributed random numbers in Prolog.
What I know is using the maybe
from library(random)
one can set up the probabilities. But what about when it comes to random distributions?
In general, languages provide you with a uniform distribution over 0 to 1. There are various algorithms for getting from that uniform distribution to another distribution, but this case is particularly common so there are a few ways to do it.
If you need a modest amount of random values in a normal distribution, the Box-Muller transform is a very simple algorithm, it amounts to a little math on a few uniform random values:
random_normal(N) :-
random(U1), random(U2),
Z0 is sqrt(-2 * log(U1)) * cos(2*pi*U2),
Z1 is sqrt(-2 * log(U1)) * sin(2*pi*U2),
(N = Z0 ; N = Z1).
This algorithm consumes two uniform values and produces two normal values. I'm providing both solutions. Other ways of doing this might be better for some applications. For instance, you could use asserta/1
and retract/1
to cache the second value and use it without computing, though messing around in the dynamic store may be about as bad as doing the other work (you'd have to benchmark it). Here's the use:
?- random_normal(Z).
Z = -1.2418135230345024 ;
Z = -1.1135242997982466.
?- random_normal(Z).
Z = 0.6266801862581797 ;
Z = -0.4934840828548163.
?- random_normal(Z).
Z = 0.5525713772053663 ;
Z = -0.7118660644436128.
I'm not greatly confident of this but it may get you over the hump.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With