Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate normal distributed random numbers in Prolog?

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?

like image 797
Meow Avatar asked Jun 12 '17 15:06

Meow


1 Answers

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.

like image 101
Daniel Lyons Avatar answered Sep 28 '22 09:09

Daniel Lyons