45 people like it.

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 (n-1) (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

Link:http://fssnip.net/3g
Posted:6 years ago
Author:Tony Lee
Tags: random , sequence