Skip to content

Some improvement and additions to MO kernels #354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 54 commits into from
Aug 16, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8427ae5
Fix type stability of independent kernel
Crown421 Aug 6, 2021
1a5ac23
Add convenience functions
Crown421 Aug 6, 2021
d79d24b
Add/fix tests
Crown421 Aug 7, 2021
4f23240
Suggested change for kernelmatrix computation
Crown421 Aug 7, 2021
a33c312
Add results to test script
Crown421 Aug 10, 2021
a729c01
Switching to new kernelmatrix for independent kernel, tests
Crown421 Aug 10, 2021
e1f92a8
Change type stability
Crown421 Aug 10, 2021
e7d7db9
New kernelmatrix for IntrinsicCoregion kernel, tests
Crown421 Aug 10, 2021
ee69c6e
JuliaFormatter
Crown421 Aug 10, 2021
d1d8d45
Improve code reuse, Traits
Crown421 Aug 10, 2021
d80453c
Use FillArray
Crown421 Aug 11, 2021
06cbb3d
Remove traits, move to explicit function
Crown421 Aug 11, 2021
d03b951
Relax matrixkernel types
Crown421 Aug 11, 2021
c8f8093
Adjust MOInput specifications
Crown421 Aug 11, 2021
cd6dedc
Merge branch 'mo-improvements' of github.com:Crown421/KernelFunctions…
Crown421 Aug 11, 2021
8b7410a
Merge branch 'master' into mo-improvements
Crown421 Aug 11, 2021
1978e25
Change supertype, move matrixkernel
Crown421 Aug 11, 2021
3ffd436
JuliaFormatter
Crown421 Aug 11, 2021
c42e43d
Merge branch 'master' into mo-improvements
Crown421 Aug 11, 2021
96bf55e
Remove forced typesymmetry, and improve fallback
Crown421 Aug 11, 2021
b649e65
Improve documentation, add matrixkernel to other kernels
Crown421 Aug 11, 2021
fe81b0a
Comment out specialized kernelmatrix!
Crown421 Aug 11, 2021
509dfd6
Add kernelmatrix! back in with version check
Crown421 Aug 11, 2021
33f3e87
Formatter
Crown421 Aug 11, 2021
0f9ce64
Improve doc phrasing
Crown421 Aug 12, 2021
51a3736
Merge branch 'master' into mo-improvements
Crown421 Aug 12, 2021
8459d0c
Change Union name
Crown421 Aug 12, 2021
1675598
Substantially improve tests
Crown421 Aug 12, 2021
0672a1f
Add ed clarity for lazy kronecker
Crown421 Aug 12, 2021
cf8e8f3
Improve tests for lmm and slfm
Crown421 Aug 12, 2021
31620e2
Formatter
Crown421 Aug 12, 2021
9b27b58
Update src/mokernels/mokernel.jl
Crown421 Aug 12, 2021
d68f86e
Remove comments
Crown421 Aug 13, 2021
59ff2c8
Add check for lmm kernel, tests
Crown421 Aug 13, 2021
7c99633
Merge branch 'mo-improvements' of github.com:Crown421/KernelFunctions…
Crown421 Aug 13, 2021
286d5d5
Fix constructor mistake
Crown421 Aug 13, 2021
cb37e0f
Remove kwarg dispatch
Crown421 Aug 13, 2021
fee8eaf
Remove matrixkernel and lazy kron
Crown421 Aug 15, 2021
3466daa
Merge branch 'master' into mo-improvements
Crown421 Aug 15, 2021
533f8fd
Remove matrixkernel export
Crown421 Aug 16, 2021
213b606
Update src/matrix/kernelkroneckermat.jl
Crown421 Aug 16, 2021
f2c6ae6
Update src/mokernels/independent.jl
Crown421 Aug 16, 2021
407ca80
Update src/mokernels/independent.jl
Crown421 Aug 16, 2021
6bcc83d
Update src/mokernels/mokernel.jl
Crown421 Aug 16, 2021
d5571df
helper function name, formatter
Crown421 Aug 16, 2021
13427a7
Merge branch 'master' into mo-improvements
Crown421 Aug 16, 2021
48db5a0
Remove explicit in-place tests
Crown421 Aug 16, 2021
43a5ab9
Remove temp file and bump patch
Crown421 Aug 16, 2021
f2ac5ed
Change helper function name
Crown421 Aug 16, 2021
dac5db7
Fixed rename oversight
Crown421 Aug 16, 2021
e61a668
Fix missing Union
Crown421 Aug 16, 2021
8cbb1eb
Silly mistake
Crown421 Aug 16, 2021
c72efd9
Make arguments more consistent
Crown421 Aug 16, 2021
11e6d56
Forgot to uncomment
Crown421 Aug 16, 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
21 changes: 20 additions & 1 deletion src/mokernels/independent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,39 @@ struct IndependentMOKernel{Tkernel<:Kernel} <: MOKernel
kernel::Tkernel
end

