Skip to content

Commit a026cc9

Browse files
authored
**BREAKING**: Migrate from Requires.jl to package extensions (#591)
* Migrate from Requires.jl to package extensions We drop 1.6 support while we are at it. The minimum to support package extensions would be 1.9, but we will support LTS. * Add note about package extensions
1 parent 652f5c9 commit a026cc9

7 files changed

Lines changed: 82 additions & 53 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ jobs:
2121
matrix:
2222
version:
2323
- '1'
24-
- '1.6'
2524
- 'lts'
2625
os:
2726
- ubuntu-latest

Project.toml

Lines changed: 12 additions & 4 deletions
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.67"
3+
version = "0.11.0"
44

55
[deps]
66
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
@@ -13,14 +13,21 @@ IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6"
1313
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1414
LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
1515
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
16-
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
1716
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
1817
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1918
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
2019
TensorCore = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50"
2120
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2221
ZygoteRules = "700de1a5-db45-46bc-99cf-38207098b444"
2322

23+
[weakdeps]
24+
Kronecker = "2c470bb0-bcc8-11e8-3dad-c9649493f05e"
25+
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
26+
27+
[extensions]
28+
KernelFunctionsKroneckerExt = "Kronecker"
29+
KernelFunctionsPDMatsExt = "PDMats"
30+
2431
[compat]
2532
ChainRulesCore = "1"
2633
Compat = "3.7, 4"
@@ -29,11 +36,12 @@ Distances = "0.10.9"
2936
FillArrays = "0.10, 0.11, 0.12, 0.13, 1"
3037
Functors = "0.1, 0.2, 0.3, 0.4, 0.5"
3138
IrrationalConstants = "0.1, 0.2"
39+
Kronecker = "0.4, 0.5"
3240
LogExpFunctions = "0.2.1, 0.3"
33-
Requires = "1.0.1"
41+
PDMats = "0.11"
3442
SpecialFunctions = "0.8, 0.9, 0.10, 1, 2"
3543
Statistics = "1"
3644
StatsBase = "0.32, 0.33, 0.34"
3745
TensorCore = "0.1"
3846
ZygoteRules = "0.2"
39-
julia = "1.6"
47+
julia = "1.10"

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
99
[compat]
1010
Distances = "0.10"
1111
Documenter = "1"
12-
KernelFunctions = "0.10"
12+
KernelFunctions = "0.11"
1313
Kronecker = "0.4, 0.5"
1414
PDMats = "0.11"
1515
Statistics = "1"

docs/src/api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ NystromFact
8989
```
9090

9191
## Conditional Utilities
92-
To keep the dependencies of KernelFunctions lean, some functionality is only available if specific other packages are explicitly loaded (`using`).
92+
To keep the dependencies of KernelFunctions lean, it uses [package extensions](https://pkgdocs.julialang.org/v1/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)) to
93+
conditionally load some code. In order to enable the following functions, load the required
94+
packages with `using`.
9395

9496
### Kronecker.jl
9597
[*https://github.com/MichielStock/Kronecker.jl*](https://github.com/MichielStock/Kronecker.jl)
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1+
module KernelFunctionsKroneckerExt
2+
3+
using KernelFunctions:
4+
KernelFunctions,
5+
Kernel,
6+
MOKernel,
7+
IndependentMOKernel,
8+
IntrinsicCoregionMOKernel,
9+
IsotopicMOInputsUnion,
10+
MOInputIsotopicByFeatures,
11+
MOInputIsotopicByOutputs,
12+
kernelmatrix,
13+
_mo_output_covariance
14+
using Kronecker: Kronecker
15+
116
# Since Kronecker does not implement `TensorCore.:⊗` but instead exports its own function
217
# `Kronecker.:⊗`, only the module is imported and Kronecker.:⊗ and Kronecker.kronecker are
318
# called explicitly.
4-
using .Kronecker: Kronecker
5-
6-
export kernelkronmat
7-
export kronecker_kernelmatrix
819

920
@doc raw"""
1021
kernelkronmat(κ::Kernel, X::AbstractVector{<:Real}, dims::Int) -> KroneckerPower
@@ -16,8 +27,8 @@ where `D` is given by `dims`.
1627
1728
Requires `Kronecker.jl` and for `iskroncompatible(κ)` to return `true`.
1829
"""
19-
function kernelkronmat::Kernel, X::AbstractVector{<:Real}, dims::Int)
20-
checkkroncompatible(κ)
30+
function KernelFunctions.kernelkronmat::Kernel, X::AbstractVector{<:Real}, dims::Int)
31+
KernelFunctions.checkkroncompatible(κ)
2132
K = kernelmatrix(κ, X)
2233
return Kronecker.kronecker(K, dims)
2334
end
@@ -32,32 +43,12 @@ Returns a `KroneckerProduct` matrix on the grid built with the collection of vec
3243
3344
Requires `Kronecker.jl` and for `iskroncompatible(κ)` to return `true`.
3445
"""
35-
function kernelkronmat::Kernel, X::AbstractVector{<:AbstractVector})
36-
checkkroncompatible(κ)
46+
function KernelFunctions.kernelkronmat::Kernel, X::AbstractVector{<:AbstractVector})
47+
KernelFunctions.checkkroncompatible(κ)
3748
Ks = kernelmatrix.(κ, X)
3849
return reduce(Kronecker.:, Ks)
3950
end
4051

41-
@doc raw"""
42-
iskroncompatible(k::Kernel)
43-
44-
Determine whether kernel `k` is compatible with Kronecker constructions such as [`kernelkronmat`](@ref)
45-
46-
The function returns `false` by default. If `k` is compatible it must satisfy for all ``x, x' \in \mathbb{R}^D`:
47-
```math
48-
k(x, x') = \prod_{i=1}^D k(x_i, x'_i).
49-
```
50-
"""
51-
@inline iskroncompatible::Kernel) = false # Default return for kernels
52-
53-
function checkkroncompatible::Kernel)
54-
return iskroncompatible(κ) || throw(
55-
ArgumentError(
56-
"The chosen kernel is not compatible for Kronecker matrices (see [`iskroncompatible`](@ref))",
57-
),
58-
)
59-
end
60-
6152
function _kernelmatrix_kroneckerjl_helper(
6253
::Type{<:MOInputIsotopicByFeatures}, Kfeatures, Koutputs
6354
)
@@ -79,7 +70,7 @@ Requires Kronecker.jl: Computes the `kernelmatrix` for the `IndependentMOKernel`
7970
`IntrinsicCoregionMOKernel`, but returns a lazy kronecker product. This object can be very
8071
efficiently inverted or decomposed. See also [`kernelmatrix`](@ref).
8172
"""
82-
function kronecker_kernelmatrix(
73+
function KernelFunctions.kronecker_kernelmatrix(
8374
k::Union{IndependentMOKernel,IntrinsicCoregionMOKernel}, x::MOI, y::MOI
8475
) where {MOI<:IsotopicMOInputsUnion}
8576
x.out_dim == y.out_dim ||
@@ -89,22 +80,24 @@ function kronecker_kernelmatrix(
8980
return _kernelmatrix_kroneckerjl_helper(MOI, Kfeatures, Koutputs)
9081
end
9182

92-
function kronecker_kernelmatrix(
83+
function KernelFunctions.kronecker_kernelmatrix(
9384
k::Union{IndependentMOKernel,IntrinsicCoregionMOKernel}, x::MOI
9485
) where {MOI<:IsotopicMOInputsUnion}
9586
Kfeatures = kernelmatrix(k.kernel, x.x)
9687
Koutputs = _mo_output_covariance(k, x.out_dim)
9788
return _kernelmatrix_kroneckerjl_helper(MOI, Kfeatures, Koutputs)
9889
end
9990

100-
function kronecker_kernelmatrix(
91+
function KernelFunctions.kronecker_kernelmatrix(
10192
k::MOKernel, x::IsotopicMOInputsUnion, y::IsotopicMOInputsUnion
10293
)
10394
return throw(
10495
ArgumentError("This kernel does not support a lazy kronecker kernelmatrix.")
10596
)
10697
end
10798

108-
function kronecker_kernelmatrix(k::MOKernel, x::IsotopicMOInputsUnion)
109-
return kronecker_kernelmatrix(k, x, x)
99+
function KernelFunctions.kronecker_kernelmatrix(k::MOKernel, x::IsotopicMOInputsUnion)
100+
return KernelFunctions.kronecker_kernelmatrix(k, x, x)
101+
end
102+
110103
end
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
using .PDMats: PDMat
1+
module KernelFunctionsPDMatsExt
22

3-
export kernelpdmat
3+
using KernelFunctions:
4+
KernelFunctions, Kernel, ColVecs, RowVecs, kernelmatrix, vec_of_vecs, defaultobs
5+
using LinearAlgebra: I, isposdef
6+
using PDMats: PDMat
47

58
"""
69
kernelpdmat(k::Kernel, X::AbstractVector)
@@ -10,7 +13,7 @@ with the Cholesky decomposition precomputed.
1013
The algorithm adds a diagonal "nugget" term to the kernel matrix which is increased until positive
1114
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.
1215
"""
13-
function kernelpdmat::Kernel, X::AbstractVector)
16+
function KernelFunctions.kernelpdmat::Kernel, X::AbstractVector)
1417
K = kernelmatrix(κ, X)
1518
Kmax = maximum(K)
1619
α = eps(eltype(K))
@@ -35,6 +38,10 @@ If `obsdim=2`, equivalent to `kernelpdmat(k, ColVecs(X))`.
3538
3639
See also: [`ColVecs`](@ref), [`RowVecs`](@ref)
3740
"""
38-
function kernelpdmat::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs)
39-
return kernelpdmat(κ, vec_of_vecs(X; obsdim=obsdim))
41+
function KernelFunctions.kernelpdmat(
42+
κ::Kernel, X::AbstractMatrix; obsdim::Union{Int,Nothing}=defaultobs
43+
)
44+
return KernelFunctions.kernelpdmat(κ, vec_of_vecs(X; obsdim=obsdim))
45+
end
46+
4047
end

src/KernelFunctions.jl

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export median_heuristic_transform
3434

3535
export NystromFact, nystrom
3636

37+
export kernelkronmat, kronecker_kernelmatrix, iskroncompatible
38+
export kernelpdmat
39+
3740
export gaborkernel
3841
export spectral_mixture_kernel, spectral_mixture_product_kernel
3942

@@ -54,7 +57,6 @@ using Distances
5457
using FillArrays
5558
using Functors
5659
using LinearAlgebra
57-
using Requires
5860
using SpecialFunctions: loggamma, besselk, polygamma
5961
using IrrationalConstants: logtwo, twoπ, invsqrt2
6062
using LogExpFunctions: softplus
@@ -126,13 +128,31 @@ include("zygoterules.jl")
126128

127129
include("TestUtils.jl")
128130

129-
function __init__()
130-
@require Kronecker = "2c470bb0-bcc8-11e8-3dad-c9649493f05e" begin
131-
include("matrix/kernelkroneckermat.jl")
132-
end
133-
@require PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" begin
134-
include("matrix/kernelpdmat.jl")
135-
end
131+
# Kronecker extension stubs
132+
@doc raw"""
133+
iskroncompatible(k::Kernel)
134+
135+
Determine whether kernel `k` is compatible with Kronecker constructions such as [`kernelkronmat`](@ref)
136+
137+
The function returns `false` by default. If `k` is compatible it must satisfy for all ``x, x' \in \mathbb{R}^D`:
138+
```math
139+
k(x, x') = \prod_{i=1}^D k(x_i, x'_i).
140+
```
141+
"""
142+
@inline iskroncompatible::Kernel) = false
143+
144+
function checkkroncompatible::Kernel)
145+
return iskroncompatible(κ) || throw(
146+
ArgumentError(
147+
"The chosen kernel is not compatible for Kronecker matrices (see [`iskroncompatible`](@ref))",
148+
),
149+
)
136150
end
137151

152+
function kernelkronmat end
153+
function kronecker_kernelmatrix end
154+
155+
# PDMats extension stub
156+
function kernelpdmat end
157+
138158
end

0 commit comments

Comments
 (0)