# # ProbBallsBoxes(k,n,eps) # Probability that n balls thrown randomly over the interval [0,1] # end up leaving none of the k boxes (of width eps) empty # # This is the basic tool to compute scores for Mass Profiles # and other similar problems. # # Gaston H. Gonnet (Dec 6, 2004) # lnProbBallsBoxes := proc( k:{0,posint}, n:nonnegative, eps:positive ) if eps > 1 then error(eps,'epsilon cannot be > 1') elif k=0 then 0 elif eps >= 1/k then error(eps,k,'epsilon cannot be >= 1/k') elif n 1 then error(eps,'epsilon cannot be > 1') elif k=0 then 1 elif eps >= 1/k then error(eps,k,'epsilon cannot be >= 1/k') elif n exp(x)-1; #ln1x := x -> ln(1+x); #P2ne := -2*expx1(ln1x(-e)*n) + expx1(ln1x(-2*e)*n); #expand( P2ne-eval(Pkne,k=2) ); # #P3ne := -3*expx1(ln1x(-e)*n) + 3*expx1(ln1x(-2*e)*n) - expx1(ln1x(-3*e)*n); #expand( P3ne-eval(Pkne,k=3) ); # #for p in [5,10,20,40,80] do # eqns := {}; # to 3 do # t := evalf(ln(P(p,2*p,1/(6*p)))); # eqns := eqns union {t=a0+a1*p+b1/p}; # p := 2*p; # od: # sol := solve( eqns, {a0,a1,b1} ); # ne := -ln(1-exp(subs(sol,a1))); # lprint( evalf(sol,12), evalf(ne,12) ) # od: # ## 3-point interpolation #eqns := { seq( P.i.ne = a1*i + a0 + b1/i, i=[5,6,8] )}; #solve( eqns, {a0,a1,b1} ); # ## 4-point interpolation #eqns := { seq( P.i.ne = a1*i + a0 + b1/i + b3/i^3, i=[5,6,7,8] )}; #solve( eqns, {a0,a1,b1,b3} ); # ## Test recurrence on Pnke (given by looking at what happens with ## the first ball) #Equal := proc( k, n, e ) # (1-k*e)*P(k,n-1,e) + k*e*P(k-1,n-1,e) - P(k,n,e) end: # #P := proc(k,n,e) #if k < 2 then Pe(k,n,e) #elif k>n then 0 #else (1-k*e)*P(k,n-1,e) + k*e*P(k-1,n-1,e) fi #end: # ## Testing (in darwin, producing commands for maple) #to 12 do # n := Rand(1..100); # k := Rand(1..n); # ieps := (k+1)*Rand(1..50); # t := ProbBallsBoxes(k,n,1/ieps); # printf( '(evalf(P(%d,%d,1/%d)) - (%.18g))/(%.18g);\n', # k, n, ieps, t, t ); # od: ## Darwin simulation of ProbCloseMatches #SimProbCloseMatches := proc( n1:posint, n2:posint ) #sts := [seq( Stat('eps for k='.i), i=1..min(n1,n2) )]; #to 100000 do # a1 := Rand(array(numeric,n1)); # a2 := Rand(array(numeric,n2)); # for k to min(n1,n2) do # best := [10]; # for i1 to n1 do for i2 to n2 do if |a1[i1]-a2[i2]| < best[1] then # best := [|a1[i1]-a2[i2]|,i1,i2] fi od od; # sts[k]+best[1]; # #a1[best[2]] := Rand(1e6..1e7); # a2[best[3]] := Rand(2e7..1e8); # od; # od: #sts #end: #SimProbCloseMatches := proc( n1:posint, n2:posint ) #sts := [seq( Stat('eps for k='.i), i=1..min(n1,n2) )]; #to 10000 do # a1 := Rand(array(numeric,n1)); # md := []; # to n2 do # t := Rand(); # md := append( md, seq( |t-i|, i=a1 )) od; # md := sort(md); # for k to min(n1,n2) do sts[k]+md[k] od; # od: #sts #end: