Skip to content

Commit

Permalink
Merge 6fc966d into 2181649
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasgudjonwright committed Jul 13, 2021
2 parents 2181649 + 6fc966d commit b5463ff
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 52 deletions.
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.7"
version = "0.10.8"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Expand Down
2 changes: 1 addition & 1 deletion docs/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ version = "0.21.1"
deps = ["ChainRulesCore", "Compat", "CompositionsBase", "Distances", "FillArrays", "Functors", "LinearAlgebra", "Random", "Requires", "SpecialFunctions", "StatsBase", "StatsFuns", "TensorCore", "Test", "ZygoteRules"]
path = ".."
uuid = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
version = "0.10.6"
version = "0.10.7"

[[Kronecker]]
deps = ["FillArrays", "LinearAlgebra", "NamedDims", "SparseArrays", "StatsBase"]
Expand Down
112 changes: 80 additions & 32 deletions src/mokernels/moinput.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
"""
MOInput(x::AbstractVector, out_dim::Integer)
MOInputIsotopicByFeatures(x::AbstractVector, out_dim::Integer)
A data type to accomodate modelling multi-dimensional output data.
`MOInputIsotopicByFeatures(x, out_dim)` has length `out_dim * length(x)`.
`MOInput(x, out_dim)` has length `length(x) * out_dim`.
```jldoctest
julia> x = [1, 2, 3];
julia> KernelFunctions.MOInputIsotopicByFeatures(x, 2)
6-element KernelFunctions.MOInputIsotopicByFeatures{Int64, Vector{Int64}}:
(1, 1)
(1, 2)
(2, 1)
(2, 2)
(3, 1)
(3, 2)
```
Accommodates modelling multi-dimensional output data where all outputs are always observed.
As shown above, an `MOInputIsotopicByFeatures` represents a vector of tuples.
The first `out_dim` elements represent all outputs for the first input, the second
`out_dim` elements represent the outputs for the second input, etc.
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
"""
struct MOInputIsotopicByFeatures{S,T<:AbstractVector{S}} <: AbstractVector{Tuple{S,Int}}
x::T
out_dim::Integer
end

"""
MOInputIsotopicByOutputs(x::AbstractVector, out_dim::Integer)
`MOInputIsotopicByOutputs(x, out_dim)` has length `length(x) * out_dim`.
```jldoctest
julia> x = [1, 2, 3];
julia> MOInput(x, 2)
6-element MOInput{Vector{Int64}}:
julia> KernelFunctions.MOInputIsotopicByOutputs(x, 2)
6-element KernelFunctions.MOInputIsotopicByOutputs{Int64, Vector{Int64}}:
(1, 1)
(2, 1)
(3, 1)
Expand All @@ -18,40 +47,59 @@ julia> MOInput(x, 2)
(3, 2)
```
As shown above, an `MOInput` represents a vector of tuples.
Accommodates modelling multi-dimensional output data where all outputs are always observed.
As shown above, an `MOInputIsotopicByOutputs` represents a vector of tuples.
The first `length(x)` elements represent the inputs for the first output, the second
`length(x)` elements represent the inputs for the second output, etc.
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
"""
struct MOInput{T<:AbstractVector} <: AbstractVector{Tuple{Any,Int}}
struct MOInputIsotopicByOutputs{S,T<:AbstractVector{S}} <: AbstractVector{Tuple{S,Int}}
x::T
out_dim::Integer
end

Base.length(inp::MOInput) = inp.out_dim * length(inp.x)

Base.size(inp::MOInput, d) = d::Integer == 1 ? inp.out_dim * size(inp.x, 1) : 1
Base.size(inp::MOInput) = (inp.out_dim * size(inp.x, 1),)

Base.lastindex(inp::MOInput) = length(inp)
Base.firstindex(inp::MOInput) = 1

function Base.getindex(inp::MOInput, ind::Integer)
if ind > 0
out_dim = ind ÷ length(inp.x) + 1
ind = ind % length(inp.x)
if ind == 0
ind = length(inp.x)
out_dim -= 1
end
return (inp.x[ind], out_dim::Int)
else
throw(BoundsError(string("Trying to access at ", ind)))
end
const IsotopicMOInputs = Union{MOInputIsotopicByFeatures,MOInputIsotopicByOutputs}

function Base.getindex(inp::MOInputIsotopicByOutputs, ind::Integer)
@boundscheck checkbounds(inp, ind)
output_index, feature_index = fldmod1(ind, length(inp.x))
feature = @inbounds inp.x[feature_index]
return feature, output_index
end

