Page 1 of 1

Mersenne twister dll

Posted: Thu Aug 24, 2006 8:44 am
by danraymond
Hades or anyone,

how does one call that MT dll in PB.

I am really needing to generate good random numbers between a range (say between minnumber=250 and maxnumber=500).

I tried simply writing a subroutine that tested Random(maxnumber) and spits out an answer when it gets one between say 250 and 500.

However, because Random() is really running between 0 and 500 and is relatively unbiased as far as I can tell, it actually spits out far too many too close to 150 and my result is therefore biased too low.

In the real program its actually a water demand (litres/person/day) and is accumulated daily over say 150 years!.

If I don't include the random subroutine and simply do the 500 value the accumulated demand is around twice that when the random routine chooses between 75% and 100% (ie between 375 and 500). Thats not correct. it appears the values are far too close to the 375 when the number is spat out of the subroutine

any help mucho grando apprecioso!

Dan Raymond

Posted: Thu Aug 24, 2006 8:54 am
by Trond
The Random() functions itself is not biased. And to get a random number between 250 and 500, use Random(500-250)+250.

Posted: Thu Aug 24, 2006 9:54 am
by mskuma
I agree with Trond. The PB RNG is good quality. I think mT is overkill for this application. Probably mT should only be really necessary if the PB seed range is deemed inadequate, or you need to use a 'known' RNG.

Posted: Thu Aug 24, 2006 10:28 am
by netmaestro
Well - for fun, dunno if it's better or not, but here's what I came up with after downloading that dll:

Code: Select all

OpenLibrary(0,"mt19937ar.dll") 

Debug "Functions:" 
Debug "---------------" 
ExamineLibraryFunctions(0) 
While NextLibraryFunction() 
  Debug LibraryFunctionName() 
Wend 
Debug "" 
Debug "A Test:" 
Debug "---------------" 

CallFunction(0, "init_genrand", timeGetTime_()) 
*genrand31 = GetFunction(0, "genrand_int31") 

Dim nums.d(100) 

For i=1 To 100 
  nums(i) = 250+Int(CallFunctionFast(*genrand31)/#MAXLONG *250) 
Next 
CloseLibrary(0) 

For i=1 To 100
  If nums(i)>=250 And nums(i)<=300
    cc+1
  EndIf
Next

Debug "250-300: "+Str(cc)
cc=0

For i=1 To 100
  If nums(i)>=301 And nums(i)<=350
    cc+1
  EndIf
Next

Debug "301-350: "+Str(cc)
cc=0

For i=1 To 100
  If nums(i)>=351 And nums(i)<=400
    cc+1
  EndIf
Next

Debug "351-400: "+Str(cc)
cc=0

For i=1 To 100
  If nums(i)>=401 And nums(i)<=450
    cc+1
  EndIf
Next

Debug "401-450: "+Str(cc)
cc=0

For i=1 To 100
  If nums(i)>=451 And nums(i)<=500
    cc+1
  EndIf
Next

Debug "451-500: "+Str(cc)
I don't know a lot about random number generation, sorry, but I think it's working correctly if you want to use it. My example shows 100 random numbers between 250 and 500. Guys like mskuma and trond can probably show how to finetune it and maximize the randomness. I just seeded it with timeGetTime_() which probably isn't the best.

[edit] Based on this test, it looks pretty d*mn random to me! (though, seemingly no more random than PB's native PRNG)

Image