# kernel function should be symmetric
# would really like (κ::IndependentMOKernel)((x, px)::Tuple{T,Int}, (y, py)::Tuple{T,Int}) where T, but seems to cause autodiff problems
function (κ::IndependentMOKernel)((x, px)::Tuple{Any,Int}, (y, py)::Tuple{Any,Int})
if px == py
return κ.kernel(x, y)
else
return 0.0
retType = Base.return_types(κ.kernel, (typeof(x), typeof(y)))[1]
return zero(retType)
end
end

# this function never gets called it seems
function kernelmatrix(k::IndependentMOKernel, x::MOInput, y::MOInput)
@assert x.out_dim == y.out_dim
temp = k.kernel.(x.x, permutedims(y.x))
return cat((temp for _ in 1:(y.out_dim))...; dims=(1, 2))
end

export kernelmatrix2
function kernelmatrix2(k::IndependentMOKernel, x::MOInputIsotopicByFeatures, y::MOInputIsotopicByFeatures)
@assert x.out_dim == y.out_dim
Ktmp = kernelmatrix(k.kernel, x.x, y.x)
mtype = eltype(Ktmp)
kron(Ktmp, Matrix{mtype}(I, x.out_dim, x.out_dim))
end

function kernelmatrix2(k::IndependentMOKernel, x::MOInputIsotopicByOutputs, y::MOInputIsotopicByOutputs)
@assert x.out_dim == y.out_dim
Ktmp = kernelmatrix(k.kernel, x.x, y.x)
mtype = eltype(Ktmp)
kron(Matrix{mtype}(I, x.out_dim, x.out_dim), Ktmp)
end

function Base.show(io::IO, k::IndependentMOKernel)
return print(io, string("Independent Multi-Output Kernel\n\t", string(k.kernel)))
end
29 changes: 28 additions & 1 deletion src/mokernels/intrinsiccoregion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,37 @@ 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})
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

# convenience function
function (k::IntrinsicCoregionMOKernel)(x::Vector{T}, y::Vector{T}) where T <: Real
@assert size(x) == size(y)
outputsize = size(k.B, 1)
xMO = MOInputIsotopicByFeatures([x], outputsize)
yMO = MOInputIsotopicByFeatures([y], outputsize)
kernelmatrix(k, xMO, yMO)
end

# kernelmatrix (test for now)
export kernelmatrix2
function kernelmatrix2(k::IntrinsicCoregionMOKernel, x::MOInputIsotopicByFeatures, y::MOInputIsotopicByFeatures)
@assert x.out_dim == y.out_dim == size(k.B, 1)
Ktmp = kernelmatrix(k.kernel, x.x, y.x)
kron(Ktmp, k.B)
end

function kernelmatrix2(k::IntrinsicCoregionMOKernel, x::MOInputIsotopicByOutputs, y::MOInputIsotopicByOutputs)
@assert x.out_dim == y.out_dim == size(k.B, 1)
Ktmp = kernelmatrix(k.kernel, x.x, y.x)
kron(k.B, Ktmp)
end

