45 people like it.
Like the snippet!
Gaussian Random Sequence
Normalized Random sequence generator conforming to the user supplied mean and sigma utilizing a "seed factory" instead of the default time of day. The Gaussian sequence is based on the central limit theory, averages together the flat distribution from the random generator built into .NET. Two examples of using normalRand are given to create infinite sequences of white and brown(ian) noise.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:

open System
// Config for normalRand
// Number of samples to average [4 to 10?] (tails stretch/flatten out as this gets larger)
let nSamples = 10
// Creating Random() w/o a seed uses the time of day so if many are created in
// rapid succession they will all use the same seed resulting in identical
// sequences. seed() utilizes an MT safe single instance of Random() to seed the
// generators below to to avoid this problem.
let seed =
let seedGen = new Random()
(fun () > lock seedGen (fun () > seedGen.Next()))
/// Creates an infinite sequence of gaussian distributed random #'s with mean and std
/// MT safe, but returned sequence is not
/// possible range of (0,sigma) is +sigma*sqrt(3*nSamples)
let normalRand mean sigma =
// calc normalization factors up front & alloc a random()
let norm = sigma * sqrt (3*nSamples>float)
let shift = norm  mean
let scale = 2.0 * norm / (float nSamples)
let randGen = new Random(seed())
// return a gaussian # by averaging another random seq (central limit theory)
let rec gaussAvg n acc =
if n > 0 then gaussAvg (n1) (acc+randGen.NextDouble())
else (acc * scale)  shift
let rec gaussSeq() = seq { yield gaussAvg nSamples 0.0; yield! gaussSeq()}
gaussSeq()
/// Creates an infinite sequece of white noise (mean 0, std 1)
/// MT safe, but returned sequence is not
let whiteNoise = normalRand 0.0 1.0
/// Creates an infinite sequence of brown noise (by integrating white noise)
/// Not normalized since it's infinite
let brownNoise = whiteNoise > Seq.scan (fun acc v > acc+v) 0.0

namespace System
val nSamples : int
Full name: Script.nSamples
val seed : (unit > int)
Full name: Script.seed
val seedGen : Random
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

Random() : unit
Random(Seed: int) : unit
val lock : lockObject:'Lock > action:(unit > 'T) > 'T (requires reference type)
Full name: Microsoft.FSharp.Core.Operators.lock
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
val normalRand : mean:float > sigma:float > seq<float>
Full name: Script.normalRand
Creates an infinite sequence of gaussian distributed random #'s with mean and std
MT safe, but returned sequence is not
possible range of (0,sigma) is +sigma*sqrt(3*nSamples)
val mean : float
val sigma : float
val norm : float
val sqrt : value:'T > 'U (requires member Sqrt)
Full name: Microsoft.FSharp.Core.Operators.sqrt
Multiple items
val float : value:'T > float (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.float

type float = Double
Full name: Microsoft.FSharp.Core.float

type float<'Measure> = float
Full name: Microsoft.FSharp.Core.float<_>
val shift : float
val scale : float
val randGen : Random
val gaussAvg : (int > float > float)
val n : int
val acc : float
Random.NextDouble() : float
val gaussSeq : (unit > seq<float>)
Multiple items
val seq : sequence:seq<'T> > seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq

type seq<'T> = Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val whiteNoise : seq<float>
Full name: Script.whiteNoise
Creates an infinite sequece of white noise (mean 0, std 1)
MT safe, but returned sequence is not
val brownNoise : seq<float>
Full name: Script.brownNoise
Creates an infinite sequence of brown noise (by integrating white noise)
Not normalized since it's infinite
module Seq
from Microsoft.FSharp.Collections
val scan : folder:('State > 'T > 'State) > state:'State > source:seq<'T> > seq<'State>
Full name: Microsoft.FSharp.Collections.Seq.scan
val v : float
More information