Skip to content

Add MOInputHeterotopic type & helpers #393

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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.26"
version = "0.10.27"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Expand Down
3 changes: 2 additions & 1 deletion src/KernelFunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export spectral_mixture_kernel, spectral_mixture_product_kernel

export ColVecs, RowVecs

export MOInput, prepare_isotopic_multi_output_data, prepare_heterotopic_multi_output_data
export MOInput, MOInputHeterotopic,
prepare_isotopic_multi_output_data, prepare_heterotopic_multi_output_data
export IndependentMOKernel,
LatentFactorMOKernel, IntrinsicCoregionMOKernel, LinearMixingModelKernel

Expand Down
47 changes: 47 additions & 0 deletions src/mokernels/moinput.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,43 @@ struct MOInputIsotopicByOutputs{S,T<:AbstractVector{S}} <: AbstractVector{Tuple{
out_dim::Integer
end

"""
MOInputsHeterotopic(x::AbstractVector, output_indices::Integer)

`MOInputsHeterotopic(x, output_indices)` has length `length(x)`.

```jldoctest
julia> x = [1, 2, 3, 4, 5, 6];

julia> out_inds = [1, 1, 2, 3, 2, 1];

julia> KernelFunctions.MOInputsHeterotopic(x, out_inds)
6-element KernelFunctions.MOInputsHeterotopic{Int64, Vector{Int64}}:
(1, 1)
(2, 1)
(3, 2)
(4, 3)
(5, 2)
(6, 1)
```

Accommodates modelling multi-dimensional output data where not all outputs are observed
for every input.

As shown above, an `MOInputsHeterotopic` represents a vector of tuples.
The `length(x)` elements represent the inputs that are observed at the locations specified
by `output_indices`.
"""
struct MOInputsHeterotopic{S ,T<:AbstractVector{S}} <: AbstractVector{Tuple{S,Int}}
x::T
output_indices::AbstractVector{Int}
end

# Return the inputs at a specific output
function get_inputs_at_output(inp::MOInputsHeterotopic, output)
return [input[1] for input in inputs if input[2]==output]
end

const IsotopicMOInputsUnion = Union{MOInputIsotopicByFeatures,MOInputIsotopicByOutputs}

function Base.getindex(inp::MOInputIsotopicByOutputs, ind::Integer)
Expand All @@ -74,7 +111,13 @@ function Base.getindex(inp::MOInputIsotopicByFeatures, ind::Integer)
return feature, output_index
end

function Base.getindex(inp::MOInputsHeterotopic, ind::Integer)
@boundscheck checkbounds(inp, ind)
return inp.x[ind], inp.output_indices[ind]
end

Base.size(inp::IsotopicMOInputsUnion) = (inp.out_dim * length(inp.x),)
Base.size(inp::MOInputsHeterotopic) = (length(inp.output_indices),)

function Base.vcat(x::MOInputIsotopicByFeatures, y::MOInputIsotopicByFeatures)
x.out_dim == y.out_dim || throw(DimensionMismatch("out_dim mismatch"))
Expand All @@ -86,6 +129,10 @@ function Base.vcat(x::MOInputIsotopicByOutputs, y::MOInputIsotopicByOutputs)
return MOInputIsotopicByOutputs(vcat(x.x, y.x), x.out_dim)
end

function Base.vcat(x::MOInputsHeterotopic, y::MOInputsHeterotopic)
return MOInputsHeterotopic(vcat(x.x, y.x), vcat(x.output_indices, y.output_indices))
end

"""
MOInput(x::AbstractVector, out_dim::Integer)

Expand Down
21 changes: 21 additions & 0 deletions test/mokernels/moinput.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@
@test all([(x_, i) for x_ in x for i in 1:3] .== ibf)
end

@testset "heterotopic" begin
out_inds = [1, 2, 3, 2]
mo_input = KernelFunctions.MOInputsHeterotopic(x, out_inds)
@test isa(mo_input, type_1) == true
@test isa(mo_input, type_2) == false

@test length(mo_input) == 4
@test size(mo_input) == (4,)
@test size(mo_input, 1) == 4
@test size(mo_input, 2) == 1
@test lastindex(mo_input) == 4
@test firstindex(mo_input) == 1
@test_throws BoundsError mo_input[0]
@test vcat(mo_input, mo_input) == KernelFunctions.MOInputsHeterotopic(vcat(x, x), vcat(out_inds, out_inds))

@test mo_input[2] == (x[2], 2)
@test mo_input[3] == (x[3], 3)
@test mo_input[4] == (x[4], 2)
@test all([(x_, i) for (x_, i) in zip(x, out_inds)] .== mo_input)
end

@testset "prepare_isotopic_multi_output_data" begin
@testset "ColVecs" begin
N = 5
Expand Down