Generate random numbers with gaussian distribution
Posted: Sun Jul 04, 2004 6:15 pm
It's probably not great, but it works. There is also an example attached to the bottom of the procedure.
Code: Select all
#GRANDOM_TEST = 1 ; Set this to zero to disable the test code, anything else to enable it
#M_PI = 3.14159;265358979323846
#GRAND_MAX = 32767 ; Used when generating random numbers
; Name: GRandom
; Synopsis: number = GRandom(mean, std)
; Parameters: mean.f - Center value around which the random numbers will be generated
; std.f - Standard deviation, which controls the range from which the majority of the numbers will be generated
; Returns: number.f - The generated random number
; Globals: None
; Description: Generates a random number using a Gaussian (normal) distribution
; centred around the specified mean point with the given standard deviation
Procedure.f GRandom(mean.f, std.f)
DefType.f u1
DefType.f u2
DefType.w side ; Select with side of the mean we take value from - simply alternates
DefType.f temp
DefType.f number
side = Random(#GRAND_MAX) & 1 ; randomly choose side of curve
temp = Random(#GRAND_MAX) + 1
temp = temp / #GRAND_MAX ; generate random number between 0 and 1 (not including 0!!)
u1 = std * Sqr(Log(temp) * -2) ;
temp = Random(#GRAND_MAX)
temp = temp / #GRAND_MAX ; generate random number between 0 and 1
u2 = temp * 2 * #M_PI ; generate random number between 0 and 2pi
If side
number = u1 * Cos(u2) + mean
Else
number = u1 * Sin(u2) + mean
EndIf
ProcedureReturn number
EndProcedure
; Example starts here
CompilerIf #GRANDOM_TEST<>0
#NUMBER_BINS = 320
Dim bins.w(#NUMBER_BINS)
For number_numbers=0 To 10000
use_bin.f = GRandom(#NUMBER_BINS / 2, 20)
;use_bin.f = Random(#NUMBER_BINS) ; Uncomment this line to see the distribution of the built in random number generator
If use_bin>=0 And use_bin<#NUMBER_BINS
bins(Int(use_bin)) + 1
EndIf
Next
If CreateImage(1, #NUMBER_BINS, 256)=0 : End : EndIf
StartDrawing(ImageOutput())
Box(0, 0, #NUMBER_BINS, 256, RGB(0,0,0))
FrontColor(255, 255, 255)
For current_bin=0 To #NUMBER_BINS-1
;Debug "bin "+Str(current_bin)+": "+Str(bins(current_bin))
Line(current_bin, 0, 0, bins(current_bin))
Next
StopDrawing()
If OpenWindow(0, #CW_USEDEFAULT, #CW_USEDEFAULT, 400, 300, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_TitleBar, "Test")
If CreateGadgetList(WindowID())
ImageGadget(1, 10, 10, 320, 256, ImageID())
EndIf
Repeat
ev.l = WaitWindowEvent()
While ev
Select ev
Case #PB_Event_CloseWindow
quit = 1
EndSelect
ev = WindowEvent()
Wend
Until quit=1
CloseWindow(0)
EndIf
End
CompilerEndIf