Sign in to follow this  
Followers 0
Yashied

_GRandom()

6 posts in this topic

#1 ·  Posted (edited)

I recently had the need to generate random numbers that are distributed according to the law of Gauss. The fact that the function Random() generates a uniformly distributed random numbers. Histogram for the function Random() is as follows (in the range from -1 to 1).

 

post_img_006.png

By the way, the histogram for RtlRandomEx() function from ntdll.dll is as follows (much worse than for the Random() function - Mersenne Twister).

 

post_img_009.png

I wrote a function _GRandom() similar to Random(), but returns a numbers that are distributed according to the law of Gauss. I hope that it will be useful for someone.

 

Func _GRandom($Min = 0, $Max = 1, $Variance = Default, $Mean = Default)

    Local $D, $X1, $X2, $Result

    If $Min > $Max Then
        Return SetError(1, 0, 0)
    EndIf
    If $Min = $Max Then
        Return $Min
    EndIf
    If $Mean = Default Then
        $Mean = ($Min + $Max) / 2
    EndIf
    If $Variance = Default Then
        $Variance = ($Max - $Min) / 2
    EndIf
    If ($Mean < $Min) Or ($Mean > $Max) Then
        Return SetError(1, 0, 0)
    EndIf
    If $Variance <= 0 Then
        Return SetError(1, 0, 0)
    EndIf
    Do
        Do
            $X1 = Random(-1, 1)
            $X2 = Random(-1, 1)
            $D = $X1 ^ 2 + $X2 ^ 2
        Until $D <= 1
        $Result = $Mean + $X1 * $Variance * Sqrt(-2 * Log($D) / $D)
    Until ($Result >= $Min) And (($Result <= $Max))
    Return $Result
EndFunc   ;==>_GRandom

$Min

The smallest number to be generated. The default is 0.

$Max

The largest number to be generated. The default is 1.

$Variance

Variance relative to the range that specifies by $Min and $Max parameters.

$Mean

Expected value within the range of $Mim...$Max. The default is the value in the middle of this range - 0.5.

Below shows a histogram for this function.

_GRandom(-1, 1, 0.3, 0)

post_img_007.png

All histograms were drawn by using this function.

Edited by Yashied

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Sorry to be critical, but if you are selectively rejecting numbers based on an upper and lower limit (min,max), then that automatically prevents the distribution from being Gaussian. The true Gaussian integral spans from -∞ to +∞.

What you are doing is rejecting everything outside of +/- 2 SD of the mean. Whilst you may end up with a bell-curve of probability favouring the mean (which is probably useful in itself), it isn't Gaussian.

The most widely accepted true gaussian algorithms are the Box-Muller method and the Ziggurat Method.

[EDIT]

Also, what you term 'variance' is actually standard deviation. For example, this:

_GRandom(0,200,100,100)

should give me a data set with mean = 100 and SD = 10, but it actually gives an SD of 53 ish.

Edited by andybiochem

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

I wrote a function _GRandom() similar to Random(), but returns a numbers that are distributed according to the law of Gauss. I hope that it will be useful for someone.

Your UDF is invalid.

See about the true solution here


The point of world view

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Your UDF is invalid.

See about the true solution here

What exactly it is invalid? The fact that I limited the range of generated values? Histogram says otherwise.

EDIT:

Yes, I know that the Gaussian function is defined at -/+ infinity, but in practice, we use a finite interval.

Edited by Yashied

Share this post


Link to post
Share on other sites

To verify your UDF's distribution try The Kolmogorov–Smirnov test from any statistical tool.

The Kolmogorov–Smirnov test can be modified to serve as a goodness of fit test. In the special case of testing for normality of the distribution, samples are standardized and compared with a standard normal distribution. This is equivalent to setting the mean and variance of the reference distribution equal to the sample estimates, and it is known that using the sample to modify the null hypothesis reduces the power of a test.


The point of world view

Share this post


Link to post
Share on other sites

Using

$s = ""
For $i = 1 to 500
    $s &= _GRandom(50,150,100,100) & @CRLF
Next
ClipPut(StringStripWS($s,2))

...to generate 500 data points with Mean = 100, and SD=10, gives the following analyses...

TEST

Ho: The sampled population is normally distributed

alpha = 0.05

RESULTS

n = 500

Mean = 101.7177478

Standard Deviation = 27.56706523

Variance = 759.9430853

K^2 = 6.26

p = 0.04350404

VERDICT

Reject Ho: The distribution is not normal.

TEST

Ho: The sampled population is normally distributed

alpha = 0.05

RESULTS

n = 500

Mean = 100.1

Standard Deviation = 28.79

Variance = 828.8641

AD = 5.460

P = <0.005

VERDICT

Reject Ho: The distribution is not normal.

TEST

Ho: The sampled population is normally distributed

alpha = 0.05

RESULTS

n = 500

Mean = 100.1

Standard Deviation = 28.79

Variance = 828.8641

RJ = 0.979

P = <0.010

VERDICT

Reject Ho: The distribution is not normal.

TEST

Ho: The sampled population is normally distributed

alpha = 0.05

RESULTS

n = 500

Mean = 100.1

Standard Deviation = 28.79

Variance = 828.8641

KS = 0.064

P = <0.010

VERDICT

Reject Ho: The distribution is not normal.

The only way to get the UDF to pass a test for normality is to set the min and max massively below and above the mean to essentially disable the rejection of the tail-end numbers.

I don't want to put you down; it's a good effort...and can be made statistically correct very easily.


- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0