Skip to content

Commit d4b7976

Browse files
committed
Merge branch 'interface-fix' of https://github.com/jaksle/KernelDensity.jl into interface-fix
2 parents eee2128 + eac3b90 commit d4b7976

File tree

4 files changed

+56
-33
lines changed

4 files changed

+56
-33
lines changed

Project.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@ authors = ["Simon Byrne and various contributors"]
44
version = "0.6.8"
55

66
[deps]
7-
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
87
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
98
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
109
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
1110
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
12-
Loess = "4345ca2d-374a-55d4-8d30-97f9976e7612"
13-
LsqFit = "2fda8390-95c7-5789-9bda-21331edee243"
14-
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
15-
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1611
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
1712

1813
[compat]

src/interp.jl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Interpolations: interpolate, scale
22

3-
struct InterpKDE{K,I} <: AbstractKDE
3+
mutable struct InterpKDE{K,I} <: AbstractKDE
44
kde::K
55
itp::I
66
InterpKDE{K,I}(kde::K, itp::I) where {K,I} = new{K,I}(kde, itp)
@@ -23,10 +23,20 @@ function InterpKDE(kde::BivariateKDE, opts...)
2323
end
2424
InterpKDE(kde::BivariateKDE) = InterpKDE(kde::BivariateKDE, BSpline(Quadratic(Line(OnGrid()))))
2525

26-
pdf(k::UnivariateKDE,x) = pdf(InterpKDE(k),x)
26+
27+
# pdf interface implementation
28+
# it should be consistent with Distributions.pdf
29+
30+
# any dimension
2731
pdf(ik::InterpKDE,x::Real...) = ik.itp(x...)
28-
pdf(ik::InterpKDE,xs::AbstractVector) = [ik.itp(x) for x in xs]
29-
Base.broadcast(::typeof(pdf),k::UnivariateKDE,xs) = InterpKDE(k).itp.(xs)
32+
pdf(ik::InterpKDE, V::AbstractVector) = ik.itp(V...)
33+
pdf(ik::InterpKDE, M::AbstractArray{<:Real, N}) where N = pdf.(ik,eachslice(M, dims=ntuple(i->i+1, N-1)) )
34+
35+
# 1 dimension
36+
pdf(k::UnivariateKDE,x) = pdf(InterpKDE(k),x)
37+
Base.Broadcast.broadcasted(::typeof(pdf),k::UnivariateKDE,xs) = Base.Broadcast.broadcasted(InterpKDE(k).itp, xs)
3038

39+
# 2 dimensions
3140
pdf(k::BivariateKDE,x,y) = pdf(InterpKDE(k),x,y)
32-
pdf(ik::InterpKDE,xs::AbstractVector,ys::AbstractVector) = [ik.itp(x,y) for x in xs, y in ys]
41+
pdf(ik::InterpKDE,xs::AbstractVector,ys::AbstractVector) = ik.itp.(xs,ys')
42+
pdf(k::BivariateKDE, M) = pdf(InterpKDE(k),M)

src/univariate.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ sum(density) * step(x) ≈ 1
1313
1414
$(FIELDS)
1515
"""
16-
struct UnivariateKDE{R<:AbstractRange} <: AbstractKDE
16+
mutable struct UnivariateKDE{R<:AbstractRange} <: AbstractKDE
1717
"Gridpoints for evaluating the density."
1818
x::R
1919
"Kernel density at corresponding gridpoints `x`."

test/interp.jl

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,43 @@
11
using Test
22
using KernelDensity
33

4-
X = randn(100)
5-
Y = randn(100)
6-
7-
k = kde(X)
8-
@test pdf(k, k.x) k.density
9-
10-
k = kde((X,Y))
11-
@test pdf(k, k.x, k.y) k.density
12-
13-
# Try to evaluate the KDE outside the interpolation domain
14-
# The KDE is allowed to be zero, but it should not be greater than the exact solution
15-
k = kde([0.0], bandwidth=1.0)
16-
@test pdf(k, k.x) k.density
17-
@test pdf(k, -10.0) pdf(Normal(), -10.0)
18-
@test pdf(k, +10.0) pdf(Normal(), +10.0)
19-
20-
k = kde(([0.0],[0.0]), bandwidth=(1.0, 1.0))
21-
@test pdf(k, k.x, k.y) k.density
22-
@test pdf(k, -10.0, 0.0) pdf(MvNormal(2, 1.0), [-10.0, 0.0])
23-
@test pdf(k, +10.0, 0.0) pdf(MvNormal(2, 1.0), [+10.0, 0.0])
24-
@test pdf(k, 0.0, -10.0) pdf(MvNormal(2, 1.0), [0.0, -10.0])
25-
@test pdf(k, 0.0, +10.0) pdf(MvNormal(2, 1.0), [0.0, +10.0])
4+
@testset "interpolation computation" begin
5+
X = randn(100)
6+
Y = randn(100)
7+
8+
k = kde(X)
9+
@test pdf.(k, k.x) k.density
10+
11+
k = kde((X,Y))
12+
@test pdf(k, k.x, k.y) k.density
13+
14+
# Try to evaluate the KDE outside the interpolation domain
15+
# The KDE is allowed to be zero, but it should not be greater than the exact solution
16+
k = kde([0.0], bandwidth=1.0)
17+
@test pdf.(k, k.x) k.density
18+
@test pdf(k, -10.0) pdf(Normal(), -10.0)
19+
@test pdf(k, +10.0) pdf(Normal(), +10.0)
20+
21+
k = kde(([0.0],[0.0]), bandwidth=(1.0, 1.0))
22+
@test pdf(k, k.x, k.y) k.density
23+
@test pdf(k, -10.0, 0.0) pdf(MvNormal(2, 1.0), [-10.0, 0.0])
24+
@test pdf(k, +10.0, 0.0) pdf(MvNormal(2, 1.0), [+10.0, 0.0])
25+
@test pdf(k, 0.0, -10.0) pdf(MvNormal(2, 1.0), [0.0, -10.0])
26+
@test pdf(k, 0.0, +10.0) pdf(MvNormal(2, 1.0), [0.0, +10.0])
27+
end
28+
29+
@testset "pdf method interface" begin
30+
k = kde([-1., 1.])
31+
ik = InterpKDE(k)
32+
33+
@test pdf.(k, [0., 1.]) [pdf(k, 0.), pdf(k, 1.)] pdf.(k,[0., 1.]) [pdf(ik, 0.), pdf(ik, 1.)]
34+
@test all( pdf.(k, (0., 1.)) .≈ (pdf(k, 0.), pdf(k, 1.)) )
35+
@test pdf.(k, [0. 1.; 2. -1.]) [pdf(k, 0.) pdf(k, 1.); pdf(k, 2.) pdf(k, -1.)]
36+
37+
k2d = kde(([-1., 1.], [0., 1.]))
38+
ik2d = InterpKDE(k2d)
39+
40+
@test pdf(k2d, [0.5, 0.1]) pdf(k2d, [0.5; 0.1]) pdf(k2d, 0.5, 0.1) pdf(ik2d, 0.5, 0.1)
41+
@test pdf(k2d, [0.5 1.; 0.1 1.]) [pdf(ik2d, 0.5, 0.1), pdf(ik2d, 1., 1.)]
42+
@test pdf(k2d, [0.5; 1. ;;; 0.1; 1.]) [pdf(ik2d, 0.5, 1.) pdf(ik2d, 0.1, 1.)]
43+
end

0 commit comments

Comments
 (0)