mirror of
https://github.com/postgres/postgres.git
synced 2025-10-27 00:12:01 +03:00
Invent random_normal() to provide normally-distributed random numbers.
There is already a version of this in contrib/tablefunc, but it seems sufficiently widely useful to justify having it in core. Paul Ramsey Discussion: https://postgr.es/m/CACowWR0DqHAvOKUCNxTrASFkWsDLqKMd6WiXvVvaWg4pV1BMnQ@mail.gmail.com
This commit is contained in:
@@ -1136,8 +1136,8 @@ getGaussianRand(pg_prng_state *state, int64 min, int64 max,
|
||||
Assert(parameter >= MIN_GAUSSIAN_PARAM);
|
||||
|
||||
/*
|
||||
* Get user specified random number from this loop, with -parameter <
|
||||
* stdev <= parameter
|
||||
* Get normally-distributed random number in the range -parameter <= stdev
|
||||
* < parameter.
|
||||
*
|
||||
* This loop is executed until the number is in the expected range.
|
||||
*
|
||||
@@ -1149,25 +1149,7 @@ getGaussianRand(pg_prng_state *state, int64 min, int64 max,
|
||||
*/
|
||||
do
|
||||
{
|
||||
/*
|
||||
* pg_prng_double generates [0, 1), but for the basic version of the
|
||||
* Box-Muller transform the two uniformly distributed random numbers
|
||||
* are expected to be in (0, 1] (see
|
||||
* https://en.wikipedia.org/wiki/Box-Muller_transform)
|
||||
*/
|
||||
double rand1 = 1.0 - pg_prng_double(state);
|
||||
double rand2 = 1.0 - pg_prng_double(state);
|
||||
|
||||
/* Box-Muller basic form transform */
|
||||
double var_sqrt = sqrt(-2.0 * log(rand1));
|
||||
|
||||
stdev = var_sqrt * sin(2.0 * M_PI * rand2);
|
||||
|
||||
/*
|
||||
* we may try with cos, but there may be a bias induced if the
|
||||
* previous value fails the test. To be on the safe side, let us try
|
||||
* over.
|
||||
*/
|
||||
stdev = pg_prng_double_normal(state);
|
||||
}
|
||||
while (stdev < -parameter || stdev >= parameter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user