03-21-2019, 12:06 PM
Hi All!
I thought of a new class of random numbers! Pick two different approximations of the same function, call them f1(x) and f2(x). Perform the following:
Functions f1(x) and f2(x) should NOT return extremely small or ig values for argumens in [0, 1]. The last calculation step above obtains some numerical noise suitable as random values.
Here is sample code in Excel VBA using two approximations for the Normal CDF:
The resulting numbers have a mean close to 0.5 and standard deviation close to 0.28.
You can use simpler approximations for the Normal or other functions. Ultimately, your choices for f1(x) and f2(x) are HUGE!!!
Namir
I thought of a new class of random numbers! Pick two different approximations of the same function, call them f1(x) and f2(x). Perform the following:
Code:
Using a seed of X in [0,1].
Calculate f1(x) and f2(x).
Calculate D = Abs(f1(x) – f2(x))
Calculate L = fix(log10(Diff)) to remove factional part
Calculate x = Diff / 10 ^ L
Calculate x = Frac(10000 * x)
Functions f1(x) and f2(x) should NOT return extremely small or ig values for argumens in [0, 1]. The last calculation step above obtains some numerical noise suitable as random values.
Here is sample code in Excel VBA using two approximations for the Normal CDF:
Code:
Option Explicit
Function Frac(ByVal x As Double) As Double
Frac = x - Fix(x)
End Function
Function phi3(ByVal x As Double) As Double
' Page 1977
Dim y As Double, Pi As Double
Dim K As Double
Pi = 4 * Atn(1)
K = Sqr(2 / Pi)
y = K * x * (1 + 0.44715 * x * x)
phi3 = 0.5 * (1 + WorksheetFunction.Tanh(y))
End Function
Function phi4(ByVal x As Double) As Double
' Hammaker 1978
Dim y As Double, Pi As Double
Dim K As Double
Pi = 4 * Atn(1)
K = Sqr(2 / Pi)
y = 0.806 * x * (1 - 0.018 * x)
phi4 = 0.5 * (1 + -Sqr(1 - Exp(-y * y)))
End Function
Function Rand34(ByVal x As Double) As Double
Dim Diff As Double
Dim L As Integer
Diff = Abs(phi3(x) - phi4(x))
L = Fix(Log(Diff) / Log(10))
x = Diff / 10 ^ L
x = Frac(10000 * x)
Rand34 = x
End Function
Sub go()
Const max = 10000
Dim x As Double
Dim I As Integer
Randomize Timer
x = Rnd(1)
For I = 1 To max
DoEvents
If x = 0 Then x = Frac(Log(4 * Atn(1) + I) / Log(10))
x = Rand34(x)
Cells(I, 1) = x
Next I
End Sub
The resulting numbers have a mean close to 0.5 and standard deviation close to 0.28.
You can use simpler approximations for the Normal or other functions. Ultimately, your choices for f1(x) and f2(x) are HUGE!!!
Namir