2 people like it.

# Simple normally distributed random number generator

There are better (faster, more efficient) ways to do this, F# numerics library for a start, but this is at least interesting. This snippet uses the polar form of the Box-Muller method to generate Normal- (Gaussian-) distributed random numbers as an infinite sequence. The polar form is more efficient than the basic form as it does not rely on trigonometric function calls, but there are far more efficient alogrithms (read harder to implement) e.g. the Ziggurat method (for a later post).

 ``` 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: ``` ``````let normalDistRandom mean stdDev = let rand = new System.Random() let rec polarBoxMullerDist () = seq { let rec getRands () = let u = (2.0 * rand.NextDouble()) - 1.0 let v = (2.0 * rand.NextDouble()) - 1.0 let w = u * u + v * v if w >= 1.0 then getRands() else u, v, w let u, v, w = getRands() let scale = System.Math.Sqrt(-2.0 * System.Math.Log(w) / w) let x = scale * u let y = scale * v yield mean + (x * stdDev); yield mean + (y * stdDev); yield! polarBoxMullerDist () } polarBoxMullerDist () ``````
val normalDistRandom : mean:float -> stdDev:float -> seq<float>

Full name: Script.normalDistRandom
val mean : float
val stdDev : float
val rand : System.Random
namespace System
Multiple items
type Random =
new : unit -> Random + 1 overload
member Next : unit -> int + 2 overloads
member NextBytes : buffer:byte[] -> unit
member NextDouble : unit -> float

Full name: System.Random

--------------------
System.Random() : unit
System.Random(Seed: int) : unit
val polarBoxMullerDist : (unit -> seq<float>)
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val getRands : (unit -> float * float * float)
val u : float
System.Random.NextDouble() : float
val v : float
val w : float
val scale : float
type Math =
static val PI : float
static val E : float
static member Abs : value:sbyte -> sbyte + 6 overloads
static member Acos : d:float -> float
static member Asin : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member BigMul : a:int * b:int -> int64
static member Ceiling : d:decimal -> decimal + 1 overload
static member Cos : d:float -> float
...

Full name: System.Math
System.Math.Sqrt(d: float) : float
System.Math.Log(d: float) : float
System.Math.Log(a: float, newBase: float) : float
val x : float
val y : float