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