Base.iterate(inp::MOInput) = (inp[1], 1)
function Base.iterate(inp::MOInput, state)
return (state < length(inp)) ? (inp[state + 1], state + 1) : nothing
function Base.getindex(inp::MOInputIsotopicByFeatures, ind::Integer)
@boundscheck checkbounds(inp, ind)
feature_index, output_index = fldmod1(ind, inp.out_dim)
feature = @inbounds inp.x[feature_index]
return feature, output_index
end

Base.size(inp::IsotopicMOInputs) = (inp.out_dim * length(inp.x),)

"""
MOInput(x::AbstractVector, out_dim::Integer)
A data type to accommodate modelling multi-dimensional output data.
`MOInput(x, out_dim)` has length `length(x) * out_dim`.
```jldoctest
julia> x = [1, 2, 3];
julia> MOInput(x, 2)
6-element KernelFunctions.MOInputIsotopicByOutputs{Int64, Vector{Int64}}:
(1, 1)
(2, 1)
(3, 1)
(1, 2)
(2, 2)
(3, 2)
```
As shown above, an `MOInput` represents a vector of tuples.
The first `length(x)` elements represent the inputs for the first output, the second
`length(x)` elements represent the inputs for the second output, etc.
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
`MOInput` will be deprecated in version 0.11 in favour of `MOInputIsotopicByOutputs`,
and removed in version 0.12.
"""
const MOInput = MOInputIsotopicByOutputs
60 changes: 44 additions & 16 deletions test/mokernels/moinput.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
@testset "moinput" begin
x = [rand(5) for _ in 1:4]
mgpi = MOInput(x, 3)

@test length(mgpi) == 12
@test size(mgpi) == (12,)
@test size(mgpi, 1) == 12
@test size(mgpi, 2) == 1
@test lastindex(mgpi) == 12
@test firstindex(mgpi) == 1
@test iterate(mgpi) == (mgpi[1], 1)
@test iterate(mgpi, 2) == (mgpi[3], 3)
@test_throws BoundsError mgpi[0]

@test mgpi[2] == (x[2], 1)
@test mgpi[5] == (x[1], 2)
@test mgpi[7] == (x[3], 2)
@test all([(x_, i) for i in 1:3 for x_ in x] .== mgpi)
type_1 = AbstractVector{Tuple{Vector{Float64},Int}}
type_2 = AbstractVector{Tuple{AbstractVector{Vector{Float64}},Int}}

@testset "isotopicbyoutputs" begin
ibo = MOInput(x, 3)

@test ibo == KernelFunctions.MOInputIsotopicByOutputs(x, 3)

@test isa(ibo, type_1) == true
@test isa(ibo, type_2) == false

@test length(ibo) == 12
@test size(ibo) == (12,)
@test size(ibo, 1) == 12
@test size(ibo, 2) == 1
@test lastindex(ibo) == 12
@test firstindex(ibo) == 1
@test_throws BoundsError ibo[0]

@test ibo[2] == (x[2], 1)
@test ibo[5] == (x[1], 2)
@test ibo[7] == (x[3], 2)
@test all([(x_, i) for i in 1:3 for x_ in x] .== ibo)
end

@testset "isotopicbyfeatures" begin
ibf = KernelFunctions.MOInputIsotopicByFeatures(x, 3)

@test isa(ibf, type_1) == true
@test isa(ibf, type_2) == false

@test length(ibf) == 12
@test size(ibf) == (12,)
@test size(ibf, 1) == 12
@test size(ibf, 2) == 1
@test lastindex(ibf) == 12
@test firstindex(ibf) == 1
@test_throws BoundsError ibf[0]

@test ibf[2] == (x[1], 2)
@test ibf[5] == (x[2], 2)
@test ibf[7] == (x[3], 1)
@test all([(x_, i) for x_ in x for i in 1:3] .== ibf)
end
end
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ include("test_utils.jl")
KernelFunctions;
doctestfilters=[
r"{([a-zA-Z0-9]+,\s?)+[a-zA-Z0-9]+}",
r"(Array{[a-zA-Z0-9]+,\s?1}|Vector{[a-zA-Z0-9]+})",
r"(Array{[a-zA-Z0-9]+,\s?2}|Matrix{[a-zA-Z0-9]+})",
r"(Array{[a-zA-Z0-9]+,\s?1}|\s?Vector{[a-zA-Z0-9]+})",
r"(Array{[a-zA-Z0-9]+,\s?2}|\s?Matrix{[a-zA-Z0-9]+})",
],
)
end
Expand Down

0 comments on commit b5463ff

Please sign in to comment.