Skip to content
This repository has been archived by the owner on Aug 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from findmyway/master
Browse files Browse the repository at this point in the history
Add Space & AbstractEnv into base
  • Loading branch information
jbrea authored Sep 2, 2018
2 parents 6b0ec82 + f3ef2fb commit f882dd9
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.jl.cov
*.jl.*.cov
*.jl.mem
deps/deps.jl

Manifest.toml
30 changes: 30 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
- osx
julia:
- 1.0
- nightly
notifications:
email: false
git:
depth: 99999999

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
#matrix:
# allow_failures:
# - julia: nightly

## uncomment and modify the following lines to manually install system packages
#addons:
# apt: # apt-get for linux
# packages:
# - gfortran
#before_script: # homebrew for mac
# - if [ $TRAVIS_OS_NAME = osx ]; then brew install gcc; fi

## uncomment the following lines to override the default test script
script:
- julia -e 'using Pkg; Pkg.activate(pwd()); Pkg.test()'
8 changes: 6 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
authors = ["Johanni Brea <[email protected]>"]
name = "ReinforcementLearningBase"
uuid = "9b2b9cba-ac73-11e8-02b1-9f0869453fc0"
authors = ["Johanni Brea <[email protected]>", "Jun Tian <[email protected]>"]
version = "0.1.0"