function Base.show(io::IO, k::IntrinsicCoregionMOKernel)
return print(
io, "Intrinsic Coregion Kernel: ", k.kernel, " with ", size(k.B, 1), " outputs"
Expand Down
79 changes: 79 additions & 0 deletions temporary_script.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# this script should be removed when the alternative MO kernelmatrix is accepted or rejected.

using KernelFunctions, BenchmarkTools
using LinearAlgebra

mrank = 1
dims = (in=5, out=3)
x = [rand(dims.in) for _ in 1:20]

xMOF = KernelFunctions.MOInputIsotopicByFeatures(x, dims.out)
xMOO = KernelFunctions.MOInputIsotopicByOutputs(x, dims.out)

indk = IndependentMOKernel(GaussianKernel())

Kind1 = kernelmatrix(indk, xMOF, xMOF)
Kind2 = kernelmatrix2(indk, xMOF, xMOF)

Kind1 ≈ Kind2
# true

@benchmark kernelmatrix($indk, $xMOF, $xMOF)
# BenchmarkTools.Trial: 756 samples with 1 evaluation.
# Range (min … max): 6.186 ms … 11.470 ms ┊ GC (min … max): 0.00% … 35.30%
# Time (median): 6.423 ms ┊ GC (median): 0.00%
# Time (mean ± σ): 6.614 ms ± 806.792 μs ┊ GC (mean ± σ): 2.76% ± 7.77%

# ▅▇█▇▃
# ▆██████▅▆▄▅▄▁▄▁▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▁▁▁▆██▇▇ ▇
# 6.19 ms Histogram: log(frequency) by time 10 ms <

# Memory estimate: 2.34 MiB, allocs estimate: 60060.

@benchmark kernelmatrix2($indk, $xMOF, $xMOF)
# BenchmarkTools.Trial: 10000 samples with 5 evaluations.
# Range (min … max): 6.162 μs … 341.226 μs ┊ GC (min … max): 0.00% … 96.29%
# Time (median): 6.947 μs ┊ GC (median): 0.00%
# Time (mean ± σ): 8.235 μs ± 16.802 μs ┊ GC (mean ± σ): 12.37% ± 5.92%

# ▁▄▆▇██▇▆▅▄▃▂▁▁▁ ▂
# ▅██████████████████▇▇▆▇▅▆▆▆▅▅▆▅▅▃▄▅▅▅▁▁▃▁▃▅▅▆▆▆▇▇▇▇▇▇▇██▇▇▇ █
# 6.16 μs Histogram: log(frequency) by time 13.7 μs <

# Memory estimate: 34.89 KiB, allocs estimate: 7.


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

ickernel = IntrinsicCoregionMOKernel(GaussianKernel(), B)

Kic1 = kernelmatrix(ickernel, xMOF, xMOF)
Kic2 = kernelmatrix2(ickernel, xMOF, xMOF)

Kic1 ≈ Kic2
#true

@benchmark kernelmatrix($ickernel, $xMOF, $xMOF)
# BenchmarkTools.Trial: 1874 samples with 1 evaluation.
# Range (min … max): 2.522 ms … 5.424 ms ┊ GC (min … max): 0.00% … 51.13%
# Time (median): 2.601 ms ┊ GC (median): 0.00%
# Time (mean ± σ): 2.666 ms ± 369.030 μs ┊ GC (mean ± σ): 2.01% ± 7.04%

# ▂█▆▁ ▁
# ███████▅▄▅▅▃▁▁▃▅▁▁▁▃▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇▇ █
# 2.52 ms Histogram: log(frequency) by time 570 ms <

# Memory estimate: 985.47 KiB, allocs estimate: 39639.

@benchmark kernelmatrix2($ickernel, $xMOF, $xMOF)
# BenchmarkTools.Trial: 10000 samples with 5 evaluations.
# Range (min … max): 6.152 μs … 322.002 μs ┊ GC (min … max): 0.00% … 96.14%
# Time (median): 6.676 μs ┊ GC (median): 0.00%
# Time (mean ± σ): 8.100 μs ± 16.959 μs ┊ GC (mean ± σ): 12.53% ± 5.85%

# ▄▇██▇▅▄▃▂▁▁ ▁▁▁▁ ▂
# ▆██████████████▇▇▇▆▆▇▇▇▇▆▇▆▄▅▄▃▆▁▅▄▅▆▆▅▅▄▅▄▆▇▇█▇▇▇▇██████▇▇ █
# 6.15 μs Histogram: log(frequency) by time 13.5 μs <

# Memory estimate: 34.77 KiB, allocs estimate: 6.
6 changes: 6 additions & 0 deletions test/mokernels/independent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
@test k(x1[1], x1[1]) isa Real
@test kernelmatrix(k, x1) isa Matrix

# type stability
x2 = MOInput(rand(Float32, 4), 2)
@test k(x2[1], x2[2]) isa Float32
@test k(x2[1], x2[1]) isa Float32
@test eltype(typeof(kernelmatrix(k, x2))) <: Float32

@test string(k) ==
"Independent Multi-Output Kernel\n" *
"\tSquared Exponential Kernel (metric = Euclidean(0.0))"
Expand Down
13 changes: 12 additions & 1 deletion test/mokernels/intrinsiccoregion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,27 @@
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)]
# X = [(rand(dims.in), rand(1:(dims.out))) for i in 1:(dims.obs)]
x = [rand(dims.in) for _ in 1:2]
X = KernelFunctions.MOInputIsotopicByFeatures(x, dims.out)

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

icoregionkernel2 = IntrinsicCoregionMOKernel(kernel, B)
@test icoregionkernel == icoregionkernel2

@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])

# test convenience function using kronecker product
@test icoregionkernel(X.x[1], X.x[2]) ≈ icoregionkernel.kernel(X.x[1], X.x[2])*B

# kernelmatrix
@test kernelmatrix(icoregionkernel, X) ≈ kron(kernelmatrix(kernel, X.x), B)

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