From this question: a random number generator that gravitates numbers to any given number in the range? I did some research, since I came across such a random number generator before, All I remember was the name "Muller", so I think I found it here:
I can find many of its implementations in other languages, but I cannot correctly implement it in C #.
This page, for example, the Box-Muller Method for generating Gaussian random numbers, says the code should look like this (this is not C #):
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> double gaussian(void) { static double v, fac; static int phase = 0; double S, Z, U1, U2, u; if (phase) Z = v * fac; else { do { U1 = (double)rand() / RAND_MAX; U2 = (double)rand() / RAND_MAX; u = 2. * U1 - 1.; v = 2. * U2 - 1.; S = u * u + v * v; } while(S >= 1); fac = sqrt (-2. * log(S) / S); Z = u * fac; } phase = 1 - phase; return Z; }
Now, here is my implementation above in C #. Note that the conversion gives 2 numbers, hence the trick with the “phase” above. I just discard the second value and return the first.
public static double NextGaussianDouble(this Random r) { double u, v, S; do { u = 2.0 * r.NextDouble() - 1.0; v = 2.0 * r.NextDouble() - 1.0; S = u * u + v * v; } while (S >= 1.0); double fac = Math.Sqrt(-2.0 * Math.Log(S) / S); return u * fac; }
My question is in the following specific scenario, where my code does not return a value in the range from 0 to 1, and I cannot figure out what the source code might look like.
- u = 0.5, v = 0.1
- S becomes
0.5*0.5 + 0.1*0.1 = 0.26 - fac becomes ~
3.22 - Thus, the return value is ~
0.5 * 3.22 or ~ 1.6
It is not within 0 .. 1 .
What am I doing wrong / don't understand?
If I change my code so that instead of multiplying fac by u , I multiply by S , I get a value that ranges from 0 to 1 but has an incorrect distribution (it seems to have a maximum distribution around 0.7-0.8, and then tapers in both directions.)