Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Random Numbers - Uniform,Gaussian(Normal),Poission Distributions

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Random Numbers - Uniform,Gaussian(Normal),Poission Distributions

    Following on from the recent discussion on Combinations and Permutations, There are a couple of other very useful non-uniform distributions that occur in a wide range of situations. I've consolidated the three most common distributions here into three examples.

    IAW forum rules, no discussion here please. Thread to discuss if you want is here:
    https://forum.powerbasic.com/forum/u...-distributions

    1. Uniform Distribution - Generates random permutations or combinations of N numbers selected K at a time. (using Fisher Yates/Knuth Algorithm).

    Code:
    'Generate a series of permutations using Fsher Yates /Knuth shuffle
    'If last parameter is %true, it orders the result so effectively produces a combination.
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "win32API.inc"
    FUNCTION PBMAIN () AS LONG
    LOCAL N,K,lngResult,lngTrials, x,z AS LONG
    LOCAL strResult AS STRING
    lngTrials = 100
    DIM Nums() AS LONG
     K = 5: N = 52
     RANDOMIZE
    FOR z = 1 TO lngTrials
        lngResult = KfromN(k,n,nums(),%true)
        FOR x = 1 TO UBOUND(nums())
          strResult += STR$(nums(x)) & $TAB
        NEXT
       strResult = strResult & $CR
    NEXT
    ? strResult
    END FUNCTION
    
    FUNCTION KfromN( K AS LONG, N AS LONG, Nums() AS LONG,Sorted AS LONG) AS LONG
    #REGISTER NONE
    REGISTER i AS LONG
      IF K > N THEN EXIT FUNCTION
        REDIM Nums(1 TO N)
        FOR i = 1 TO N
            nums(i) = i
        NEXT
        FOR i = 1 TO K
         SWAP Nums(i), Nums(RND(i,N))
        NEXT
        REDIM PRESERVE nums(1 TO K)
        IF sorted THEN ARRAY SORT nums()
      FUNCTION = %True
    END FUNCTION
    2. Poisson Distribution - Given the average number of occurrences of a "rare" event in a period, determines the probability of an event occuring 0,1,2,3,,, times in a period. Code generates a random array of x periods with the number of events in each period.

    Code:
    'Poisson Distribution Random number generator
    'Creates a sequence of random numbers with a Poisson distribution for a specified average value,
    ' See https://en.wikipedia.org/wiki/Poisson_distribution
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
    LOCAL AvgValue AS EXT
    LOCAL flgSorted,lngTotalNumbers,x AS LONG
    LOCAL strResult AS STRING
    LOCAL nums() AS LONG
    
    RANDOMIZE
    'Set values
    AvgValue = 10
    flgSorted = -1  '-1 for true, 0 for false
    lngTotalNumbers = 2000
    
    'Get numbers
    DIM nums(1 TO lngTotalNumbers)
    FOR x = 1 TO lngTotalNumbers
        nums(x) = PoissonRnd(AvgValue)
    NEXT
    
    'Display
    IF flgSorted THEN ARRAY SORT nums()
    FOR x = 1 TO lngTotalNumbers
        strResult += STR$(nums(x)) & " "
    NEXT
    ? strResult
    END FUNCTION
    
    FUNCTION PoissonRnd(AvgVal AS EXT) AS LONG
    LOCAL l,p AS EXT
    LOCAL k AS LONG
    L = 2.718281828459045^-AvgVal:k=0:p=1
    DO
        INCR k
        p = p * RND
    LOOP UNTIL p <= l
    FUNCTION = k-1
    END FUNCTION
    3. Gaussian (Normal) distribution. Knowing the mean and standard deviation, generates a list of values with a normal (bell curve) distribution (either integers or floats)

    Code:
    'Generate an array of Normally distributed numbers
    #COMPILE EXE
    #DIM ALL
    #INCLUDE ONCE "WIN32API.INC"
    
    FUNCTION PBMAIN () AS LONG
     LOCAL NoOfSamples AS LONG
     LOCAL mean, SD AS DOUBLE
     LOCAL x AS LONG
     LOCAL strR AS STRING
     DIM DistCount() AS LONG '
    
    Mean = 100
    SD = 6
    NoOfSamples = 100000
    
     'Get Normally distributed Integers
     DIM nums(NoOfSamples) AS LONG
     GausDistInts(mean,SD,nums())
    
    'Get Normally distributed Floats
    ' DIM nums(NoOfSamples) AS DOUBLE
    ' GausDistFloats(mean,SD,nums())
    
    'Generate list
    ' for x = lbound(nums()) to ubound(nums())
    '     strR += str$(nums(x)) & $cr
    ' next
    ' ? strR
    
    'Display distribution analysis
     ARRAY SORT nums()
     DIM DistCount(nums(LBOUND(nums())) TO nums(UBOUND(nums())))
     FOR x = LBOUND(nums()) TO UBOUND(nums())
         INCR DistCount(nums(x))
     NEXT
     strR = "Mean = " & STR$(mean) & ", SD " & FORMAT$(sd,"#.##") & ", Samples: " & STR$(NoOfSamples) & $CR
     strR+= "Results range from " & STR$(Nums(LBOUND(nums()))) & " to " & STR$(nums(UBOUND(nums()))) & $CR & $CR
      FOR x = LBOUND(Distcount()) TO UBOUND(Distcount())
         strR += STR$(x) & $TAB & STR$(distcount(x)) &  $CR
     NEXT
     ? strR
    END FUNCTION
    
    '====== Gaussian Distributions ========
    FUNCTION GausDistInts(Mean AS DOUBLE,SD AS DOUBLE,nums() AS LONG) AS LONG
      LOCAL GR,pi AS EXT
      LOCAL x AS LONG
      pi= 3.141592653589793
      FOR x = LBOUND(nums()) TO UBOUND(nums())
         'Box Mueller
          GR = SQR(-2*LOG(GetRandomFloat)) * SIN(2*pi*GetRandomFloat)
          nums(x)=gr*sd + mean
      NEXT
    END FUNCTION
    
    FUNCTION GausDistFloats(Mean AS DOUBLE,SD AS DOUBLE,nums() AS DOUBLE) AS LONG
      LOCAL GR,pi  AS EXT
      LOCAL x AS LONG
      pi= 3.141592653589793
      FOR x = LBOUND(nums()) TO UBOUND(nums())
          GR = SQR(-2*LOG(GetRandomFloat)) * SIN(2*pi*GetRandomFloat)
          nums(x)=gr*sd + mean
      NEXT
    END FUNCTION
    
    '========= Higher precision Pseudorandom number generator
    'Courtesy of David Roberts
    FUNCTION GetRandomFloat() AS EXT
    LOCAL hRand, dwResult AS DWORD
      BCryptOpenAlgorithmProvider(hRand, $$BCRYPT_RNG_ALGORITHM, $$NUL, 0)
      BCryptGenRandom(hRand, VARPTR(dwResult), 4, 0)
      BCryptCloseAlgorithmProvider(hRand, 0)
      FUNCTION = dwResult/2^32
    END FUNCTION
    Last edited by Stuart McLachlan; 6 May 2019, 07:04 AM.
Working...
X