Skip to content

Commit

Permalink
fix tests (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
mforets authored Feb 22, 2020
1 parent 15aec30 commit a456045
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 12 deletions.
6 changes: 6 additions & 0 deletions docs/src/lib/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ EulerDiscretization
@system
```

## Initial-value problem macro

```@docs
@ivp
```

## Identity operator

```@docs
Expand Down
4 changes: 3 additions & 1 deletion src/MathematicalSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ Macros
==========================#
include("macros.jl")

export @map
export @map,
@system,
@ivp

#===================================
Successor state for discrete systems
Expand Down
82 changes: 71 additions & 11 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ using Espresso: matchex
using LinearAlgebra: I
using MacroTools: @capture
using InteractiveUtils: subtypes
export @system

import Base: sort

Expand Down Expand Up @@ -244,7 +243,11 @@ function strip_dynamic_equation(expr)
return (nothing, nothing, nothing)
end

function parse_system(exprs)
function _parse_system(expr::Expr)
return _parse_system((expr,))
end

function _parse_system(exprs::NTuple{N, Expr}) where {N}
# define default dynamic equation, unknown abstract system type,
# and empty list of constraints
dynamic_equation = nothing
Expand Down Expand Up @@ -729,6 +732,15 @@ function sort(parameters::Vector{<:Tuple{Any, Symbol}}, order::NTuple{N, Symbol}
return order_parameters
end

function _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
lhs, rhs = extract_dyn_equation_parameters(dyn_eq, state, input, noise, dim, AT)
ordered_rhs = sort(rhs, (:A, :B, :c, :D, :f, :statedim, :inputdim, :noisedim))
ordered_set = sort(extract_set_parameter.(constr, state, input, noise), (:X, :U, :W))
field_names, var_names = constructor_input(lhs, ordered_rhs, ordered_set)
sys_type = _corresponding_type(AT, field_names)
return sys_type, var_names
end

"""
system(expr...)
Expand Down Expand Up @@ -846,19 +858,67 @@ ConstrainedBlackBoxControlDiscreteSystem{typeof(f),BallInf{Float64},BallInf{Floa
"""
macro system(expr...)
try
if typeof(expr) == :Expr
dyn_eq, AT, constr, state, input, noise, dim, x0 = parse_system([expr])
dyn_eq, AT, constr, state, input, noise, dim, x0 = _parse_system(expr)
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
sys = Expr(:call, :($sys_type), :($(var_names...)))
if x0 == nothing
return esc(sys)
else
ivp = Expr(:call, InitialValueProblem, :($sys), :($x0))
return esc(ivp)
end
catch ex
if isa(ex, ArgumentError)
return :(throw($ex))
else
dyn_eq, AT, constr, state, input, noise, dim, x0 = parse_system(expr)
throw(ex)
end
lhs, rhs = extract_dyn_equation_parameters(dyn_eq, state, input, noise, dim, AT)
ordered_rhs = sort(rhs, (:A, :B, :c, :D, :f, :statedim, :inputdim, :noisedim))
ordered_set = sort(extract_set_parameter.(constr, state, input, noise), (:X, :U, :W))
field_names, var_names = constructor_input(lhs, ordered_rhs, ordered_set)
sys_type = _corresponding_type(AT, field_names)
end
end

"""
ivp(expr...)
Return an instance of the initial-value problem type corresponding to the given
expressions.
### Input
- `expr` -- expressions separated by commas which define the dynamic equation,
the constraint sets or the dimensionality of the system, and the set
of initial states (required)
### Output
An initial-value problem that best matches the given expressions.
### Notes
This macro behaves like the `@system` macro, the sole difference being that in
`@ivp` the constraint on the set of initial states is mandatory. For the technical
details we refer to the documentation of [`@system`](@ref).
### Examples
```jldoctest ivp_macro
julia> p = @ivp(x' = -x, x(0) ∈ [1.0]);
julia> typeof(p)
InitialValueProblem{LinearContinuousSystem{Float64,IdentityMultiple{Float64}},Array{Float64,1}}
julia> initial_state(p)
1-element Array{Float64,1}:
1.0
```
"""
macro ivp(expr...)
try
dyn_eq, AT, constr, state, input, noise, dim, x0 = _parse_system(expr)
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
sys = Expr(:call, :($sys_type), :($(var_names...)))
if x0 == nothing
return esc(sys)
return throw(ArgumentError("an initial-value problem should define the " *
"initial states, but such expression was not found"))
else
ivp = Expr(:call, InitialValueProblem, :($sys), :($x0))
return esc(ivp)
Expand Down
6 changes: 6 additions & 0 deletions test/@ivp.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@testset "@ivp for a continuous system" begin
P = @ivp(x' = -x, x(0) Interval(-1.0, 1.0))
@test P == InitialValueProblem(LinearContinuousSystem(I(-1.0, 1)), Interval(-1, 1))
# throw error if x(0) is not defined
@test_throws ArgumentError @ivp(x' = -x)
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ include("successor.jl")
include("utilities.jl")
include("discretize.jl")
include("@system.jl")
include("@ivp.jl")

0 comments on commit a456045

Please sign in to comment.