samedi 4 décembre 2021

Creating a simple one-dimensional Sobol sequence generator

A Sobol sequence, a series of low-discrepancy quasi-random numbers in range [0,1], can be generated by first initializing a vector of direction numbers:

Dim V(31) As ULong
For i = 1 To 31
  V(i-1) = 2 ^ (32 - i)
Next

and then by fetching each number by continually looping through the enumeration below:

For Each lnumber As ULong In Sobol(V)
   MessageBox.Show(lnumber / 2 ^ 32)
Next

The above loop can be used to generate up to 2^32 values, which is the typical period of a linear congruential generator.

The question is, how can individual Sobol numbers be pulled from Sobol() without using a loop, and instead obtaining one number at a time from a single call-out to the function? The idea would be to instantiate a public class, anywhere in my code, like

Dim ran As New SobolNumber()

and then calling for the next number using for example:

Dim x as Double
x = ran.NextSobolNumber

The Sobol() function and required Ruler() function are listed below:

Public Iterator Function Sobol(ByVal v() As ULong) As IEnumerable(Of ULong)
    Dim s As ULong = 0
    For Each r In Ruler()
        Yield s = s Xor v(r)
    Next r
End Function

Public Iterator Function Ruler() As IEnumerable(Of Integer)
    Yield 0
    For Each r In Ruler()
        Yield r + 1
        Yield 0
    Next r
End Function



Aucun commentaire:

Enregistrer un commentaire