Skip to content

Commit 189da4b

Browse files
authored
Improve performance of choose (#123)
1 parent 1a82260 commit 189da4b

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

src/UnweightedSamplingMulti.jl

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -162,29 +162,32 @@ function recompute_skip!(s::MultiAlgRSWRSKIPSampler, n)
162162
return s
163163
end
164164

165+
macro quantile_fast(k)
166+
block = Expr(:block)
167+
firstv = quote
168+
$(esc(:s)) = $(esc(:n)) * $(esc(:p))
169+
$(esc(:q)) = 1. - $(esc(:p))
170+
$(esc(:x)) = 1. + $(esc(:s)) / $(esc(:q))
171+
$(esc(:x)) > $(esc(:nt)) && return 1
172+
end
173+
append!(block.args, firstv.args)
174+
for i in 2:k
175+
nextv = quote
176+
$(esc(:s)) *= ($(esc(:n)) - $i) * $(esc(:p))
177+
$(esc(:q)) *= 1. - $(esc(:p))
178+
$(esc(:x)) += $(esc(:s)) / ($(esc(:q)) * $(factorial(i)))
179+
$(esc(:x)) > $(esc(:nt)) && return $i
180+
end
181+
append!(block.args, nextv.args)
182+
end
183+
return block
184+
end
185+
165186
@inline function choose(rng, n, p)
166187
z = exp(n*log1p(-p))
167188
t = rand(rng, Uniform(z, 1.0))
168-
s = n*p
169-
q = 1-p
170-
x = z + z*s/q
171-
x > t && return 1
172-
s *= (n-1)*p
173-
q *= 1-p
174-
x += (s*z/q)/2
175-
x > t && return 2
176-
s *= (n-2)*p
177-
q *= 1-p
178-
x += (s*z/q)/6
179-
x > t && return 3
180-
s *= (n-3)*p
181-
q *= 1-p
182-
x += (s*z/q)/24
183-
x > t && return 4
184-
s *= (n-4)*p
185-
q *= 1-p
186-
x += (s*z/q)/120
187-
x > t && return 5
189+
nt = t/z
190+
@quantile_fast(8)
188191
return quantile(Binomial(n, p), t)
189192
end
190193

@@ -274,3 +277,5 @@ function ordvalue(s::MultiOrdAlgRSWRSKIPSampler)
274277
return s.value[sortperm(s.ord)]
275278
end
276279
end
280+
281+

0 commit comments

Comments
 (0)