Skip to content

Commit 4e145a9

Browse files
authored
Merge pull request #1 from alan-turing-institute/light-interface
Light interface
2 parents 07b664c + a3e8aca commit 4e145a9

File tree

7 files changed

+131
-0
lines changed

7 files changed

+131
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*DS_Store
2+
Manifest.toml

.travis.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Documentation: http://docs.travis-ci.com/user/languages/julia/
2+
language: julia
3+
os:
4+
- linux
5+
julia:
6+
- 1.1
7+
- 1.2
8+
- 1.3
9+
- 1.4
10+
- nightly
11+
matrix:
12+
allow_failures:
13+
- julia: nightly
14+
notifications:
15+
email: false
16+
after_success:
17+
# push coverage results to Codecov
18+
- julia -e 'using Pkg; pkg"add Coverage"; using Coverage; Codecov.submit(Codecov.process_folder())'
File renamed without changes.

Manifest.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
[[ScientificTypes]]
4+
git-tree-sha1 = "661a775ebf854f14509f590952eba63b47c82a5f"
5+
uuid = "321657f4-b219-11e9-178b-2701a2544e81"
6+
version = "0.6.0"

Project.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name = "MLJModelInterface"
2+
uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea"
3+
authors = ["Thibaut Lienart <[email protected]>"]
4+
version = "0.1.0"
5+
6+
[deps]
7+
ScientificTypes = "321657f4-b219-11e9-178b-2701a2544e81"
8+
9+
[compat]
10+
ScientificTypes = "^0.6"
11+
12+
[extras]
13+
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
14+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
15+
16+
[targets]
17+
test = ["Test", "Tables"]

src/MLJModelInterface.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module MLJModelInterface
2+
3+
# ------------------------------------------------------------------------
4+
# Dependency (note that ScientificTypes itself does not have dependencies)
5+
import ScientificTypes: trait
6+
7+
# ------------------------------------------------------------------------
8+
# Single export: matrix, everything else is qualified in MLJBase
9+
export matrix
10+
11+
# ------------------------------------------------------------------------
12+
13+
abstract type Mode end
14+
struct LightInterface <: Mode end
15+
struct FullInterface <: Mode end
16+
17+
const INTERFACE_MODE = Ref{Mode}(LightInterface())
18+
19+
set_interface_mode(m::Mode) = (INTERFACE_MODE[] = m)
20+
21+
get_interface_mode() = INTERFACE_MODE[]
22+
23+
struct InterfaceError <: Exception
24+
m::String
25+
end
26+
27+
vtrait(X) = X |> trait |> Val
28+
29+
"""
30+
matrix(X; transpose=false)
31+
32+
If `X <: AbstractMatrix`, return `X` or `permutedims(X)` if `transpose=true`.
33+
If `X` is a Tables.jl compatible table source, convert `X` into a `Matrix`.
34+
"""
35+
matrix(X; kw...) = matrix(vtrait(X), X, get_interface_mode(); kw...)
36+
37+
matrix(::Val{:other}, X::AbstractMatrix, ::Mode; transpose=false) =
38+
transpose ? permutedims(X) : X
39+
40+
matrix(::Val{:other}, X, ::Mode; kw...) =
41+
throw(ArgumentError("Function `matrix` only supports AbstractMatrix or " *
42+
"containers implementing the Tables interface."))
43+
44+
matrix(::Val{:table}, X, ::LightInterface; kw...) =
45+
throw(InterfaceError("Only `MLJModelInterface` loaded. Import `MLJBase`."))
46+
47+
end # module

test/runtests.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Test, MLJModelInterface, ScientificTypes
2+
using Tables
3+
4+
const M = MLJModelInterface
5+
6+
ScientificTypes.TRAIT_FUNCTION_GIVEN_NAME[:table] = Tables.istable
7+
8+
@testset "light-interface" begin
9+
M.set_interface_mode(M.LightInterface())
10+
@test M.get_interface_mode() isa M.LightInterface
11+
12+
# matrix object (:other)
13+
X = zeros(3, 4)
14+
mX = matrix(X)
15+
mtX = matrix(X; transpose=true)
16+
17+
@test mX === X
18+
@test mtX == permutedims(X)
19+
20+
# :other but not matrix
21+
X = (1, 2, 3, 4)
22+
@test_throws ArgumentError matrix(X)
23+
24+
# :table
25+
X = (x=[1,2,3], y=[1,2,3])
26+
@test M.vtrait(X) isa Val{:table}
27+
@test_throws M.InterfaceError matrix(X)
28+
end
29+
30+
@testset "full-interface" begin
31+
M.set_interface_mode(M.FullInterface())
32+
@test M.get_interface_mode() isa M.FullInterface
33+
34+
M.matrix(::Val{:table}, X, ::M.FullInterface; kw...) =
35+
Tables.matrix(X; kw...)
36+
37+
X = (x=[1,2,3], y=[1,2,3])
38+
mX = matrix(X)
39+
@test mX isa Matrix
40+
@test mX == hcat(X.x, X.y)
41+
end

0 commit comments

Comments
 (0)