Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
cdfae04
Adds first version of Intrinsic Coregionalization Multi-Output Kernel.
david-vicente Mar 20, 2021
5e4efc3
Changes the name of the kernel. Removes "implementation code" for the
david-vicente Mar 21, 2021
fa3c124
Adds tests for CoregionMOKernel.
david-vicente Mar 22, 2021
1f89b00
Adds coregion tests to runtests file.
david-vicente Mar 22, 2021
0704989
Adds docstring to coregion kernel.
david-vicente Mar 22, 2021
5574ec9
Update src/mokernels/coregion.jl
david-vicente Mar 22, 2021
ac411ac
Makes notation in docstring conformant with the rest of the package.
david-vicente Mar 22, 2021
4500e21
Makes code respect formating style guidelines.
david-vicente Mar 22, 2021
9796500
Merge branch 'master' of https://github.com/4aHxKzD/KernelFunctions.jl
david-vicente Mar 22, 2021
d4a93c7
Merge remote-tracking branch 'upstream/master'
david-vicente Mar 23, 2021
eaeffb4
Adds Coregion kernel to docs file.
david-vicente Mar 23, 2021
570655c
Merge branch 'JuliaGaussianProcesses:master' into master
david-vicente May 27, 2021
13d2584
Removes unused argument.
david-vicente May 27, 2021
e6311d6
Creates new methods for Finitedifferences.to_vec to deal with the
david-vicente May 27, 2021
a5fc6b2
Creates new methods to compute the jacobian of multioutput kernels.
david-vicente May 27, 2021
13cbe37
Formatting.
david-vicente May 27, 2021
81c2476
Reworkes to_vec so that the reimplementation of _jvp and jacobian is
david-vicente May 28, 2021
72f124e
Renames kernel.
david-vicente May 28, 2021
cbf4cba
Changes all affected files by the kernel renaming.
david-vicente May 28, 2021
30c2a5c
Adds test_interface method to generate inputs for MOkernels.
david-vicente May 28, 2021
8765077
Makes IntrinsicCoregionMOKernel use the standard suit of tests.
david-vicente May 28, 2021
51a0a7e
Improves MOkernels tests to test different outputs dimensions.
david-vicente May 28, 2021
df66dc0
Passes RNG object to rand method.
david-vicente May 28, 2021
936bd94
Adds MOKernel methods for testfunction and testdiagfunction.
david-vicente May 30, 2021
e10059a
Adds test_FiniteDiff method for MOKernels.
david-vicente May 30, 2021
01490b7
Changes test_FiniteDiff for MOKernel signature to have the same number
david-vicente May 31, 2021
2e04b29
Corrects bug in tests where the created covariance matrix between out…
david-vicente May 31, 2021
28d912d
Adapts compare_gradient for MOKernels.
david-vicente May 31, 2021
6bef1b7
Adapts test_AD for MOKernels.
david-vicente May 31, 2021
a6689ad
Adapts test_ADs for MOKernels.
david-vicente May 31, 2021
bc58b16
Corrects type annotation.
david-vicente May 31, 2021
53f4d65
Corrects argument splatting.
david-vicente May 31, 2021
dcabde9
Rewrites variables as named tuple.
david-vicente May 31, 2021
b029763
Updates arguments.
david-vicente May 31, 2021
b31625f
Adds standardised AD tests for IntrinsicCoregionMOKernel.
david-vicente May 31, 2021
4a603e2
Adds include of finitedifferences file to runtests.
david-vicente May 31, 2021
01e31c1
Passes dims argument.
david-vicente May 31, 2021
d823057
Formatting.
david-vicente May 31, 2021
4988667
Formatting.
david-vicente May 31, 2021
f30273e
Corrects a bug where the wrong tuple fields were used.
david-vicente May 31, 2021
bf9d217
Corrects test.
david-vicente Jun 1, 2021
1ac68f6
Implements @theogf approach to testing gradients of MOkernels.
david-vicente Jun 1, 2021
90db07d
With new approach this file is not needed.
david-vicente Jun 1, 2021
7928803
Correctly implement @theogf approach to MOkernels AD testing.
david-vicente Jun 1, 2021
bf1ab84
Changes tests to use SqExponentialKernel instead of
david-vicente Jun 1, 2021
b5cbab8
Deletes unsused include.
david-vicente Jun 1, 2021
a627f76
Simplifies docstring.
david-vicente Jun 1, 2021
af05c2a
Improves error message.
david-vicente Jun 1, 2021
4965979
Deletes file because we currently pass just the Real part to gradient
david-vicente Jun 1, 2021
cb27119
Adds kernel and number of outputs when printing Icoregionkernel.
david-vicente Jun 1, 2021
85c86f7
Adds test for different inputs as arguments.
david-vicente Jun 1, 2021
dbd7f27
Stops infringing character limit.
david-vicente Jun 1, 2021
93e9b2c
Further simplify docstring.
david-vicente Jun 1, 2021
9ab8e60
Adds tests.
david-vicente Jun 1, 2021
d3ef272
Merge branch 'JuliaGaussianProcesses:master' into master
david-vicente Jun 1, 2021
16a773b
Deletes unuseful tests.
david-vicente Jun 1, 2021
160a38e
Updates print test.
david-vicente Jun 1, 2021
bb8adc2
Stops using interpolations.
david-vicente Jun 1, 2021
6fa2404
Creates constructor with keyword arguments.
david-vicente Jun 1, 2021
fede680
Restore constructor.
david-vicente Jun 1, 2021
a86529b
Deletes non kwargs outer constructor.
david-vicente Jun 1, 2021
169234e
Formatting.
david-vicente Jun 1, 2021
3f211b2
Updates code to be in consistent with kwargs constructor.
david-vicente Jun 1, 2021
5db59ef
Updates docstring.
david-vicente Jun 1, 2021
6a1e950
Merge branch 'master' into master
devmotion Jun 1, 2021
6d46be5
Update Project.toml
devmotion Jun 1, 2021
b160810
Formatting.
david-vicente Jun 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "KernelFunctions"
uuid = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
version = "0.10.1"
version = "0.10.2"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Expand Down
1 change: 1 addition & 0 deletions docs/src/kernels.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,5 @@ NormalizedKernel
MOKernel
IndependentMOKernel
LatentFactorMOKernel
IntrinsicCoregionMOKernel
```
3 changes: 2 additions & 1 deletion src/KernelFunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export spectral_mixture_kernel, spectral_mixture_product_kernel
export ColVecs, RowVecs

export MOInput
export IndependentMOKernel, LatentFactorMOKernel
export IndependentMOKernel, LatentFactorMOKernel, IntrinsicCoregionMOKernel

# Reexports
export tensor, ⊗, compose
Expand Down Expand Up @@ -105,6 +105,7 @@ include(joinpath("mokernels", "mokernel.jl"))
include(joinpath("mokernels", "moinput.jl"))
include(joinpath("mokernels", "independent.jl"))
include(joinpath("mokernels", "slfm.jl"))
include(joinpath("mokernels", "intrinsiccoregion.jl"))

include("chainrules.jl")
include("zygoterules.jl")
Expand Down
45 changes: 45 additions & 0 deletions src/mokernels/intrinsiccoregion.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@doc raw"""
IntrinsicIntrinsicCoregionMOKernel(; kernel::Kernel, B::AbstractMatrix)

Kernel associated with the intrinsic coregionalization model.

# Definition

For inputs ``x, x'`` and output dimensions ``p, p'``, the kernel is defined as[^ARL]
```math
k\big((x, p), (x', p'); B, \tilde{k}\big) = B_{p, p'} \tilde{k}\big(x, x'\big),
```
where ``B`` is a positive semidefinite matrix of size ``m \times m``, with ``m`` being the
number of outputs, and ``\tilde{k}`` is a scalar-valued kernel shared by the latent
processes.

[^ARL]: M. Álvarez, L. Rosasco, & N. Lawrence (2012). [Kernels for Vector-Valued Functions: a Review](https://arxiv.org/pdf/1106.6251.pdf).
"""
struct IntrinsicCoregionMOKernel{K<:Kernel,T<:AbstractMatrix} <: MOKernel
kernel::K
B::T

function IntrinsicCoregionMOKernel{K,T}(kernel::K, B::T) where {K,T}
@check_args(
IntrinsicCoregionMOKernel,
B,
eigmin(B) >= 0,
"B has to be positive semi-definite"
)
return new{K,T}(kernel, B)
end
end

function IntrinsicCoregionMOKernel(; kernel::Kernel, B::AbstractMatrix)
return IntrinsicCoregionMOKernel{typeof(kernel),typeof(B)}(kernel, B)
end

function (k::IntrinsicCoregionMOKernel)((x, px)::Tuple{Any,Int}, (y, py)::Tuple{Any,Int})
return k.B[px, py] * k.kernel(x, y)
end

function Base.show(io::IO, k::IntrinsicCoregionMOKernel)
return print(
io, "Intrinsic Coregion Kernel: ", k.kernel, " with ", size(k.B, 1), " outputs"
)
end
12 changes: 12 additions & 0 deletions src/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ function test_interface(
)
end

function test_interface(
rng::AbstractRNG, k::MOKernel, ::Type{Vector{Tuple{T,Int}}}; dim_out=1, kwargs...
) where {T<:Real}
return test_interface(
k,
[(randn(rng, T), rand(rng, 1:dim_out)) for i in 1:51],
[(randn(rng, T), rand(rng, 1:dim_out)) for i in 1:51],
[(randn(rng, T), rand(rng, 1:dim_out)) for i in 1:50];
kwargs...,
)
end

function test_interface(
rng::AbstractRNG, k::Kernel, ::Type{<:ColVecs{T}}; dim_in=2, kwargs...
) where {T<:Real}
Expand Down
28 changes: 28 additions & 0 deletions test/mokernels/intrinsiccoregion.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@testset "intrinsiccoregion" begin
rng = MersenneTwister(123)

dims = (in=3, out=2, obs=3)
rank = 1

A = randn(dims.out, rank)
B = A * transpose(A) + Diagonal(rand(dims.out))

X = [(rand(dims.in), rand(1:(dims.out))) for i in 1:(dims.obs)]

kernel = SqExponentialKernel()
icoregionkernel = IntrinsicCoregionMOKernel(; kernel=kernel, B=B)

@test icoregionkernel.B == B
@test icoregionkernel.kernel == kernel
@test icoregionkernel(X[1], X[1]) ≈ B[X[1][2], X[1][2]] * kernel(X[1][1], X[1][1])
@test icoregionkernel(X[1], X[end]) ≈ B[X[1][2], X[end][2]] * kernel(X[1][1], X[end][1])

KernelFunctions.TestUtils.test_interface(
icoregionkernel, Vector{Tuple{Float64,Int}}; dim_out=dims.out
)

test_ADs(icoregionkernel; dims=dims)

@test string(icoregionkernel) ==
string("Intrinsic Coregion Kernel: ", kernel, " with ", dims.out, " outputs")
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ include("test_utils.jl")
include(joinpath("mokernels", "moinput.jl"))
include(joinpath("mokernels", "independent.jl"))
include(joinpath("mokernels", "slfm.jl"))
include(joinpath("mokernels", "intrinsiccoregion.jl"))
end
@info "Ran tests on Multi-Output Kernels"

Expand Down
106 changes: 106 additions & 0 deletions test/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ testfunction(k, A, dim) = sum(kernelmatrix(k, A; obsdim=dim))
testdiagfunction(k, A, dim) = sum(kernelmatrix_diag(k, A; obsdim=dim))
testdiagfunction(k, A, B, dim) = sum(kernelmatrix_diag(k, A, B; obsdim=dim))

testfunction(k::MOKernel, A, B) = sum(kernelmatrix(k, A, B))
testfunction(k::MOKernel, A) = sum(kernelmatrix(k, A))
testdiagfunction(k::MOKernel, A) = sum(kernelmatrix_diag(k, A))
testdiagfunction(k::MOKernel, A, B) = sum(kernelmatrix_diag(k, A, B))

function test_ADs(
kernelfunction, args=nothing; ADs=[:Zygote, :ForwardDiff, :ReverseDiff], dims=[3, 3]
)
Expand All @@ -64,6 +69,17 @@ function test_ADs(
end
end

function test_ADs(
k::MOKernel; ADs=[:Zygote, :ForwardDiff, :ReverseDiff], dims=(in=3, out=2, obs=3)
)
test_fd = test_FiniteDiff(k, dims)
if !test_fd.anynonpass
for AD in ADs
test_AD(AD, k, dims)
end
end
end

function test_FiniteDiff(kernelfunction, args=nothing, dims=[3, 3])
# Init arguments :
k = if args === nothing
Expand Down Expand Up @@ -128,6 +144,50 @@ function test_FiniteDiff(kernelfunction, args=nothing, dims=[3, 3])
end
end

function test_FiniteDiff(k::MOKernel, dims=(in=3, out=2, obs=3))
rng = MersenneTwister(42)
@testset "FiniteDifferences" begin
## Testing Kernel Functions
x = (rand(rng, dims.in), rand(rng, 1:(dims.out)))
y = (rand(rng, dims.in), rand(rng, 1:(dims.out)))

@test_nowarn gradient(:FiniteDiff, x[1]) do a
k((a, x[2]), y)
end

## Testing Kernel Matrices

A = [(randn(rng, dims.in), rand(rng, 1:(dims.out))) for i in 1:(dims.obs)]
B = [(randn(rng, dims.in), rand(rng, 1:(dims.out))) for i in 1:(dims.obs)]

@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testfunction(k, A)
end
@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testfunction(k, A, B)
end
@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(B))) do b
B = tuple.(eachcol(b), last.(B))
testfunction(k, A, B)
end

@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testdiagfunction(k, A)
end
@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testdiagfunction(k, A, B)
end
@test_nowarn gradient(:FiniteDiff, reduce(hcat, first.(B))) do b
B = tuple.(eachcol(b), last.(B))
testdiagfunction(k, A, B)
end
end
end

function test_AD(AD::Symbol, kernelfunction, args=nothing, dims=[3, 3])
@testset "$(AD)" begin
# Test kappa function
Expand Down Expand Up @@ -194,3 +254,49 @@ function test_AD(AD::Symbol, kernelfunction, args=nothing, dims=[3, 3])
end
end
end

function test_AD(AD::Symbol, k::MOKernel, dims=(in=3, out=2, obs=3))
@testset "$(AD)" begin
rng = MersenneTwister(42)

# Testing kernel evaluations
x = (rand(rng, dims.in), rand(rng, 1:(dims.out)))
y = (rand(rng, dims.in), rand(rng, 1:(dims.out)))

compare_gradient(AD, x[1]) do a
k((a, x[2]), y)
end
compare_gradient(AD, y[1]) do b
k(x, (b, y[2]))
end

# Testing kernel matrices
A = [(randn(rng, dims.in), rand(rng, 1:(dims.out))) for i in 1:(dims.obs)]
B = [(randn(rng, dims.in), rand(rng, 1:(dims.out))) for i in 1:(dims.obs)]

compare_gradient(AD, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testfunction(k, A)
end
compare_gradient(AD, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testfunction(k, A, B)
end
compare_gradient(AD, reduce(hcat, first.(B))) do b
B = tuple.(eachcol(b), last.(B))
testfunction(k, A, B)
end
compare_gradient(AD, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testdiagfunction(k, A)
end
compare_gradient(AD, reduce(hcat, first.(A))) do a
A = tuple.(eachcol(a), last.(A))
testdiagfunction(k, A, B)
end
compare_gradient(AD, reduce(hcat, first.(B))) do b
B = tuple.(eachcol(b), last.(B))
testdiagfunction(k, A, B)
end
end
end