Skip to content

Commit

Permalink
Add Base.similar, merge and merge! for Histogram (#270)
Browse files Browse the repository at this point in the history
* Add Base.similar, merge and merge! for Histogram

* Use zero(h::Histogram) instead of similar(h::Histogram)

Suggested by @andreasnoack.

* Improve tests for zero and merge for Histogram
  • Loading branch information
oschulz authored and andreasnoack committed Jun 6, 2017
1 parent 41a76c2 commit 6d588fa
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/hist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,45 @@ function normalize{T, N, E}(h::Histogram{T, N, E}, aux_weights::Array{T,N}...; m
normalize!(h_fltcp, aux_weights_fltcp..., mode = mode)
(h_fltcp, aux_weights_fltcp...)
end


"""
zero(h::Histogram)
Create a new histogram with the same binning, type and shape of weights
and the same properties (`closed` and `isdensity`) as `h`, with all weights
set to zero.
"""
Base.zero{T,N,E}(h::Histogram{T,N,E}) =
Histogram{T,N,E}(deepcopy(h.edges), zero(h.weights), h.closed, h.isdensity)


"""
merge!(target::Histogram, others::Histogram...)
Update histogram `target` by merging it with the histograms `others`. See
`merge(histogram::Histogram, others::Histogram...)` for details.
"""
function Base.merge!(target::Histogram, others::Histogram...)
for h in others
target.edges != h.edges && throw(ArgumentError("can't merge histograms with different binning"))
size(target.weights) != size(h.weights) && throw(ArgumentError("can't merge histograms with different dimensions"))
target.closed != h.closed && throw(ArgumentError("can't merge histograms with different closed left/right settings"))
target.isdensity != h.isdensity && throw(ArgumentError("can't merge histograms with different isdensity settings"))
end
for h in others
target.weights .+= h.weights
end
target
end


"""
merge(h::Histogram, others::Histogram...)
Construct a new histogram by merging `h` with `others`. All histograms must
have the same binning, shape of weights and properties (`closed` and
`isdensity`). The weights of all histograms are summed up for each bin, the
weights of the resulting histogram will have the same type as those of `h`.
"""
Base.merge(h::Histogram, others::Histogram...) = merge!(zero(h), h, others...)
20 changes: 20 additions & 0 deletions test/hist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,24 @@ end
end


@testset "Histogram zero" begin
h = fit(Histogram, (rand(100), rand(100)), closed=:left)
h2 = @inferred zero(h)
@test all(x -> x0, h2.weights)
@test !(h.weights === h2.weights)
@test h.edges == h2.edges
@test h.closed == h2.closed
@test h.isdensity == h2.isdensity
end


@testset "Histogram merge" begin
histograms = [fit(Histogram, (rand(100), 10 * rand(100)), (0:0.1:1, 0:1:10), closed=:left) for _ in 1:10]
h = zero(histograms[1])
merge!(h, histograms ...)
@test h.weights == (+).((x->x.weights).(histograms)...)
@test (@inferred merge(histograms...)) == h
end


end # @testset "StatsBase.Histogram"

0 comments on commit 6d588fa

Please sign in to comment.