Skip to content

Commit 12b20e8

Browse files
committed
Add low-level allocating histogram interface
1 parent 210c1cc commit 12b20e8

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

src/histogram.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,32 @@ __hist_eltype(eltypes) = _invunit(typeof(mapreduce(oneunit, *, eltypes)))
135135
_hist_eltype(edges::Tuple{Vararg{AbstractRange}}) = __hist_eltype(map(eltype, edges))
136136
_hist_eltype(edges::Tuple{Vararg{HistEdge}}) = __hist_eltype(map(eltype, edges))
137137

138+
_hist_size(edges::Tuple{Vararg{AbstractRange}}) = map(e -> length(e) - 1, edges)
139+
_hist_size(edges::Tuple{Vararg{HistEdge}}) = map(e -> e.nbin, edges)
140+
141+
function _histogram(binning::AbstractBinning,
142+
data::AbstractVector{<:Tuple{Vararg{Any,N}}},
143+
edges::Tuple{Vararg{HistEdge,N}};
144+
weights::Union{Nothing,<:AbstractVector} = nothing
145+
) where {N}
146+
hist = zeros(_hist_eltype(edges), _hist_size(edges)...)
147+
_histogram!(binning, hist, edges, data, weights)
148+
return hist
149+
end
150+
function _histogram(binning::AbstractBinning,
151+
data::AbstractVector{<:Tuple{Vararg{Any,N}}},
152+
edges::Tuple{Vararg{AbstractRange,N}};
153+
weights::Union{Nothing,<:AbstractVector} = nothing
154+
) where {N}
155+
edges′ = map(HistEdge, edges)
156+
return _histogram(binning, data, edges′; weights)
157+
end
158+
function _histogram(binning::AbstractBinning,
159+
data::AbstractVector{<:Tuple{Vararg{Any,N}}},
160+
edges::Union{<:HistEdge,<:AbstractRange}...;
161+
weights::Union{Nothing,<:AbstractVector} = nothing
162+
) where {N}
163+
return _histogram(binning, data, edges; weights)
164+
end
165+
138166
end # module Histogramming

src/kde.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,9 @@ function estimate(method::AbstractBinningKDE,
398398
info::UnivariateKDEInfo) where {T}
399399
lo, hi, nbins = info.lo, info.hi, info.nbins
400400

401-
f = zeros(_invunit(T), nbins)
402401
data′ = reinterpret(reshape, Tuple{T}, data)
403-
Histogramming._histogram!(_kde2hist_method(method), f,
404-
(Histogramming.HistEdge(lo, hi, nbins),), data′, weights)
405-
402+
f = Histogramming._histogram(_kde2hist_method(method),
403+
data′, (Histogramming.HistEdge(lo, hi, nbins),); weights)
406404
if lo == hi
407405
centers = range(lo, hi, length = 1)
408406
else

test/histogram.jl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const LB = Histogramming.LinearBinning()
8888
end
8989

9090
@testset "Low Level ($(N)D, $style)" for N in 1:3, style in (HB, LB)
91-
using .Histogramming: HistEdge, _histogram!
91+
using .Histogramming: HistEdge, _histogram!, _histogram
9292

9393
edges = ((0.0:0.25:1.0 for _ in 1:N)...,)
9494
edges′ = HistEdge.(edges)
@@ -104,6 +104,9 @@ end
104104
fill!(hist, 0)
105105
_histogram!(style, hist, edges′, x1, nothing)
106106
@test sum(hist) * step(edges[1])^N == 1.0
107+
# compare to the allocating interface
108+
@test hist == _histogram(style, x1, edges′)
109+
@test hist == _histogram(style, x1, edges′; weights = [1])
107110

108111
# out-of-bounds elements are not binned
109112
x0 = [(-1.0, (0.0 for _ in 1:N-1)...,)]
@@ -115,6 +118,15 @@ end
115118
fill!(hist, 0)
116119
@test (@inferred _histogram!(style, hist, edges′, x1, nothing)) === 1.0
117120
@test_broken (@allocated _histogram!(style, hist, edges′, x1, nothing)) == 0
121+
122+
@test (@inferred _histogram(style, x1, edges)) isa Array{Float64,N}
123+
@test (@inferred _histogram(style, x1, edges; weights = [1])) isa Array{Float64,N}
124+
@test (@inferred _histogram(style, x1, edges′)) isa Array{Float64,N}
125+
@test (@inferred _histogram(style, x1, edges′; weights = [1])) isa Array{Float64,N}
126+
@test (@inferred _histogram(style, x1, edges...)) isa Array{Float64,N}
127+
@test (@inferred _histogram(style, x1, edges...; weights = [1])) isa Array{Float64,N}
128+
@test (@inferred _histogram(style, x1, edges′...)) isa Array{Float64,N}
129+
@test (@inferred _histogram(style, x1, edges′...; weights = [1])) isa Array{Float64,N}
118130
end
119131

120132
@testset "Unitful numbers" begin
@@ -128,6 +140,14 @@ end
128140
# verify that the function accepts unitful quantities
129141
@test _histogram!(style, uhist, HistEdge.(uedges), vals, nothing) === 1.0
130142
@test sum(uhist) * mapreduce(step, *, uedges) 1.0 rtol=2eps(1.0)
143+
144+
uhist2 = _histogram(style, vals, uedges)
145+
@test eltype(uhist2) == eltype(uhist)
146+
@test uhist2 == uhist
147+
148+
uhist3 = _histogram(style, vals, uedges...)
149+
@test eltype(uhist3) == eltype(uhist)
150+
@test uhist3 == uhist
131151
end
132152
end
133153

0 commit comments

Comments
 (0)