Skip to content

Commit

Permalink
add sample_by_weights (tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
lindahua committed Jun 14, 2013
1 parent 7597c3a commit ad9681e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
35 changes: 34 additions & 1 deletion src/Stats.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ module Stats
tiedrank,
weighted_mean,
randshuffle!,
randsample
randsample,
sample_by_weights


# Weighted mean
# NB: Weights should include 1/n factor
Expand Down Expand Up @@ -639,4 +641,35 @@ module Stats

randsample{T}(x::AbstractVector{T}, n::Integer) = x[randsample(1:length(x), n)]


###########################################################
#
# A fast sampling method to sample x ~ p,
# where p is proportional to given weights.
#
# This algorithm performs the sampling without
# computing p (normalizing the weights).
#
# This function is particularly useful in many MCMC
# algorithms.
#
###########################################################

function sample_by_weights(w::Vector{Float64}, totalw::Float64)
n = length(w)
t = rand() * totalw

x = 1
s = w[1]

while x < n && s < t
x += 1
s += w[x]
end
return x
end

sample_by_weights(w::Vector{Float64}) = sample_by_weights(w, sum(w))

end # module

15 changes: 14 additions & 1 deletion test/rands.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ function verify_randsample(r::Matrix{Int}, m::Int, tol::Float64)
end



# rand shuffle

m = 5
Expand Down Expand Up @@ -67,3 +66,17 @@ for i = 1 : n
end
@test verify_randsample(r, m, 0.02)

# sample_by_weights

w = [1., 2., 3., 4.]
n = 1000000

cnts = zeros(Int, 4)
for i = 1 : n
xi = sample_by_weights(w, 10.)
cnts[xi] += 1
end
p = cnts / n
p0 = w / sum(w)
@test all(abs(p - p0) .< 0.01)

0 comments on commit ad9681e

Please sign in to comment.