Skip to content

Commit

Permalink
some tests, fix bug in delete!
Browse files Browse the repository at this point in the history
  • Loading branch information
abraunst committed Apr 13, 2024
1 parent 18a7061 commit e129e03
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This small package contains:
* `c::Cavity(a::Accumulator)`: keeps a live-updated `cavity` of `a`.
* Create it with `c = cavity(a::Accumulator)`.
* Retrieval `c[i]` takes time `O(log N)`.
*`collect(c)` takes time `O(N)` (but is slower than `cavity(v::Vector)`).
* `collect(c)` takes time `O(N)` (but is slower than `cavity(v::Vector)`).


* `Q::ExponentialQueueDict{K}()`: `Dict`-like interface to a collection of events with associated independent probability rates, intended for sampling on a Gillespie-like scheme.
Expand Down
30 changes: 25 additions & 5 deletions src/exponentialqueue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,18 @@ function ExponentialQueueDict{K}() where K
ExponentialQueueDict(acc, cumsum(acc), Dict{K,Int}(), K[])
end

function ExponentialQueueDict(v::AbstractVector{Pair{K,Float64}}) where K
acc = Accumulator(last.(v))
ExponentialQueueDict(acc, cumsum(acc), Dict(k=>i for (i,(k,_)) in pairs(v)), first.(v))
function ExponentialQueueDict(v)
acc = Accumulator([r for (_,r) in v])
ExponentialQueueDict(acc, cumsum(acc), Dict(k=>i for (i,(k,_)) in enumerate(v)), [i for (i,_) in v])
end

ExponentialQueueDict(D::Dict{K,Float64}) where K = ExponentialQueueDict(collect(D))

ExponentialQueueDict() = ExponentialQueueDict{Any}()

Dict(e::AbstractExponentialQueue) = Dict(k=>e.acc[i] for (k,i) in pairs(e.idx) if !iszero(e.acc[i]))


function Base.setindex!(e::AbstractExponentialQueue, p, i)
if p <= 0
# do not store null rates
Expand All @@ -117,13 +122,25 @@ Base.haskey(e::ExponentialQueueDict, i) = haskey(e.idx, i)

Base.getindex(e::AbstractExponentialQueue, i) = haskey(e, i) ? e.acc[e.idx[i]] : 0.0

function Base.delete!(e::AbstractExponentialQueue, i)


function _delete!(e::AbstractExponentialQueue, i)
l, k = e.idx[i], e.ridx[length(e.acc)]
e.acc[l] = e.acc.sums[1][end]
e.idx[k], e.ridx[l] = l, k
e.idx[i] = 0
pop!(e.acc)
pop!(e.ridx)
end

function Base.delete!(e::ExponentialQueueDict, i)
_delete!(e, i)
delete!(e.idx, i)
e
end

function Base.delete!(e::ExponentialQueue, i)
_delete!(e, i)
e.idx[i] = 0
e
end

Expand Down Expand Up @@ -166,3 +183,6 @@ function Base.empty!(e::ExponentialQueueDict)
empty!(e.ridx)
empty!(e.acc)
end


Base.:(==)(e1::AbstractExponentialQueue, e2::AbstractExponentialQueue) = (Dict(e1) == Dict(e2))
10 changes: 10 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ end

@testset "ExponentialQueueDict" begin
e = ExponentialQueueDict{String}()
e["event1"] = 5
e["event1"] = 0
@test !haskey(e, "event1")
e["event1"] = 10
@test e["event2"] == 0
@test !haskey(e, "event2")
Expand All @@ -109,6 +112,13 @@ end
e[1000] = 10
empty!(e)
@test isempty(e)
e1 = ExponentialQueueDict{Symbol}()
events = [:a => 1.0, :b => 2.0, :c => 3.0]
for (k,r) in events
e1[k] = r
end
e2 = ExponentialQueueDict(events)
@test e1 == e2
end

nothing

0 comments on commit e129e03

Please sign in to comment.