|
Post by tsh73 on Nov 28, 2019 21:08:22 GMT
Nope. It looks like LB (4.5.1) has exactly the same RND so result is the same
Some other BASIC 58 to 42
QBasic (1.1) - has to change rnd(0) to rnd(1) 13 to 87 Unexpected
QB64 42 to 58
|
|
|
Post by daveylibra on Nov 28, 2019 22:09:40 GMT
So in coin tossing game, if you want to win money betting on series 1, you better agree to pretty long strings ahead of time. Yes, forgetting the question of how RND performs for a moment, I was trying to solve what to me is a paradox- That maths says there are, on average, slightly more series 1, which gives an advantage in a coin tossing game. But, the probability of any single coin toss is 50/50. I know this is a computing forum and not a maths one, but anyone care to think about this?
|
|
|
Post by B+ on Nov 29, 2019 0:46:40 GMT
Yes, I thought about this and the difference that makes a difference is the n trials, n creates a cutoff boundary, no series is allowed to run out once n is hit so the the number of sequences that fit in n vary inversely according to the series length. So we end up seeing more small sequences than what would occur in the wild without borders.
BTW, I keep wanting to use term sequence because a series usually means a sum is involved eg, a Taylor Series.
|
|
|
Post by tsh73 on Nov 29, 2019 4:40:39 GMT
Just in case, g95 (GNU fortran) EDIT please forgive my pigLatinFORTRAN: I used to know it but it was long ago. So I just took BASIC program and beat it until g95 compiler agreed consider it FORTRAN
Total of length 1 2572 Total of length >1 2524. Of 100 seed tests: Times Total of Length 1 was greater than Total of all the other Lengths = 54 Times the Total of all the other lengths was >= Total of length 1 = 46 code dimension N(10000) integer TOTAL(20) integer seed, x, count L1=0 LX=0
do seed = 1,100 call srand(seed)
do X = 1, 10000!'VVVV INT truncates all the junk so integer versus integer comparison VVVV IF (10 * RaND(0) < 5) THEN N(X) = 0 ELSE N(X) = 1 endif enddo
do Nn = 1, 20 TOTAL(Nn)=0 enddo
X = 1 DO WHILE (X < 10000) Nn = N(X) COUNT = 0 DO WHILE (Nn .eq. N(X) .AND. X < 10000) COUNT = COUNT + 1 X = X + 1 ENDDO IF (COUNT < 20) THEN TOTAL(COUNT) = TOTAL(COUNT) + 1 ELSE TOTAL(20) = TOTAL(20) + 1 END IF ENDDO
do Nn = 1, 20 PRINT *, Nn, TOTAL(Nn) enddo
TOT = 0 do Nn = 2, 20 TOT = TOT + TOTAL(Nn) enddo
PRINT *,"" PRINT *,"Seed: ", seed PRINT *,"Total of length 1 ", TOTAL(1) PRINT *,"Total of length >1 ", TOT IF (TOTAL(1) > TOT) THEN L1 = L1 + 1 ELSE LX = LX + 1 end if enddo
PRINT *,"Of ", L1 + LX, " seed tests:" PRINT *, "Times Total of Length 1 was greater than Total of all the other Lengths = ", L1 PRINT *, "Times the Total of all the other lengths was >= Total of length 1 = ", LX
end
|
|
|
Post by tsh73 on Nov 29, 2019 6:37:02 GMT
Did I miss something? Where math says it?
EDIT never mind, I saw this post
|
|
|
Post by tsh73 on Nov 29, 2019 8:03:02 GMT
Ok how I see it 1. JB/LB generator is slightly biased - condition "rnd(0)>0.5" returns more 0s then 1s Like this N=100000 while 1 scan i=i+1 s=s+(rnd(0)>.5) if i mod N = 0 then print i, s, s/i wend
gives (as I am typing it works and works and works) 135000000 67112815 0.49713196 That's about 0.57% off supposed 0.5. 2. Thing you encountered is slightly different kind of flaw - dependence between consecutive calls of RND, checking with same condition N=100000 while 1 scan i=i+1 r = (rnd(0)>.5) s=s+ ( prev = r) prev = r if i mod N = 0 then print i, s, s/i wend
68500000 34602787 0.50515018 that gave me 1.03% Could it be related to first one? I dunno. 3. but discarding every other RND(0) seems help with this particular flaw N=100000 while 1 scan i=i+1 r = (rnd(0)>.5) discard = rnd(0) 'discard every other RND call s=s+ ( prev = r) prev = r if i mod N = 0 then print i, s, s/i wend
61100000 30537225 0.49979092 difference is 0.04 % (discarding does not help with coin bias, though) Now in other BASIC 17600000 8801637 0.500093011 0.02% 18900000 9451500 0.500079365 0.02% 19200000 9600185 0.500009635 0.002% (numbers flow, but first two definitely better then JB/LB) 4. Fair results from a biased coin, Wikipedia (for future reference) N=100000 while 1 i=i+1 [again] scan 'https://en.wikipedia.org/wiki/Fair_coin#Fair_results_from_a_biased_coin '1.Toss the coin twice. '2.If the results match, start over, forgetting both results. '3.If the results differ, use the first result, forgetting the second [startOver] r1 = (rnd(0)>.5) r2 = (rnd(0)>.5) if r1=r2 then [startOver] 'else use r1 s = s+r1 if i mod N = 0 then print i, s, s/i wend
results 10000000 4999093 0.4999093 0.02% So we could have better coin in JB. But it looks like it contains same flaw (probability of next==current is not 0.5 - I've got 0.4961, that's about 0.75% off) 5. It is a flaws in JB/LB RND, not explicitely related to INT vs FLOAT vs DOUBLE. My 4.5 cents
|
|
|
Post by Rod on Nov 29, 2019 12:51:01 GMT
Ok, we know there is a bias in the RNG. It produces too many numbers <.5 than it should. I was thinking the cusp around .5 could be where we hit trouble. But experimenting I see that it produces relatively few numbers at the cusp, so few that it cannot be the float issue has any impact. The numbers are skewed across the entire range.
The double coin toss is an intriguing solution. But my clumsy bias to balance the "bias" works and there seems to be no obvious side effects. This bias was just twice the difference at 1000000 mark.
bias=.002976 N=100000 while 1 scan i=i+1 s=s+(rnd(0)+bias>.5) if i mod N = 0 then print i, s, s/i wend
I am less sure about the series problem. Given its series of 0s or 1s I am not sure how you can say that "heads" is more likely. My code was counting "series" ie two or more 0s or two or more 1s but I don't think that was the question.
|
|
|
Post by B+ on Nov 29, 2019 15:27:30 GMT
<rant> Just an aside- to say JB's rnd() stinks is overkill and offensive. Its small bias has been investigated over the years with just about every statistical tool we users can throw at it. On my web site you'll find examples and for example chi-squared tests done on the output. For 99% of use- usually games- it is fine. And for most 'Monte Carlo' science simulations. For fun look up the history of bad pseudo-random generators, from the likes of Microsoft and IBM. You always have the option of running your JB code in 'big brother' Liberty BASIC, where you can call a Mersenne Twister dll and you'd really struggle to find any bias. ( LB is a free download, but with a nag screen. I'd strongly recommend paying for it- Carl has put thousands of hours into developing his languages and it has not made him rich!) </rant> Here is where I got the impression that Liberty had a better Random Number Generator see 3rd paragraph. tsh73 is pretty resourceful but might of missed this? That thing from Wiki was really interesting, every other RND might be a problem!?!? must be fairly common problem to recommend a fair coin algo! My shuffle routine looking better and better!
|
|
|
Post by B+ on Nov 29, 2019 17:05:31 GMT
Rod, "I am less sure about the series problem. Given its series of 0s or 1s I am not sure how you can say that "heads" is more likely. My code was counting "series" ie two or more 0s or two or more 1s but I don't think that was the question." "
I don't think anyone said heads more likely, we've been saying a "series" of 1 is more likely.
And I am still thinking about that one. I am now thinking the game should be very short, small n sequences, is when a series of length one will dominate, slightly not long sequences. And for small n we can count the perms and see without RND what is what.
|
|
|
Post by B+ on Nov 29, 2019 20:48:40 GMT
OK running through all the permutations of 0s and 1s of sequence length n, here is code that counts length 1 sequences in lengths(0) and all other length sequences in lengths(1) to save us trouble of totaling up all the different lengths.
Here is code running n strings of 0s 1s for n = 1 to 5 to check if code is working (and see how the counts are going on every variation):
for nLength = 1 to 5 scan for perm = 0 to 2 ^ nLength - 1 scan dim lengths(1) 'systematically create a sequence of 0s, 1sn of nlength seq$ = right$(string$("0", nLength); base2$(perm), nLength)
print seq$; '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< comment out for big runs
'now count the series lengths m = 1 while m <= len(seq$) scan match$ = mid$(seq$, m, 1) : l = 0 while mid$(seq$, m, 1) = match$ and m <= len(seq$) scan l = l + 1 : m = m + 1 wend if l = 1 then lengths(0) = lengths(0) + 1 else lengths(1) = lengths(1) + 1 'this will total all the other seq$ lengths end if wend
' >>>>>>>>>>>>>>>> comment out next lines for big > 25? runs print ": This sequence had ";lengths(0);" of length=1 and ";lengths(1); " of length>1, that's plus "; if lengths(0) > lengths(1) then print 1;" for L1." else print 0;" for L1."
if lengths(0) > lengths(1) then L1 = L1 + 1 else LX = LX + 1 next print int(10000*L1/(L1 + LX))/100; "% of perms length "; nLength; " had L1 more times than all other series lengths." print L1 = 0 : LX = 0 next
'this one does not do set limit function base2$(integer) while 2 ^ j <= integer if (integer and 2^j) > 0 then b$ = "1" + b$ else b$ = "0" + b$ j = j + 1 wend base2$ = b$ end function
function string$(char$, ntimes) while n <= ntimes string$ = string$ + char$ n = n + 1 wend end function
Comment out the 2 comment out blocks and run nLengths 1 to 20 or whatever, just know code boggs down around 13 and runs exponentially longer each run after, you might not even want to wait for n = 20.
I don't see Length 1 edging out the sum of all other lengths ever on average, except trivial when n = 1.
|
|
|
Post by tenochtitlanuk on Nov 29, 2019 22:21:25 GMT
Ran runs of one million productions of 0/1, and checked for what I think of as 1-tuples ( ie changes on next char), 2-tuples, 3-tuples, etc. Get close to expected ratios etc- but even one million is still fluctuating, of course. Screen grabs show the JB one calling rnd(), and the LB one calling the Mersenne Twister dll. I too had identified that the last n-tuple may be under-declared, if you terminate before the end of that -tuple. That will be a tiny effect for long sequences. nomainwin
dim bins( 100)
WindowWidth = 480 WindowHeight = 670
open "Digit Sequences" for graphics_nsb as #wg
#wg "trapclose quit" #wg "fill black; down ; flush ; font Courier_New 10 bold"
'for d =1 to 100000 ' test if PRNG takes time to become random!!! ' dummy =rnd( 0) 'next d
open "MersTwistLB" for DLL as #MT
CallDLL #MT, "SeedWithTime", ret as void
previous =int( rnd( 0) *2) ' supply an initial precedent 0 /1 runlength =1 binMax =0 countZeros =0 countOnes =0
scan
op$ =str$( previous)
for x =1 to 1000000 scan b = int( rnd( 0) *2) ' next random 0 /1 'CallDLL #MT, "getRandom", ret as ulong 'b =int( 2 *ret /2^32)
if b =0 then countZeros =countZeros +1 else countOnes =countOnes +1 op$ = op$ +str$( b)
if b <>previous then ' are we following a run of same char? bins( runlength) =bins( runlength) +1 ' | increment appropriate bin previous =b ' if not, | set previous to the new changed state runlength =1 ' | start a new runlength else runlength =runlength +1 ' if so, increment run length end if
if ( x mod 10000) =0 then gosub [display]
next x
#wg "flush ; getbmp scr 1 1 480 670" bmpsave "scr", "sequences" +str$( time$( "seconds")) +".bmp"
wait
sub quit h$ close #MT close #h$ end end sub
[display] #wg "cls ; fill black"
binMax =0 bytesCount =0
for k =1 to 100 ' needed so can scale so left hand side bar always same height if binMax <bins( k) then binMax =bins( k) bytesCount =bytesCount +k *bins( k) next k
totalBinsContent =0
for k =1 to 26 if bins( k) >0 then #wg "color white ; size 6" else_ #wg "color red ; size 4"
#wg "up ; goto "; 20 +k *15; " 590 " #wg "down ; goto "; 20 +k *15; " ";_ 589 -bins( k) *500 /binMax #wg "color black" #wg "up ; goto "; 20 +k *15; " 0" #wg "up" #wg "size 1" totalBinsContent = totalBinsContent +bins( k) next k
#wg "backcolor black ; color white ; up ; goto 50 30 ; down" #wg "\loners total rest"; #wg "\"; bins( 1); " "; totalBinsContent; " ";_ totalBinsContent -bins( 1) #wg "\" #wg "\"; "Ratio-" #wg "\loners /total singles /rest" #wg "\"; using( "#.#####", bins( 1) /totalBinsContent); " ";_ using( "#.#####", bins( 1) /( totalBinsContent -bins( 1))) #wg "\" #wg "\throws" #wg "\"; x
#wg "\" #wg "\Ones Zeros" #wg "\"; countOnes; " "; countZeros
#wg "\"; bytesCount; " examined."
return
By rem/unremming you can run either version. The dll is on my site- and elsewhere.
|
|
|
Post by honkytonk on Dec 1, 2019 11:03:20 GMT
So in coin tossing game, if you want to win money betting on series 1, you better agree to pretty long strings ahead of time. Yes, forgetting the question of how RND performs for a moment, I was trying to solve what to me is a paradox- That maths says there are, on average, slightly more series 1, which gives an advantage in a coin tossing game. But, the probability of any single coin toss is 50/50. I know this is a computing forum and not a maths one, but anyone care to think about this? I submit this to your reflection: What about the 50/50 independent of previous draws? NOMAINWIN WindowWidth = 280: UpperLeftX = 450 WindowHeight = 250: UpperLeftY = 20 BUTTON #w.go, "Go !", [go], UL, 10, 10, 40, 20 BUTTON #w.sto, "Stop !", [stop], UL, 60, 10, 40, 20 BUTTON #w.rep, "Reprends", [ret], UL, 120, 10, 60, 20 TEXTBOX #w.temp, 10 , 60, 40, 25 TEXTBOX #w.tir, 80 , 60, 40, 25 TEXTBOX #w.ntir, 150 , 60, 40, 25 TEXTBOX #w.cumpile, 10 , 115, 40, 25 TEXTBOX #w.cumface, 80 , 115, 40, 25 TEXTBOX #w.totpile, 10 , 165, 40, 25 TEXTBOX #w.totface, 80 , 165, 40, 25 GRAPHICBOX #w.m 5, 5, 265, 210 OPEN "Proba" FOR window_nf AS #w #w, "TRAPCLOSE [closeProba]" #w.m , "down": #w.m , "fill blue" temp=100: #w.temp, str$(temp) #w.m, "color yellow;backcolor blue" #w.m, "Place 5 45": #w.m, "\Tempo Tirage N Tirages" #w.m, "Place 10 105": #w.m, "\Pile Face consécutifs" #w.m, "Place 10 155": #w.m, "\Tot P Tot F" #w.m, "Place 5 155": #w.m, "\Max P Max F" #w.m, "flush" gosub [opr] wait [go] sto=0: ntir=0 #w.temp, "!contents? var$" : temp=val(var$) [ret] if sto=1 then sto=0: wait tir=int(rnd(1)*100) + 1 #w.tir, str$(tir) if tir < 51 then pile=1: tirpile=tir: gosub [pile] end if if tir > 50 then face=1: tirface=tir: gosub [face] end if gosub [pause] goto [ret] wait [pile] face=0: cumface=0: ntir=ntir+1: x=5: #w.ntir, str$(ntir) if pile=oldpile then cumpile=cumpile+1: #w.cumpile, str$(cumpile) end if oldpile=pile if cumpile > oldcumpile then totpile=cumpile: oldcumpile=totpile #w.totpile, str$(totpile) if y > 460 then x=190 ' 480 #r.r, "Place ";x;" ";y: #r.r, "\P: ";str$(totpile);"...";str$(ntir) y=y+20 end if #r.r, "flush" return wait [face] pile=0: cumpile=0: ntir=ntir+1: x=60: #w.ntir, str$(ntir) if face=oldface then cumface= cumface+1: #w.cumface, str$(cumface) end if oldface=face if cumface > oldcumface then totface=cumface: oldcumface=totface #w.totface, str$(totface) if y > 460 then x=250 #r.r, "Place ";x;" ";y: #r.r, "\F: ";str$(totface);"...";str$(ntir) y=y+20 end if #r.r, "flush" return wait [stop] sto=1 wait [pause] timer temp, [temps] wait [temps] timer 0 return wait '************************************** [opr] WindowWidth = 380: UpperLeftX = 30 WindowHeight = 550: UpperLeftY = 20 GRAPHICBOX #r.r 5, 5, 365, 510 OPEN "Résultats" FOR window_nf AS #r res=1 #r, "TRAPCLOSE [closeResult]" #r.r , "down": #r.r , "fill darkblue" #r.r , "color yellow;backcolor darkblue" for yy=10 to 510 step 20 #r.r, "place ";"180";" ";yy: #r.r, "\|" next yy #r.r, "flush" return wait [closeResult] sto=1 CLOSE #r: res=0 CLOSE #w wait [closeProba] if res=1 then close #r CLOSE #w END
|
|
|
Post by tsh73 on Dec 1, 2019 18:08:11 GMT
Err... Just what it is supposed to show?
|
|
|
Post by Rod on Dec 2, 2019 8:55:55 GMT
Yes, needs some explanation. So with a fairer coin toss should you expect heads? Not really, much better off knowing the history.
bias=.002976 for n= 1 to 100000 if (rnd(0)+bias>.5) then t$="H" else t$="T" if t$="H" then heads=heads+1 else tails=tails+1 seq$=right$(seq$,2)+t$ 'print t$,seq$
'always bet heads if t$="H" then s1=s1+1 else s1=s1-1
'always bet tails if t$="H" then s2=s2+1 else s2=s2-1
'bet the opposite if mid$(seq$,2,1)=t$ then s3=s3+1 else s3=s3-1
next print "Heads thrown ";heads print "Tails thrown ";tails print "Always bet heads ";s1 print "Always bet tails ";s2 print "Bet the opposite ";s3
|
|
|
Post by honkytonk on Dec 2, 2019 9:20:36 GMT
Err... Just what it is supposed to show? This shows that the probability of stack or face output depends on the previous outputs, and does not remain at 50/50 whatever the previous outputs as the mathematical theory says.
|
|