Page 2 of 2

Gaussian random numbers in C#

Posted: July 26th, 2005, 4:10 pm
by terrorbyte
European81,If you are in C#, you can use the C# Mersenne Twister. It has passed many tests and I believe it is widely used. It is also very easy to implement.Here is the Mersenne Twister Link.Terror

Gaussian random numbers in C#

Posted: July 26th, 2005, 4:31 pm
by European81
Terror and Surutsu:It appears that the .NET generator isn't optimal. Are the problems merely of academic nature or will they cause problems in practise as well? The Mersenne Twister seems interesting and, as you said, quite easy to implement.

Gaussian random numbers in C#

Posted: July 26th, 2005, 4:42 pm
by terrorbyte
European81,Unfortunately they are not of an academic nature. If you are performing a serious Monte Carlo and the random number generator is biased, it will skew (or skewer!) your results. My feeling is that if something is more rigorous and easy to implement, I would use it.Has anyone else had experience with the Mersenne Twister?Terror.

Gaussian random numbers in C#

Posted: July 26th, 2005, 5:40 pm
by European81
Hmm... Of course a bias can be problematic depending on the magnitude. In connection with this I have a hard time understanding what a bias "in the least significant bit" is referring to. Somebody enlighten me

Gaussian random numbers in C#

Posted: July 27th, 2005, 12:54 am
by mic4
Surutsu,System.Random is no congruential RNG, but is using an algorithm by Knuth known as ran3 in Numerical Recipes. I would still recommend to replace it with Mersenne Twister as you have already suggested.

Gaussian random numbers in C#

Posted: July 27th, 2005, 10:12 am
by SouthPark
This is "Ziggurat" algorithm in C#. You may find it useful using System;namespace Entropy.Maths.RandomNumbers{ public class Ziggurat : INormalRandom { private const double LAST_POINT = 3.6541528853610088; private const double AREA = 0.00492867323399; private double[] _x = new double[257]; private double[] _r = new double[256]; private IUniformRandom _random; public Ziggurat(IUniformRandom random) { _random = random; this.Init(); } public double Next { get { while (true) { double u = 2.0 * _random.Next - 1.0; int i = (int)(_random.Next * 256); if (Math.Abs(u) < _r) return u * _x; if (i == 0) return this.GetFromTail(u < 0); double x = u * _x; double f0 = Math.Exp(-0.5 * (_x * _x - x * x)); double f1 = Math.Exp(-0.5 * (_x[i + 1] * _x[i + 1] - x * x)); if (f1 + _random.Next * (f0 - f1) < 1.0) return x; } } } private void Init() { double r = LAST_POINT; double f = Math.Exp(-0.5 * r * r); _x[0] = AREA / f; _x[1] = r; _x[256] = 0; for (int i = 2; i < 256; ++i) { _x = Math.Sqrt(-2.0 * Math.Log(AREA / _x + f)); f = Math.Exp(-0.5 * _x * _x); } for (int i = 0; i < 256; ++i) _r = _x[i + 1] / _x; } private double GetFromTail(bool isNegative) { double x, y; do { x = Math.Log(_random.Next) / LAST_POINT; y = Math.Log(_random.Next); } while (-2.0 * y < x * x); return isNegative ? x - LAST_POINT : LAST_POINT - x; } }}