Re: Gaussian distribution

new topic     » topic index » view thread      » older message » newer message

CK,
The following gives you exact probabilities rather fast for arbitrary outco=
me,
dice nu=F9bers and regular dice shapes.

Contrary to earlier bad habits, I tested it before posting :)

For q>15 or 20, the gaussian approx is probably faster, and is precise enou=
gh.
The usual n=12 limitation is caused by the fact that 13! needs too many b=
its.
The floor value for the gaussian approximation to be good enough depends on=

the number of dice actually.

type pint(integer n) return n>0 end type

constant PMAX=170
--the biggest integer q such that q! fits into a atom, or nearly so

function gpart(pint p, pint q, pint r)
--return a list of all partitions of p in q parts, each of them not more th=
an r
sequence res,s integer k0
if p>q*r or p<q then return {} end if
if p=q then return {{{1,p}}} end if
if p=1 then
    if q=1 then return {{{1,1}}} else return {} end if
end if
if q=1 then
    if p<=r then return {{{p,1}}} else return {} end if
end if
if r=1 then return {{{1,p}}} end if
k0=(remainder(p,r)=0)
if p=q*r then res={{{r,q}}}
else res={}
end if
for i=1 to floor(p/r)-k0 do
     s=gpart(p-i*r,q-i,r-1)
     if i>0 then for j=1 to length(s) do
        s[j]=append(s[j],{r,i})
     end for end if
     res &= s
end for
res &= gpart(p,q,r-1)   --the i=0 case
return res
end function

global function chance(pint p,pint q,pint r)
--what's the chance to get p as the sum of q balanced dice with r faces
--numbered 1..r?
atom a,a0,a1
sequence res
pint p2,pmax
sequence fact
if p>q*r or p<q then return 0 end if
pmax=p
if pmax>PMAX then pmax=PMAX end if
fact=repeat(1,pmax)
for i=2 to pmax do fact[i]=i*fact[i-1] end for
a1=1/r
if q=1 then return a1
elsif q=2 then
    if p>r+1 then p=2*r+1-p end if
    return p*a1*a1
end if
a0=q/r a=a0*a1
for i=2 to q-1 do a0-=a1 a*=a0 end for
a0=0
res=gpart(p,q,r)
for i=1 to length(res) do
     a1=a
     for j=1 to length(res[i]) do
        p2=res[i][j][2]
        if p2>1 then
           if p2<=pmax then a1/=fact[p2]
           else
              a1/=fact[pmax]
              for k=pmax+1 to p2 do a1/=k end for
           end if
        end if
     end for
     a0+=a1
end for
return a0
end function

--some test code
include get.e
atom a a=0
atom a0
for i=5 to 20 do
     a0=chance(i,5,4)
     ?a0
     a+=a0
end for
?a
integer w
w=wait_key()


CChris

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu