Skip to content

Commit cbbf1d4

Browse files
devmotionst--github-actions[bot]
authored
Deprecate implicit obsdim keyword argument (#429)
* Deprecate implicit `obsdim` keyword argument * Fix format * Fix typo * Relax type annotation * Fix tests * Update src/utils.jl Co-authored-by: st-- <[email protected]> * Fix format Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Throw `ArgumentError` instead of assertion * Update Project.toml * Improve docstring of `kernelpdmat` * Update src/utils.jl Co-authored-by: st-- <[email protected]> * Update src/utils.jl Co-authored-by: st-- <[email protected]> * Fix utils.jl * Additional test of `vec_of_vecs` Co-authored-by: st-- <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent f9bbd84 commit cbbf1d4

File tree

19 files changed

+158
-71
lines changed

19 files changed

+158
-71
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "KernelFunctions"
22
uuid = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
3-
version = "0.10.28"
3+
version = "0.10.29"
44

55
[deps]
66
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"

docs/src/design.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,9 @@ In short: many people like matrices, and are familiar with `obsdim`-style keywor
139139
arguments.
140140

141141
All internals are implemented using `AbstractVector`s though, and the `obsdim` interface
142-
is just a thin layer of utility functionality which sits on top of this.
143-
144-
145-
146-
142+
is just a thin layer of utility functionality which sits on top of this. To avoid
143+
confusion and silent errors, we do not favour a specific convention (rows or columns)
144+
but instead it is necessary to specify the `obsdim` keyword argument explicitly.
147145

148146
## [Kernels for Multiple-Outputs](@id inputs_for_multiple_outputs)
149147

src/approximations/nystrom.jl

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ function sampleindex(X::AbstractVector, r::Real)
99
return S
1010
end
1111

12-
@deprecate sampleindex(X::AbstractMatrix, r::Real; obsdim::Integer=defaultobs) sampleindex(
13-
vec_of_vecs(X; obsdim=obsdim), r
14-
) false
12+
@deprecate sampleindex(
13+
X::AbstractMatrix, r::Real; obsdim::Union{Integer,Nothing}=defaultobs
14+
) sampleindex(vec_of_vecs(X; obsdim=obsdim === nothing ? nothing : Int(obsdim)), r) false
1515

1616
function nystrom_sample(k::Kernel, X::AbstractVector, S::AbstractVector{<:Integer})
1717
Xₘ = @view X[S]
@@ -21,8 +21,11 @@ function nystrom_sample(k::Kernel, X::AbstractVector, S::AbstractVector{<:Intege
2121
end
2222

2323
@deprecate nystrom_sample(
24-
k::Kernel, X::AbstractMatrix, S::Vector{<:Integer}; obsdim::Integer=defaultobs
25-
) nystrom_sample(k, vec_of_vecs(X; obsdim=obsdim), S) false
24+
k::Kernel,
25+
X::AbstractMatrix,
26+
S::Vector{<:Integer};
27+
obsdim::Union{Integer,Nothing}=defaultobs,
28+
) nystrom_sample(k, vec_of_vecs(X; obsdim=obsdim === nothing ? nothing : Int(obsdim)), S) false
2629

2730
function nystrom_pinv!(Cs::Matrix{T}, tol::T=eps(T) * size(Cs, 1)) where {T<:Real}
2831
# Compute eigendecomposition of sampled component of K
@@ -97,13 +100,32 @@ function nystrom(k::Kernel, X::AbstractVector, r::Real)
97100
return nystrom(k, X, S)
98101
end
99102

103+
"""
104+
nystrom(k::Kernel, X::AbstractMatrix, S::AbstractVector{<:Integer}; obsdim)
105+
106+
If `obsdim=1`, equivalent to `nystrom(k, RowVecs(X), S)`.
107+
If `obsdim=2`, equivalent to `nystrom(k, ColVecs(X), S)`.
108+
109+
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
110+
"""
100111
function nystrom(
101-
k::Kernel, X::AbstractMatrix, S::AbstractVector{<:Integer}; obsdim::Int=defaultobs
112+
k::Kernel,
113+
X::AbstractMatrix,
114+
S::AbstractVector{<:Integer};
115+
obsdim::Union{Int,Nothing}=defaultobs,
102116
)
103117
return nystrom(k, vec_of_vecs(X; obsdim=obsdim), S)
104118
end
105119

106-
function nystrom(k::Kernel, X::AbstractMatrix, r::Real; obsdim::Int=defaultobs)
120+
"""
121+
nystrom(k::Kernel, X::AbstractMatrix, r::Real; obsdim)
122+
123+
If `obsdim=1`, equivalent to `nystrom(k, RowVecs(X), r)`.
124+
If `obsdim=2`, equivalent to `nystrom(k, ColVecs(X), r)`.
125+
126+
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
127+
"""
128+
function nystrom(k::Kernel, X::AbstractMatrix, r::Real; obsdim::Union{Int,Nothing}=nothing)
107129
return nystrom(k, vec_of_vecs(X; obsdim=obsdim), r)
108130
end
109131

src/matrix/kernelmatrix.jl

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@
55
In-place version of [`kernelmatrix`](@ref) where pre-allocated matrix `K` will be
66
overwritten with the kernel matrix.
77
8-
kernelmatrix!(K::AbstractMatrix, κ::Kernel, X::AbstractMatrix; obsdim::Integer=2)
8+
kernelmatrix!(K::AbstractMatrix, κ::Kernel, X::AbstractMatrix; obsdim)
99
kernelmatrix!(
1010
K::AbstractMatrix,
1111
κ::Kernel,
1212
X::AbstractMatrix,
1313
Y::AbstractMatrix;
14-
obsdim::Integer=2,
14+
obsdim,
1515
)
1616
17-
Equivalent to `kernelmatrix!(K, κ, ColVecs(X))` and
18-
`kernelmatrix(K, κ, ColVecs(X), ColVecs(Y))` respectively.
19-
Set `obsdim=1` to get `RowVecs`.
17+
If `obsdim=1`, equivalent to `kernelmatrix!(K, κ, RowVecs(X))` and
18+
`kernelmatrix(K, κ, RowVecs(X), RowVecs(Y))`, respectively.
19+
If `obsdim=2`, equivalent to `kernelmatrix!(K, κ, ColVecs(X))` and
20+
`kernelmatrix(K, κ, ColVecs(X), ColVecs(Y))`, respectively.
2021
2122
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
2223
"""
@@ -35,12 +36,13 @@ Compute the kernel `κ` for each pair of inputs in `x` and `y`.
3536
Returns a matrix of size `(length(x), length(y))` satisfying
3637
`kernelmatrix(κ, x, y)[p, q] == κ(x[p], y[q])`.
3738
38-
kernelmatrix(κ::Kernel, X::AbstractMatrix; obsdim::Int=2)
39-
kernelmatrix(κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim::Int=2)
39+
kernelmatrix(κ::Kernel, X::AbstractMatrix; obsdim)
40+
kernelmatrix(κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim)
4041
41-
Equivalent to `kernelmatrix(κ, ColVecs(X))` and `kernelmatrix(κ, ColVecs(X), ColVecs(Y))`
42-
respectively.
43-
Set `obsdim=1` to get `RowVecs`.
42+
If `obsdim=1`, equivalent to `kernelmatrix(κ, RowVecs(X))` and
43+
`kernelmatrix(κ, RowVecs(X), RowVecs(Y))`, respectively.
44+
If `obsdim=2`, equivalent to `kernelmatrix(κ, ColVecs(X))` and
45+
`kernelmatrix(κ, ColVecs(X), ColVecs(Y))`, respectively.
4446
4547
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
4648
"""
@@ -52,18 +54,19 @@ kernelmatrix
5254
5355
In place version of [`kernelmatrix_diag`](@ref).
5456
55-
kernelmatrix_diag!(K::AbstractVector, κ::Kernel, X::AbstractMatrix; obsdim::Int=2)
57+
kernelmatrix_diag!(K::AbstractVector, κ::Kernel, X::AbstractMatrix; obsdim)
5658
kernelmatrix_diag!(
5759
K::AbstractVector,
5860
κ::Kernel,
5961
X::AbstractMatrix,
6062
Y::AbstractMatrix;
61-
obsdim::Int=2,
63+
obsdim
6264
)
6365
64-
Equivalent to `kernelmatrix_diag!(K, κ, ColVecs(X))` and
65-
`kernelmatrix_diag!(K, κ, ColVecs(X), ColVecs(Y))` respectively.
66-
Set `obsdim=1` to get `RowVecs`.
66+
If `obsdim=1`, equivalent to `kernelmatrix_diag!(K, κ, RowVecs(X))` and
67+
`kernelmatrix_diag!(K, κ, RowVecs(X), RowVecs(Y))`, respectively.
68+
If `obsdim=2`, equivalent to `kernelmatrix_diag!(K, κ, ColVecs(X))` and
69+
`kernelmatrix_diag!(K, κ, ColVecs(X), ColVecs(Y))`, respectively.
6770
6871
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
6972
"""
@@ -79,11 +82,13 @@ Compute the diagonal of `kernelmatrix(κ, x)` efficiently.
7982
Compute the diagonal of `kernelmatrix(κ, x, y)` efficiently.
8083
Requires that `x` and `y` are the same length.
8184
82-
kernelmatrix_diag(κ::Kernel, X::AbstractMatrix; obsdim::Int=2)
83-
kernelmatrix_diag(κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim::Int=2)
85+
kernelmatrix_diag(κ::Kernel, X::AbstractMatrix; obsdim)
86+
kernelmatrix_diag(κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim)
8487
85-
Equivalent to `kernelmatrix_diag(κ, ColVecs(X))` and
86-
`kernelmatrix_diag(κ, ColVecs(X), ColVecs(Y))` respectively.
88+
If `obsdim=1`, equivalent to `kernelmatrix_diag(κ, RowVecs(X))` and
89+
`kernelmatrix_diag(κ, RowVecs(X), RowVecs(Y))`, respectively.
90+
If `obsdim=2`, equivalent to `kernelmatrix_diag(κ, ColVecs(X))` and
91+
`kernelmatrix_diag(κ, ColVecs(X), ColVecs(Y))`, respectively.
8792
8893
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
8994
"""
@@ -162,10 +167,10 @@ end
162167
# Wrapper methods for AbstractMatrix inputs to maintain obsdim interface.
163168
#
164169

165-
const defaultobs = 2
170+
const defaultobs = nothing
166171

167172
function kernelmatrix!(
168-
K::AbstractMatrix, κ::Kernel, X::AbstractMatrix; obsdim::Int=defaultobs
173+
K::AbstractMatrix, κ::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs
169174
)
170175
return kernelmatrix!(K, κ, vec_of_vecs(X; obsdim=obsdim))
171176
end
@@ -175,12 +180,12 @@ function kernelmatrix!(
175180
κ::Kernel,
176181
X::AbstractMatrix,
177182
Y::AbstractMatrix;
178-
obsdim::Int=defaultobs,
183+
obsdim::Union{Int,Nothing}=defaultobs,
179184
)
180185
return kernelmatrix!(K, κ, vec_of_vecs(X; obsdim=obsdim), vec_of_vecs(Y; obsdim=obsdim))
181186
end
182187

183-
function kernelmatrix::Kernel, X::AbstractMatrix; obsdim::Int=defaultobs)
188+
function kernelmatrix::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs)
184189
return kernelmatrix(κ, vec_of_vecs(X; obsdim=obsdim))
185190
end
186191

@@ -189,7 +194,7 @@ function kernelmatrix(κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim=d
189194
end
190195

191196
function kernelmatrix_diag!(
192-
K::AbstractVector, κ::Kernel, X::AbstractMatrix; obsdim::Int=defaultobs
197+
K::AbstractVector, κ::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs
193198
)
194199
return kernelmatrix_diag!(K, κ, vec_of_vecs(X; obsdim=obsdim))
195200
end
@@ -199,19 +204,21 @@ function kernelmatrix_diag!(
199204
κ::Kernel,
200205
X::AbstractMatrix,
201206
Y::AbstractMatrix;
202-
obsdim::Int=defaultobs,
207+
obsdim::Union{Int,Nothing}=defaultobs,
203208
)
204209
return kernelmatrix_diag!(
205210
K, κ, vec_of_vecs(X; obsdim=obsdim), vec_of_vecs(Y; obsdim=obsdim)
206211
)
207212
end
208213

209-
function kernelmatrix_diag::Kernel, X::AbstractMatrix; obsdim::Int=defaultobs)
214+
function kernelmatrix_diag(
215+
κ::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs
216+
)
210217
return kernelmatrix_diag(κ, vec_of_vecs(X; obsdim=obsdim))
211218
end
212219

213220
function kernelmatrix_diag(
214-
κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim::Int=defaultobs
221+
κ::Kernel, X::AbstractMatrix, Y::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs
215222
)
216223
return kernelmatrix_diag(
217224
κ, vec_of_vecs(X; obsdim=obsdim), vec_of_vecs(Y; obsdim=obsdim)

src/matrix/kernelpdmat.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,13 @@ using .PDMats: PDMat
33
export kernelpdmat
44

55
"""
6-
kernelpdmat(k::Kernel, X::AbstractMatrix; obsdim::Int=2)
76
kernelpdmat(k::Kernel, X::AbstractVector)
87
98
Compute a positive-definite matrix in the form of a `PDMat` matrix (see [PDMats.jl](https://github.com/JuliaStats/PDMats.jl)),
109
with the Cholesky decomposition precomputed.
1110
The algorithm adds a diagonal "nugget" term to the kernel matrix which is increased until positive
1211
definiteness is achieved. The algorithm gives up with an error if the nugget becomes larger than 1% of the largest value in the kernel matrix.
1312
"""
14-
function kernelpdmat::Kernel, X::AbstractMatrix; obsdim::Int=defaultobs)
15-
return kernelpdmat(κ, vec_of_vecs(X; obsdim=obsdim))
16-
end
17-
1813
function kernelpdmat::Kernel, X::AbstractVector)
1914
K = kernelmatrix(κ, X)
2015
Kmax = maximum(K)
@@ -31,3 +26,15 @@ function kernelpdmat(κ::Kernel, X::AbstractVector)
3126
end
3227
return PDMat(K + α * I)
3328
end
29+
30+
"""
31+
kernelpdmat(k::Kernel, X::AbstractMatrix; obsdim)
32+
33+
If `obsdim=1`, equivalent to `kernelpdmat(k, RowVecs(X))`.
34+
If `obsdim=2`, equivalent to `kernelpdmat(k, ColVecs(X))`.
35+
36+
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
37+
"""
38+
function kernelpdmat::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs)
39+
return kernelpdmat(κ, vec_of_vecs(X; obsdim=obsdim))
40+
end

src/utils.jl

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,28 @@ macro check_args(K, param, cond, desc=string(cond))
2121
end
2222
end
2323

24-
function vec_of_vecs(X::AbstractMatrix; obsdim::Int=2)
25-
@assert obsdim (1, 2) "obsdim should be 1 or 2, see docs of kernelmatrix"
26-
if obsdim == 1
27-
RowVecs(X)
24+
function deprecated_obsdim(obsdim::Union{Int,Nothing})
25+
_obsdim = if obsdim === nothing
26+
Base.depwarn(
27+
"implicit `obsdim=2` argument is deprecated and now has to be passed " *
28+
"explicitly to specify that each column corresponds to one observation",
29+
:vec_of_vecs,
30+
)
31+
2
32+
else
33+
obsdim
34+
end
35+
return _obsdim
36+
end
37+
38+
function vec_of_vecs(X::AbstractMatrix; obsdim::Union{Int,Nothing}=nothing)
39+
_obsdim = deprecated_obsdim(obsdim)
40+
if _obsdim == 1
41+
return RowVecs(X)
42+
elseif _obsdim == 2
43+
return ColVecs(X)
2844
else
29-
ColVecs(X)
45+
throw(ArgumentError("`obsdim` keyword argument should be 1 or 2"))
3046
end
3147
end
3248