[deps]
[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ReinforcementLearningBase.jl

[![Build Status](https://travis-ci.com/JuliaReinforcementLearning/ReinforcementLearningBase.jl.svg?branch=master)](https://travis-ci.com/JuliaReinforcementLearning/ReinforcementLearningBase.jl)

ReinforcementLearningBase.jl holds the common types and utility functions to be shared by other components in ReinforcementLearning ecosystem.
1 change: 1 addition & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
julia 1.0
3 changes: 2 additions & 1 deletion src/ReinforcementLearningBase.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module ReinforcementLearningBase

greet() = print("Hello World!")
include("spaces/space.jl")
include("abstractenv.jl")

end # module
17 changes: 17 additions & 0 deletions src/abstractenv.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export AbstractEnv
abstract type AbstractEnv end

"Get current state of an environment"
function getstate end

"Reset an environment to the initial state"
function reset! end

"Take an action in an environment and return the current state"
function interact! end

"Get the action space of an environment"
function actionspace end

"Plot the current state of an environment"
function plotenv end
15 changes: 15 additions & 0 deletions src/spaces/abstractspace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
abstract type AbstractSpace end

"""
sample(s::AbstractSpace)
Get a random sample from `s`.
"""
function sample end

"""
occursin(x, s::AbstractSpace)
Return wheather `x` is a valid sample in space `s`.
"""
function occursin end
34 changes: 34 additions & 0 deletions src/spaces/boxspace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"A box in R^n."
struct BoxSpace{T <: Number,N} <: AbstractSpace
low::Array{T,N}
high::Array{T,N}
end

size(s::BoxSpace) = size(s.low)

"""
BoxSpace(low::Number, high::Number, size::Tuple{Vararg{Int}}=(1,))
```julia
BoxSpace(-1, 1)
BoxSpace(-1, 1, (2,3))
```
"""
BoxSpace(low::Number, high::Number, size::Tuple{Vararg{Int}}=(1,)) = BoxSpace(fill(low, size), fill(high, size))

"""
BoxSpace(low::Array{<:Number}, high::Array{<:Number})
```julia
BoxSpace([0, 0, 0], [1, 2, 3])
```
"""
BoxSpace(low::Array{<:Number}, high::Array{<:Number}) = size(low) == size(high) && BoxSpace(low, high)

==(x::BoxSpace, y::BoxSpace) = x.low == y.low && x.high == y.high

sample(s::BoxSpace) = map((l, h) -> l + rand() * (h - l), s.low, s.high)

occursin(xs::Array{<:Number}, s::BoxSpace) = size(s) == size(xs) &&
all(map((a, b, c) -> a b c, s.low, xs, s.high))
occursin(x::Number, s::BoxSpace) = all(map((l, h) -> l x h, s.low, s.high))
9 changes: 9 additions & 0 deletions src/spaces/discretespace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct DiscreteSpace <: AbstractSpace
n::Int
offset::Int
end

size(d::DiscreteSpace) = 1
sample(d::DiscreteSpace) = rand(d.offset : d.n + d.offset - 1)
occursin(x::Int, d::DiscreteSpace) = d.offset x < d.offset + d.n
==(x::DiscreteSpace, y::DiscreteSpace) = x.n == y.n && x.offset == y.offset
11 changes: 11 additions & 0 deletions src/spaces/multibinaryspace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
struct MultiBinarySpace <: AbstractSpace
size::Tuple{Vararg{Int}}
end

MultiBinarySpace(sz::Vararg{Int}) = MultiBinarySpace(sz)

size(s::MultiBinarySpace) = s.size

sample(s::MultiBinarySpace) = rand(Bool, s.size...)
occursin(x::Array{Bool}, s::MultiBinarySpace) = size(s) == size(x)
==(x::MultiBinarySpace, y::MultiBinarySpace) = x.size == y.size
13 changes: 13 additions & 0 deletions src/spaces/multidiscretespace.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct MultiDiscreteSpace{N} <:AbstractSpace
counts::Array{Int, N}
offset::Int
end

size(s::MultiDiscreteSpace) = size(s.counts)

"To compat with Python, here we start with 0"
sample(s::MultiDiscreteSpace) = map(x -> rand(s.offset : x + s.offset -1), s.counts)
occursin(x::Int, s::MultiDiscreteSpace) = all(e -> s.offset x < e + s.offset, s.counts)
occursin(xs::Array{Int}, s::MultiDiscreteSpace) = size(s) == size(xs) &&
all(map((e, x) -> s.offset x < e + s.offset , s.counts, xs))
==(x::MultiDiscreteSpace, y::MultiDiscreteSpace) = x.counts == y.counts && x.offset == y.offset
26 changes: 26 additions & 0 deletions src/spaces/space.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Base:occursin, size, ==
export AbstractSpace,
BoxSpace,
DiscreteSpace,
MultiBinarySpace,
MultiDiscreteSpace,
sample

include("abstractspace.jl")
include("boxspace.jl")
include("discretespace.jl")
include("multibinaryspace.jl")
include("multidiscretespace.jl")

# Tuple Support
sample(s::Tuple{Vararg{<:AbstractSpace}}) = map(sample, s)
occursin(a::Tuple, b::Tuple{Vararg{<:AbstractSpace}}) = length(a) == length(b) &&
all(map((x, y) -> occursin(x, y), a, b))

# Dict Support
sample(s::Dict{String}) = Dict(map((k, v) -> (k, sample(v)), s))
occursin(a::Dict{String}, b::Dict{String}) = length(a) == length(b) &&
all(p -> haskey(a, p.first) ?
occursin(a[p.first], p.second) :
false,
b)
4 changes: 4 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using ReinforcementLearningBase
using Test

include("space.jl")
76 changes: 76 additions & 0 deletions test/space.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@testset "Space" begin

@testset "BoxSpace" begin
@test occursin(0.5, BoxSpace(0, 1)) == true
@test occursin(0.0, BoxSpace(0, 1)) == true
@test occursin(1.0, BoxSpace(0, 1)) == true
@test occursin(-1.0, BoxSpace(0, 1)) == false
@test occursin(-Inf, BoxSpace(0, 1)) == false
@test occursin([0.5], BoxSpace(0, 1)) == true

@test occursin([0, 0], BoxSpace([-1, -2], [1, 2])) == true
@test occursin([0, 3], BoxSpace([-1, -2], [1, 2])) == false
@test occursin([0, 0], BoxSpace([-1, -2], [1, 2])) == true
end

@testset "DiscreteSpace" begin
@test occursin(0, DiscreteSpace(10, 0)) == true
@test occursin(5, DiscreteSpace(10, 0)) == true
@test occursin(10, DiscreteSpace(10, 0)) == false
end

@testset "MultiBinarySpace" begin
@test occursin([true false; true false], MultiBinarySpace(2,2)) == true
@test occursin([true false], MultiBinarySpace(2,2)) == false
end

@testset "MultiDiscreteSpace" begin
@test occursin(0, MultiDiscreteSpace([2,3,2], 0)) == true
@test occursin(1, MultiDiscreteSpace([2,3,2], 0)) == true
@test occursin(2, MultiDiscreteSpace([2,3,2], 0)) == false
@test occursin([1,1,1], MultiDiscreteSpace([2,3,2], 0)) == true
@test occursin([0,0,0], MultiDiscreteSpace([2,3,2], 0)) == true
@test occursin([3,3,3], MultiDiscreteSpace([2,3,2], 0)) == false
end

@testset "Space Tuple" begin
@test occursin(([0.5], 5, [true true; true true], [1, 1]),
(BoxSpace(0,1), DiscreteSpace(5, 0), MultiBinarySpace(2,2), MultiDiscreteSpace([2,2], 0))) == false
@test occursin(([0.5], 0, [true true; true true], [1, 1]),
(BoxSpace(0,1), DiscreteSpace(5, 0), MultiBinarySpace(2,2), MultiDiscreteSpace([2,2], 0))) == true
@test occursin((),
(BoxSpace(0,1), DiscreteSpace(5, 0), MultiBinarySpace(2,2), MultiDiscreteSpace([2,2], 0))) == false
end

@testset "Space Dict" begin
@test occursin(
Dict(
"sensors" => Dict(
"position" => [-10, 0, 10],
"velocity" => [0.1, 0.2, 0.3],
"front_cam" => (rand(10, 10, 3), rand(10, 10, 3)),
"rear_cam" => rand(10,10,3)),
"ext_controller" => [2, 1, 1],
"inner_state" => Dict(
"charge" => 35,
"system_checks" => rand(Bool, 10),
"job_status" => Dict(
"task" => 3,
"progress" => 23))),
Dict(
"sensors" => Dict(
"position"=> BoxSpace(-100, 100, (3,)),
"velocity"=> BoxSpace(-1, 1, (3,)),
"front_cam"=> (BoxSpace(0, 1, (10, 10, 3)),
BoxSpace(0, 1, (10, 10, 3))),
"rear_cam" => BoxSpace(0, 1, (10, 10, 3))),
"ext_controller" => MultiDiscreteSpace([5, 2, 2], 0),
"inner_state" => Dict(
"charge" => DiscreteSpace(100, 0),
"system_checks" => MultiBinarySpace(10),
"job_status" => Dict(
"task" => DiscreteSpace(5, 0),
"progress" => BoxSpace(0, 100))))) == true
end

end

0 comments on commit f882dd9

Please sign in to comment.