File tree Expand file tree Collapse file tree 1 file changed +44
-10
lines changed
Expand file tree Collapse file tree 1 file changed +44
-10
lines changed Original file line number Diff line number Diff line change 11# Inclusion probabilities
22# Transform weights into first order inclusion probabilities
3- # 1: p(w)=x*w +y
3+ # 1: p(w)=w*x +y
44# 2: Sum constraint: sum(probs)=n => sum(p.(ws))=n
55# 3: Minimum probability constraint: p(w_min)=w_min
6- function inclusion_prob(sampler:: Sampler , n:: Int )
6+ #
7+ # Algebra: y = w_min*(1 - x)
8+ # x = (n - N*w_min) / (sum(ws) - N*w_min) == (n - N*w_min) / (N*(μ - w_min))
9+ function inclusion_prob(sampler:: Sampler , n:: Integer ; highprec:: Bool = false )
710 @views ws = sampler. weights
811 N = length(ws)
9- min_prob = minimum(ws)
10- A = [ sum(ws) N;
11- minimum(ws) 1.0 ]
12- b = [n, min_prob]
13- x, y = A \ b
14- ps = x* ws.+ y
15- return ps
16- end
12+ @assert N > 0 " empty weights"
13+
14+ if ! highprec
15+ wmin = minimum(ws)
16+ μ = mean(ws)
17+ den = N* (μ - wmin)
18+ num = n - N* wmin
19+
20+ # If nearly singular, switch to high precision automatically
21+ if den == 0 || abs(den) ≤ 1e-12 * max(1.0 , abs(N* μ))
22+ return inclusion_prob(sampler, n; highprec= true )
23+ end
1724
25+ x = num / den
26+ y = muladd(- wmin, x, wmin) # y = wmin*(1 - x)
27+ ps = @. muladd(x, ws, y) # p = x*ws + y
28+
29+ return ps
30+ else
31+ # Compute coefficients in high precision, then cast back
32+ ps = let
33+ setprecision(256 ) do
34+ W = big.(ws)
35+ NB = big(N)
36+ nB = big(n)
37+ wmin = minimum(W)
38+ μ = mean(W)
39+ den = NB* (μ - wmin)
40+ num = nB - NB* wmin
41+ @assert den != 0 " Constraints are singular: mean(ws) == w_min"
42+
43+ x = num / den
44+ y = wmin* (1 - x)
45+ T = eltype(ws)
46+ T.( @. x* W + y )
47+ end
48+ end
49+ return ps
50+ end
51+ end
You can’t perform that action at this time.
0 commit comments