test/approximations/nystrom.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
@test kernelmatrix(k, X; obsdim=obsdim)
1515
kernelmatrix(nystrom(k, X, collect(1:dims[obsdim]); obsdim=obsdim))
1616
end
17+
@test kernelmatrix(@test_deprecated(nystrom(k, X, 1.0)))
18+
kernelmatrix(nystrom(k, ColVecs(X), 1.0))
19+
@test kernelmatrix(@test_deprecated(nystrom(k, X, 1:5)))
20+
kernelmatrix(nystrom(k, ColVecs(X), 1:5))
1721
end

test/basekernels/fbm.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
v1 = rand(rng, 3)
66
v2 = rand(rng, 3)
77
@test k(v1, v2)
8-
(
8+
(
99
sqeuclidean(v1, zero(v1))^h + sqeuclidean(v2, zero(v2))^h -
1010
sqeuclidean(v1 - v2, zero(v1 - v2))^h
1111
) / 2 atol = 1e-5

test/basekernels/matern.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
k = Matern52Kernel()
4646
@test kappa(k, x) (1 + sqrt(5) * x + 5 / 3 * x^2)exp(-sqrt(5) * x)
4747
@test k(v1, v2)
48-
(
48+
(
4949
1 + sqrt(5) * norm(v1 - v2) + 5 / 3 * norm(v1 - v2)^2
5050
)exp(-sqrt(5) * norm(v1 - v2))
5151
@test kappa(Matern52Kernel(), x) == kappa(k, x)

test/basekernels/piecewisepolynomial.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
@test PiecewisePolynomialKernel(; dim=D) isa PiecewisePolynomialKernel{0}
2121

2222
@test repr(k) ==
23-
"Piecewise Polynomial Kernel (degree = $(degree), ⌊dim/2⌋ = $(div(D, 2)), metric = Euclidean(0.0))"
23+
"Piecewise Polynomial Kernel (degree = $(degree), ⌊dim/2⌋ = $(div(D, 2)), metric = Euclidean(0.0))"
2424

2525
k3 = PiecewisePolynomialKernel(;
2626
degree=degree, dim=D, metric=WeightedEuclidean(ones(D))

test/basekernels/wiener.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
@test k0(v1, v2) minXY
2828
@test k1(v1, v2) 1 / 3 * minXY^3 + 1 / 2 * minXY^2 * euclidean(v1, v2)
2929
@test k2(v1, v2)
30-
1 / 20 * minXY^5 + 1 / 12 * minXY^3 * euclidean(v1, v2) * (X + Y - 1 / 2 * minXY)
30+
1 / 20 * minXY^5 + 1 / 12 * minXY^3 * euclidean(v1, v2) * (X + Y - 1 / 2 * minXY)
3131
@test k3(v1, v2)
32-
1 / 252 * minXY^7 +
32+
1 / 252 * minXY^7 +
3333
1 / 720 *
3434
minXY^4 *
3535
euclidean(v1, v2) *

test/kernels/gibbskernel.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
k_gibbs = GibbsKernel(ell)
99

1010
@test k_gibbs(x, y)
11-
sqrt((2 * ell(x) * ell(y)) / (ell(x)^2 + ell(y)^2)) *
11+
sqrt((2 * ell(x) * ell(y)) / (ell(x)^2 + ell(y)^2)) *
1212
exp(-(x - y)^2 / (ell(x)^2 + ell(y)^2))
1313
end

test/kernels/neuralkernelnetwork.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ using KernelFunctions: NeuralKernelNetwork, LinearLayer, product, Primitive
4343
# Vector input.
4444
@test kernelmatrix_diag(nkn_add_kernel, x0) kernelmatrix_diag(sum_k, x0)
4545
@test kernelmatrix_diag(nkn_add_kernel, x0, x1)
46-
kernelmatrix_diag(sum_k, x0, x1)
46+
kernelmatrix_diag(sum_k, x0, x1)
4747

4848
# ColVecs input.
4949
@test kernelmatrix_diag(nkn_add_kernel, X0) kernelmatrix_diag(sum_k, X0)
5050
@test kernelmatrix_diag(nkn_add_kernel, X0, X1)
51-
kernelmatrix_diag(sum_k, X0, X1)
51+
kernelmatrix_diag(sum_k, X0, X1)
5252
end
5353
@testset "product" begin
5454
nkn_prod_kernel = NeuralKernelNetwork(primitives, product)

test/kernels/transformedkernel.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
@test ktard(v1, v2) == (k ARDTransform(v))(v1, v2)
2020
@test ktard(v1, v2) == k(v .* v1, v .* v2)
2121
@test (k LinearTransform(P') ScaleTransform(s))(v1, v2) ==
22-
((k LinearTransform(P')) ScaleTransform(s))(v1, v2) ==
23-
(k (LinearTransform(P') ScaleTransform(s)))(v1, v2)
22+
((k LinearTransform(P')) ScaleTransform(s))(v1, v2) ==
23+
(k (LinearTransform(P') ScaleTransform(s)))(v1, v2)
2424

2525
@test repr(kt) == repr(k) * "\n\t- " * repr(ScaleTransform(s))
2626

0 commit comments

Comments
 (0)