Skip to content

Commit fbce558

Browse files
Adding two MOInput types (#310)
* Initial push for adding two MOInput types * Change supertype name, address field types * Updating Base functions defined * Removing MOInput from documentation * Using boundschecks * Remove iterate def and bump version * Addressing a few small comments: mainly fixing typos in docs * Adding tests for type updates * Fixing docstrings, typos * Fixing compat and format suggestion * Add MOInput alias and change test var names * Add helper methods to create MOInput types * Fixing tests from changed exports * Removing exports, adding MOInput alias, restoring docs * Version edit * Fixing test I missed * Update docs project compat * *Hopefully* fixing CI bug * Addressing a few typos * Bump version, remove helper methods, change out_dim type to Integer * Adding MOInput deprecation note * Removing small change that was accidentally included in last commit * Bumping docs manifest
1 parent e6106f4 commit fbce558

File tree

5 files changed

+128
-52
lines changed

5 files changed

+128
-52
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
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.7"
3+
version = "0.10.8"
44

55
[deps]
66
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"

docs/Manifest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ version = "0.21.1"
119119
deps = ["ChainRulesCore", "Compat", "CompositionsBase", "Distances", "FillArrays", "Functors", "LinearAlgebra", "Random", "Requires", "SpecialFunctions", "StatsBase", "StatsFuns", "TensorCore", "Test", "ZygoteRules"]
120120
path = ".."
121121
uuid = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
122-
version = "0.10.6"
122+
version = "0.10.8"
123123

124124
[[Kronecker]]
125125
deps = ["FillArrays", "LinearAlgebra", "NamedDims", "SparseArrays", "StatsBase"]

src/mokernels/moinput.jl

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
11
"""
2-
MOInput(x::AbstractVector, out_dim::Integer)
2+
MOInputIsotopicByFeatures(x::AbstractVector, out_dim::Integer)
33
4-
A data type to accomodate modelling multi-dimensional output data.
4+
`MOInputIsotopicByFeatures(x, out_dim)` has length `out_dim * length(x)`.
55
6-
`MOInput(x, out_dim)` has length `length(x) * out_dim`.
6+
```jldoctest
7+
julia> x = [1, 2, 3];
8+
9+
julia> KernelFunctions.MOInputIsotopicByFeatures(x, 2)
10+
6-element KernelFunctions.MOInputIsotopicByFeatures{Int64, Vector{Int64}}:
11+
(1, 1)
12+
(1, 2)
13+
(2, 1)
14+
(2, 2)
15+
(3, 1)
16+
(3, 2)
17+
```
18+
19+
Accommodates modelling multi-dimensional output data where all outputs are always observed.
20+
21+
As shown above, an `MOInputIsotopicByFeatures` represents a vector of tuples.
22+
The first `out_dim` elements represent all outputs for the first input, the second
23+
`out_dim` elements represent the outputs for the second input, etc.
24+
25+
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
26+
"""
27+
struct MOInputIsotopicByFeatures{S,T<:AbstractVector{S}} <: AbstractVector{Tuple{S,Int}}
28+
x::T
29+
out_dim::Integer
30+
end
31+
32+
"""
33+
MOInputIsotopicByOutputs(x::AbstractVector, out_dim::Integer)
34+
35+
`MOInputIsotopicByOutputs(x, out_dim)` has length `length(x) * out_dim`.
736
837
```jldoctest
938
julia> x = [1, 2, 3];
1039
11-
julia> MOInput(x, 2)
12-
6-element MOInput{Vector{Int64}}:
40+
julia> KernelFunctions.MOInputIsotopicByOutputs(x, 2)
41+
6-element KernelFunctions.MOInputIsotopicByOutputs{Int64, Vector{Int64}}:
1342
(1, 1)
1443
(2, 1)
1544
(3, 1)
@@ -18,40 +47,59 @@ julia> MOInput(x, 2)
1847
(3, 2)
1948
```
2049
21-
As shown above, an `MOInput` represents a vector of tuples.
50+
Accommodates modelling multi-dimensional output data where all outputs are always observed.
51+
52+
As shown above, an `MOInputIsotopicByOutputs` represents a vector of tuples.
2253
The first `length(x)` elements represent the inputs for the first output, the second
2354
`length(x)` elements represent the inputs for the second output, etc.
24-
25-
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
2655
"""
27-
struct MOInput{T<:AbstractVector} <: AbstractVector{Tuple{Any,Int}}
56+
struct MOInputIsotopicByOutputs{S,T<:AbstractVector{S}} <: AbstractVector{Tuple{S,Int}}
2857
x::T
2958
out_dim::Integer
3059
end
3160

32-
Base.length(inp::MOInput) = inp.out_dim * length(inp.x)
33-
34-
Base.size(inp::MOInput, d) = d::Integer == 1 ? inp.out_dim * size(inp.x, 1) : 1
35-
Base.size(inp::MOInput) = (inp.out_dim * size(inp.x, 1),)
36-
37-
Base.lastindex(inp::MOInput) = length(inp)
38-
Base.firstindex(inp::MOInput) = 1
39-
40-
function Base.getindex(inp::MOInput, ind::Integer)
41-
if ind > 0
42-
out_dim = ind ÷ length(inp.x) + 1
43-
ind = ind % length(inp.x)
44-
if ind == 0
45-
ind = length(inp.x)
46-
out_dim -= 1
47-
end
48-
return (inp.x[ind], out_dim::Int)
49-
else
50-
throw(BoundsError(string("Trying to access at ", ind)))
51-
end
61+
const IsotopicMOInputs = Union{MOInputIsotopicByFeatures,MOInputIsotopicByOutputs}
62+
63+
function Base.getindex(inp::MOInputIsotopicByOutputs, ind::Integer)
64+
@boundscheck checkbounds(inp, ind)
65+
output_index, feature_index = fldmod1(ind, length(inp.x))
66+
feature = @inbounds inp.x[feature_index]
67+
return feature, output_index
5268
end
5369

54-
Base.iterate(inp::MOInput) = (inp[1], 1)
55-
function Base.iterate(inp::MOInput, state)
56-
return (state < length(inp)) ? (inp[state + 1], state + 1) : nothing
70+
function Base.getindex(inp::MOInputIsotopicByFeatures, ind::Integer)
71+
@boundscheck checkbounds(inp, ind)
72+
feature_index, output_index = fldmod1(ind, inp.out_dim)
73+
feature = @inbounds inp.x[feature_index]
74+
return feature, output_index
5775
end
76+
77+
Base.size(inp::IsotopicMOInputs) = (inp.out_dim * length(inp.x),)
78+
79+
"""
80+
MOInput(x::AbstractVector, out_dim::Integer)
81+
82+
A data type to accommodate modelling multi-dimensional output data.
83+
`MOInput(x, out_dim)` has length `length(x) * out_dim`.
84+
85+
```jldoctest
86+
julia> x = [1, 2, 3];
87+
88+
julia> MOInput(x, 2)
89+
6-element KernelFunctions.MOInputIsotopicByOutputs{Int64, Vector{Int64}}:
90+
(1, 1)
91+
(2, 1)
92+
(3, 1)
93+
(1, 2)
94+
(2, 2)
95+
(3, 2)
96+
```
97+
As shown above, an `MOInput` represents a vector of tuples.
98+
The first `length(x)` elements represent the inputs for the first output, the second
99+
`length(x)` elements represent the inputs for the second output, etc.
100+
See [Inputs for Multiple Outputs](@ref) in the docs for more info.
101+
102+
`MOInput` will be deprecated in version 0.11 in favour of `MOInputIsotopicByOutputs`,
103+
and removed in version 0.12.
104+
"""
105+
const MOInput = MOInputIsotopicByOutputs

test/mokernels/moinput.jl

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
11
@testset "moinput" begin
22
x = [rand(5) for _ in 1:4]
3-
mgpi = MOInput(x, 3)
4-
5-
@test length(mgpi) == 12
6-
@test size(mgpi) == (12,)
7-
@test size(mgpi, 1) == 12
8-
@test size(mgpi, 2) == 1
9-
@test lastindex(mgpi) == 12
10-
@test firstindex(mgpi) == 1
11-
@test iterate(mgpi) == (mgpi[1], 1)
12-
@test iterate(mgpi, 2) == (mgpi[3], 3)
13-
@test_throws BoundsError mgpi[0]
14-
15-
@test mgpi[2] == (x[2], 1)
16-
@test mgpi[5] == (x[1], 2)
17-
@test mgpi[7] == (x[3], 2)
18-
@test all([(x_, i) for i in 1:3 for x_ in x] .== mgpi)
3+
type_1 = AbstractVector{Tuple{Vector{Float64},Int}}
4+
type_2 = AbstractVector{Tuple{AbstractVector{Vector{Float64}},Int}}
5+
6+
@testset "isotopicbyoutputs" begin
7+
ibo = MOInput(x, 3)
8+
9+
@test ibo == KernelFunctions.MOInputIsotopicByOutputs(x, 3)
10+
11+
@test isa(ibo, type_1) == true
12+
@test isa(ibo, type_2) == false
13+
14+
@test length(ibo) == 12
15+
@test size(ibo) == (12,)
16+
@test size(ibo, 1) == 12
17+
@test size(ibo, 2) == 1
18+
@test lastindex(ibo) == 12
19+
@test firstindex(ibo) == 1
20+
@test_throws BoundsError ibo[0]
21+
22+
@test ibo[2] == (x[2], 1)
23+
@test ibo[5] == (x[1], 2)
24+
@test ibo[7] == (x[3], 2)
25+
@test all([(x_, i) for i in 1:3 for x_ in x] .== ibo)
26+
end
27+
28+
@testset "isotopicbyfeatures" begin
29+
ibf = KernelFunctions.MOInputIsotopicByFeatures(x, 3)
30+
31+
@test isa(ibf, type_1) == true
32+
@test isa(ibf, type_2) == false
33+
34+
@test length(ibf) == 12
35+
@test size(ibf) == (12,)
36+
@test size(ibf, 1) == 12
37+
@test size(ibf, 2) == 1
38+
@test lastindex(ibf) == 12
39+
@test firstindex(ibf) == 1
40+
@test_throws BoundsError ibf[0]
41+
42+
@test ibf[2] == (x[1], 2)
43+
@test ibf[5] == (x[2], 2)
44+
@test ibf[7] == (x[3], 1)
45+
@test all([(x_, i) for x_ in x for i in 1:3] .== ibf)
46+
end
1947
end

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ include("test_utils.jl")
183183
KernelFunctions;
184184
doctestfilters=[
185185
r"{([a-zA-Z0-9]+,\s?)+[a-zA-Z0-9]+}",
186-
r"(Array{[a-zA-Z0-9]+,\s?1}|Vector{[a-zA-Z0-9]+})",
187-
r"(Array{[a-zA-Z0-9]+,\s?2}|Matrix{[a-zA-Z0-9]+})",
186+
r"(Array{[a-zA-Z0-9]+,\s?1}|\s?Vector{[a-zA-Z0-9]+})",
187+
r"(Array{[a-zA-Z0-9]+,\s?2}|\s?Matrix{[a-zA-Z0-9]+})",
188188
],
189189
)
190190
end

0 commit comments

Comments
 (0)