4

So, I'm trying to use gmp to some calculations I'm doing, and at some point I need to generate a pseudo random number (prn) from a normal distribution.

Since gmp has a uniform random variable, that already helps a lot. However, I'm finding difficult to choose which method I should use generate the normal distribution from a uniform one. In practice, my problem is that gmp only has simple operations, and so for instance I cannot use cos or erf evaluations, since I would have to implement all by miself.

My question is to what extent can I generate prn from a normal distribution on gmp, and, if it is very difficult, if there is any arbitrary precision lib which already has normal distribution implemented.

As two examples of methods that do not work (retrieved from this question):

Ziggurat algorithm uses evaluation of f, which in this case is an non-integer exponential and thus not supported by gmp.

Box–Muller Transform uses cos and sin, which are not supported by gmp.

Community
  • 1
  • 1
Jorge Leitao
  • 19,085
  • 19
  • 85
  • 121

3 Answers3

1

The Marsaglia polar method would work, if your library has a ln.

Thom Smith
  • 13,916
  • 6
  • 45
  • 91
  • 1
    And a square root, don't forget. Though I suppose one could implement Newton-Raphson to approximate a square root if needed. – Managu Jul 03 '12 at 15:03
1

Combine a library able to generate a random numbers for a N(0,1) distribution as doubles with the uniform generator of GMP.

For instance, suppose your normal generator produced 0x8.F67E33Ap-1

Probably, just a few of those digits are really random, so truncate the number to a fixed number of binary digits (i.e. truncating to 16 bits, 0x8.F67E33Ap-1 => 0x8.F67p-1) and generate a number uniformly in the range [0x8.F67p-1, 0x8.F68p-1)

For a better approximation, instead of using a uniform distribution, you may like to calculate the values of the density function at the interval extremes (double precision is enough here) and generate a random number with the distribution associated to the trapezoid defined by those two values.

Another way to solve that problem is to just generate a table of 1000, 10000 or 100000 mpf values where N(x) becomes 1/n, 2/n, etc. then, use the uniform random generator to select one of these intervals and again, calculate a random number inside the selected interval using a uniform or linear distribution.

salva
  • 9,943
  • 4
  • 29
  • 57
1

I ended up using mpfr which is essentially gmp with some more functionality. It already has a normal distribution implemented.

Jorge Leitao
  • 19,085
  • 19
  • 85
  • 121
  • Indeed; the algorithm MPFR implements was given by [C.F.F. Karney](https://arxiv.org/pdf/1303.6257.pdf). Karney, C.F.F., 2016. Sampling exactly from the normal distribution. ACM Transactions on Mathematical Software (TOMS), 42(1), pp.1-14. – Peter O. Apr 03 '22 at 03:20